4

Are there any examples of matrix transformations on polygons (cartesian), using Boost Geometry? I am defining the matrix with simple std::vectors.

Also, I could only find 1 example of matrix_transformers using ublas but it's way too convoluted for a simple matrix transformation. If this is the only way though, I'll stick with it, but it would be great to have other options, ad do this with std::vector instead of ublas::matrix.

Jaime Ivan Cervantes
  • 3,281
  • 1
  • 34
  • 36
  • @sehe Boost Geometry actually has a strategy called `matrix_transformer` that worked like a charm (see solution) – Jaime Ivan Cervantes Sep 15 '17 at 03:28
  • I... stand corrected. I have no clue what `qvm` refers to and I don't see it in your code either, but thanks for introducing me to new aspects of Boost Libraries :) – sehe Sep 15 '17 at 11:31
  • 1
    `qvm` is a Boost library for matrix, vector and quaternion operations that seems to be introduced somewhat recently. It's not in my code because it's internal to `matrix_transformer` – Jaime Ivan Cervantes Sep 15 '17 at 15:06
  • Thanks again, I'll definitely try this out – sehe Sep 15 '17 at 18:12

1 Answers1

6

Here's my solution for anyone who might be interested. Boost geometry actually added a strategy called matrix_transformer that relies on Boost's qvm::mat for matrix transformations. There's not that many examples out there, so here's my code:

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

using namespace boost::geometry::strategy::transform;

typedef boost::geometry::model::d2::point_xy<double> point_2f;
typedef boost::geometry::model::polygon<point_2f> polygon_2f;

int main() {
    polygon_2f pol;
    boost::geometry::read_wkt("POLYGON((10 10,10 27,24 22,22 10,10 10))", pol);

    polygon_2f polTrans;

    // Set the rotation angle (in radians)
    double angleDeg = 45;
    double angleRad = angleDeg * 3.14159 / 180.0;

    vector<vector<double> > mat = {{cos(angleRad), sin(angleRad), 0}, {-sin(angleRad), cos(angleRad), 0}, {0, 0, 1}};

    // Create the matrix_trasformer for a simple rotation matrix
    matrix_transformer<double, 2, 2> rotation(mat[0][0], mat[0][1], mat[0][2], mat[1][0], mat[1][1], mat[1][2], mat[2][0], mat[2][1], mat[2][2]);

    // Apply the matrix_transformer
    boost::geometry::transform(pol, polTrans, rotation);

    // Create svg file to show results
    std::ofstream svg("transformationExample.svg");
    boost::geometry::svg_mapper<point_2f> mapper(svg, 400, 400);

    mapper.add(pol);
    mapper.map(pol, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2");

    mapper.add(polTrans);
    mapper.map(polTrans, "fill-opacity:0.5;fill:rgb(153,204,255);stroke:rgb(153,204,255);stroke-width:2");

    return 0;
}

And here's my result, where the green polygon is the original and the blue polygon is transformed (remember that the rotation was about the origin):

enter image description here

Jaime Ivan Cervantes
  • 3,281
  • 1
  • 34
  • 36