(C++) BoostGeometryExample9
February 24, 2017 · View on GitHub
(C++) BoostGeometryExample9



Boost.Geometry example 9: Rescale and translate a polygon is a Boost.Geometry example.
Technical facts
Operating system(s) or programming environment(s)
Lubuntu 15.04 (vivid)
Qt Creator 3.1.1
- G++ 4.9.2
Libraries used:
Qt project file: ./CppBoostGeometryExample9/CppBoostGeometryExample9.pro
exists(../../ConsoleApplication.pri) { include(../../ConsoleApplication.pri) } !exists(../../ConsoleApplication.pri) { QT += core QT += gui greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += console CONFIG -= app_bundle TEMPLATE = app CONFIG(release, debug|release) { DEFINES += NDEBUG NTRACE_BILDERBIKKEL } QMAKE_CXXFLAGS += -std=c++11 -Wall -Wextra -Weffc++ unix { QMAKE_CXXFLAGS += -Werror } } exists(../../Libraries/Boost.pri) { include(../../Libraries/Boost.pri) } !exists(../../Libraries/Boost.pri) { win32 { INCLUDEPATH += \ ../../Libraries/boost_1_55_0 } } SOURCES += main.cpp
./CppBoostGeometryExample9/main.cpp
#include <cassert> #include <iostream> #include <vector> #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #pragma GCC diagnostic ignored "-Wunused-variable" #include <boost/geometry.hpp> #include <boost/geometry/geometries/point_xy.hpp> #include <boost/geometry/geometries/polygon.hpp> #include <boost/geometry/geometries/ring.hpp> #pragma GCC diagnostic pop boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double>> Translate( const boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double>>& shape, const double dx, const double dy ) noexcept { typedef boost::geometry::model::d2::point_xy<double> Coordinat2D; typedef boost::geometry::model::polygon<Coordinat2D> Polygon; boost::geometry::model::ring<Coordinat2D> points; boost::geometry::convert(shape,points); for (auto& point:points) { point = Coordinat2D(point.x() + dx, point.y() + dy); } Polygon new_shape; boost::geometry::append(new_shape, points); return new_shape; } boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double>> Rescale( const boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double>>& shape, const double scale, const double scale_origin_x = 0.0, const double scale_origin_y = 0.0 ) noexcept { typedef boost::geometry::model::d2::point_xy<double> Coordinat2D; typedef boost::geometry::model::polygon<Coordinat2D> Polygon; boost::geometry::model::ring<Coordinat2D> points; boost::geometry::convert(shape,points); for (auto& point:points) { const double x = point.x(); const double dx = x - scale_origin_x; const double new_x = scale_origin_x + (scale * dx); const double y = point.y(); const double dy = y - scale_origin_y; const double new_y = scale_origin_y + (scale * dy); point = Coordinat2D(new_x,new_y); } Polygon new_shape; boost::geometry::append(new_shape, points); return new_shape; } boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double>> CreateHouseShape() noexcept { /* 3- | 2- 0 | / \ 1- 4 1 | | | 0- 3---2 | +--|---|---| 0 1 2 */ typedef boost::geometry::model::d2::point_xy<double> Coordinat2D; typedef boost::geometry::model::polygon<Coordinat2D> Polygon; const std::vector<Coordinat2D> points { {0.5, 2.0}, //0 {1.0, 1.0}, //1 {1.0, 0.0}, //2 {0.0, 0.0}, //3 {0.0, 1.0} //4 }; boost::geometry::model::polygon<Coordinat2D> house; boost::geometry::append(house, points); return house; } int main() { typedef boost::geometry::model::d2::point_xy<double> Coordinat2D; typedef boost::geometry::model::polygon<Coordinat2D> Polygon; { //Translate (0.5,1.0) to origin const auto house = CreateHouseShape(); const auto translated_house = Translate(house,-0.5,-1.0); boost::geometry::model::ring<Coordinat2D> translated_points; boost::geometry::convert(translated_house,translated_points); const std::vector<Coordinat2D> translated_points_expected { { 0.0, 1.0}, //0 { 0.5, 0.0}, //1 { 0.5,-1.0}, //2 {-0.5,-1.0}, //3 {-0.5, 0.0} //4 }; assert( std::equal( translated_points.begin(),translated_points.end(), translated_points_expected.begin(), [](const Coordinat2D& a,const Coordinat2D& b) { return boost::geometry::equals(a,b); } ) && "Points must be translated as expected" ); } { //Scale twice up, from origin const auto house = CreateHouseShape(); const auto rescaled_house = Rescale(house,2.0); boost::geometry::model::ring<Coordinat2D> rescaled_points; boost::geometry::convert(rescaled_house,rescaled_points); const std::vector<Coordinat2D> rescaled_points_expected { {1.0, 4.0}, //0 {2.0, 2.0}, //1 {2.0, 0.0}, //2 {0.0, 0.0}, //3 {0.0, 2.0} //4 }; assert( std::equal( rescaled_points.begin(),rescaled_points.end(), rescaled_points_expected.begin(), [](const Coordinat2D& a,const Coordinat2D& b) { //std::cout << "(" << a.x() << "," << a.y() << ")-(" // << b.x() << "," << b.y() << ")" << std::endl; return boost::geometry::equals(a,b); } ) && "Points must be rescaled as expected" ); } { //Scale up, from center at (0.5,1.0) /* 3- | 2- 0 | / \ 1- 4 * 1 | | | 0- 3---2 | +--|---|---| 0 1 2 */ const auto house = CreateHouseShape(); const auto rescaled_house = Rescale(house,2.0,0.5,1.0); boost::geometry::model::ring<Coordinat2D> rescaled_points; boost::geometry::convert(rescaled_house,rescaled_points); const std::vector<Coordinat2D> rescaled_points_expected { { 0.5, 3.0}, //0 { 1.5, 1.0}, //1 { 1.5,-1.0}, //2 {-0.5,-1.0}, //3 {-0.5, 1.0} //4 }; assert( std::equal( rescaled_points.begin(),rescaled_points.end(), rescaled_points_expected.begin(), [](const Coordinat2D& a,const Coordinat2D& b) { //std::cout << "(" << a.x() << "," << a.y() << ")-(" // << b.x() << "," << b.y() << ")" << std::endl; return boost::geometry::equals(a,b); } ) && "Points must be rescaled as expected" ); } }