Home > Blockchain >  What define's Boost's svg_mapper scaling and translation?
What define's Boost's svg_mapper scaling and translation?

Time:02-25

This code:

#include <fstream>

#include <boost/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>

namespace bg = boost::geometry;

int main()
{
    std::ofstream svg ( "test.svg" );
    boost::geometry::svg_mapper<bg::model::d2::point_xy<double>, true, double> mapper ( svg, 6000, 3000 );

    bg::model::polygon<bg::model::d2::point_xy<double>> square{
        {{0, 0}, {0, 1000}, {1000, 1000}, {1000, 0}, {0, 0}}};
    const std::string style{"fill-opacity:1.0;fill:rgb(128,128,128);stroke:rgb(0,0,0);stroke-width:5"};

    mapper.add ( square );
    mapper.map ( square, style, 1.0 );
}

Produces this svg:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<g fill-rule="evenodd"><path d="M 1500,3000 L 1500,0 L 4500,0 L 4500,3000 L 1500,3000 z " style="fill-opacity:1.0;fill:rgb(128,128,128);stroke:rgb(0,0,0);stroke-width:5"/></g>
</svg>

The following conversions happen from the input polygon to the mapped svg geometries:

(0, 0) -> (1500,3000)
(0, 1000) -> (1500,0)
(1000, 1000) -> (4500,0)
(1000, 0) -> (4500,3000)
(0, 0) -> (1500,3000)

Staring at it a bit you see there is some transformation applied, something like this:

  • 1500 in x
  • 3000 in y
  • 3x scale in x
  • -3x scale in y

My question is - What drives that transformation and can I prevent it? And if I can't prevent it, can I retrieve it or calculate it myself?

Reason being is I'm producing many complex SVG's and would like them to all be in the same frame. So if there is a circle at pixels (10,10) in one, I would like all the images to be of the same size with the circle in the exact same location. I tried to accomplish this with viewBox but the scaling and translation was too hard to predict to keep the images consistent.

CodePudding user response:

svg_mapper calculates a bounding box from all add-ed geometries.

Then, a map_transformer is used to scale down to the desired width/height.

Contrary to what you might expect, add doesn't do anything besides expanding the bounding box. Likewise, after the first map call, no other add has any effect on the bounding-box used for the transformations.

In other words, you can use some kind of fixed bounding box, add only that, and then map your geometries into that "canvas":

enter image description here

  • Related