Path: blob/main/unittest/src/utils/geom/PositionVectorTest.cpp
169684 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file PositionVectorTest.cpp14/// @author Matthias Heppner15/// @author Michael Behrisch16/// @author Jakob Erdmann17/// @date 2009-10-2418///19// Tests the class PositionVector20/****************************************************************************/21#include <config.h>2223#include <gtest/gtest.h>24#include <utils/geom/PositionVector.h>25#include <utils/geom/Boundary.h>26#include <utils/geom/GeomHelper.h>27#include <utils/common/UtilExceptions.h>28#include <utils/common/MsgHandler.h>29#include <utils/iodevices/OutputDevice.h>303132#define EXPECT_DOUBLEVEC_EQUAL(v1, v2) \33{ \34EXPECT_EQ(v1.size(), v2.size()); \35if (v1.size() == v2.size()) { \36for (int i = 0; i < (int)v1.size(); ++i) { \37EXPECT_DOUBLE_EQ(v1[i], v2[i]); \38} \39} \40} \414243#define EXPECT_POSITIONVEC_EQUAL(v1, v2) \44{ \45EXPECT_EQ(v1.size(), v2.size()); \46if (v1.size() == v2.size()) { \47for (int i = 0; i < (int)v1.size(); ++i) { \48EXPECT_DOUBLE_EQ((v1[i].x()), (v2[i].x())); \49EXPECT_DOUBLE_EQ((v1[i].y()), (v2[i].y())); \50EXPECT_DOUBLE_EQ((v1[i].z()), (v2[i].z())); \51} \52} \53} \545556class PositionVectorTest : public testing::Test {57protected :58PositionVector* vectorPolygon;59PositionVector* vectorLine;60PositionVector* vectorTrianglePositiveCoords;61PositionVector* vectorTriangleNegativeCoords;62PositionVector* vectorRectangleOriginAlignedCorners;6364virtual void SetUp() {65vectorPolygon = new PositionVector();66vectorPolygon->push_back(Position(0, 0));67vectorPolygon->push_back(Position(0, 2));68vectorPolygon->push_back(Position(2, 4));69vectorPolygon->push_back(Position(4, 2));70vectorPolygon->push_back(Position(4, 0));7172vectorLine = new PositionVector();73vectorLine->push_back(Position(0, 0));74vectorLine->push_back(Position(2, 2));7576vectorTrianglePositiveCoords = new PositionVector();77vectorTrianglePositiveCoords->push_back(Position(1, 1));78vectorTrianglePositiveCoords->push_back(Position(3, 0));79vectorTrianglePositiveCoords->push_back(Position(2, 3));8081vectorTriangleNegativeCoords = new PositionVector();82vectorTriangleNegativeCoords->push_back(Position(2, -1));83vectorTriangleNegativeCoords->push_back(Position(1, -1));84vectorTriangleNegativeCoords->push_back(Position(2, -3));8586vectorRectangleOriginAlignedCorners = new PositionVector();87vectorRectangleOriginAlignedCorners->push_back(Position(1, 1));88vectorRectangleOriginAlignedCorners->push_back(Position(3, 1));89vectorRectangleOriginAlignedCorners->push_back(Position(3, 3));90vectorRectangleOriginAlignedCorners->push_back(Position(1, 3));91}9293virtual void TearDown() {94delete vectorPolygon;95delete vectorLine;96delete vectorTrianglePositiveCoords;97delete vectorTriangleNegativeCoords;98delete vectorRectangleOriginAlignedCorners;99}100101};102103/* Test the method 'around'*/104TEST_F(PositionVectorTest, test_method_around) {105106EXPECT_TRUE(vectorPolygon->around(Position(1, 1)));107EXPECT_TRUE(vectorPolygon->around(Position(1, 2)));108EXPECT_FALSE(vectorPolygon->around(Position(4, 4)));109EXPECT_FALSE(vectorPolygon->around(Position(0, 0)));110111EXPECT_FALSE(vectorLine->around(Position(1, 1)));112EXPECT_FALSE(vectorLine->around(Position(0, 2)));113114// with positive offset115EXPECT_TRUE(vectorPolygon->around(Position(4, 2), 1));116EXPECT_FALSE(vectorPolygon->around(Position(5, 2), 1));117// what was true remains true118EXPECT_TRUE(vectorPolygon->around(Position(1, 1), POSITION_EPS));119EXPECT_TRUE(vectorPolygon->around(Position(1, 2), POSITION_EPS));120121// with negative offset122EXPECT_FALSE(vectorPolygon->around(Position(4, 2), -POSITION_EPS));123EXPECT_TRUE(vectorPolygon->around(Position(1, 1), -1));124EXPECT_FALSE(vectorPolygon->around(Position(0.5, 0.5), -1));125}126127/* Test the method 'area'*/128TEST_F(PositionVectorTest, test_method_area) {129PositionVector square;130square.push_back(Position(0, 0));131square.push_back(Position(1, 0));132square.push_back(Position(1, 1));133square.push_back(Position(0, 1)); // open134EXPECT_DOUBLE_EQ(square.area(), 1);135square.push_back(Position(0, 0)); // closed136EXPECT_DOUBLE_EQ(square.area(), 1);137}138139/* Test the method 'scaleRelative'.*/140TEST_F(PositionVectorTest, test_method_scaleRelative) {141PositionVector square;142square.push_back(Position(0, 0));143square.push_back(Position(1, 0));144square.push_back(Position(1, 1));145square.push_back(Position(0, 1));146square.push_back(Position(0, 0));147EXPECT_DOUBLE_EQ(square.area(), 1);148square.scaleRelative(3);149EXPECT_DOUBLE_EQ(square.area(), 9);150151PositionVector expected;152expected.push_back(Position(-1, -1));153expected.push_back(Position(2, -1));154expected.push_back(Position(2, 2));155expected.push_back(Position(-1, 2));156expected.push_back(Position(-1, -1));157158EXPECT_EQ(expected.getCentroid(), square.getCentroid());159for (int i = 0; i < (int)square.size(); i++) {160EXPECT_DOUBLE_EQ(expected[i].x(), square[i].x());161EXPECT_DOUBLE_EQ(expected[i].y(), square[i].y());162}163}164165/* Test the method 'getCentroid'.*/166TEST_F(PositionVectorTest, test_method_getCentroid) {167PositionVector square;168square.push_back(Position(0, 0));169square.push_back(Position(1, 0));170square.push_back(Position(1, 1));171square.push_back(Position(0, 1));172EXPECT_EQ(Position(0.5, 0.5), square.getCentroid());173174Position pos2 = vectorLine->getCentroid();175EXPECT_DOUBLE_EQ(1, pos2.x());176EXPECT_DOUBLE_EQ(1, pos2.y());177}178179/* Test the method 'getPolygonCenter'.*/180TEST_F(PositionVectorTest, test_method_getPolygonCenter) {181Position pos = vectorPolygon->getPolygonCenter();182EXPECT_DOUBLE_EQ(2, pos.x());183EXPECT_DOUBLE_EQ(1.6, pos.y());184Position pos2 = vectorLine->getPolygonCenter();185EXPECT_DOUBLE_EQ(1, pos2.x());186EXPECT_DOUBLE_EQ(1, pos2.y());187}188189190/* Test the method 'getBoxBoundary'*/191TEST_F(PositionVectorTest, test_method_getBoxBoundary) {192Boundary bound = vectorPolygon->getBoxBoundary();193EXPECT_DOUBLE_EQ(bound.xmax(), 4);194EXPECT_DOUBLE_EQ(bound.xmin(), 0);195EXPECT_DOUBLE_EQ(bound.ymax(), 4);196EXPECT_DOUBLE_EQ(bound.ymin(), 0);197}198199/* Test the method 'splitAt'*/200TEST_F(PositionVectorTest, test_method_splitAt) {201PositionVector vec;202vec.push_back(Position(0, 0));203vec.push_back(Position(2, 0));204vec.push_back(Position(5, 0));205double smallDiff = POSITION_EPS / 2;206std::pair<PositionVector, PositionVector> result;207// split in first segment208result = vec.splitAt(1);209EXPECT_EQ(2, (int)result.first.size());210EXPECT_DOUBLE_EQ(0., result.first[0].x());211EXPECT_DOUBLE_EQ(1., result.first[1].x());212EXPECT_EQ(3, (int)result.second.size());213EXPECT_DOUBLE_EQ(1., result.second[0].x());214EXPECT_DOUBLE_EQ(2., result.second[1].x());215EXPECT_DOUBLE_EQ(5., result.second[2].x());216// split in second segment217result = vec.splitAt(4);218EXPECT_EQ(3, (int)result.first.size());219EXPECT_DOUBLE_EQ(0., result.first[0].x());220EXPECT_DOUBLE_EQ(2., result.first[1].x());221EXPECT_DOUBLE_EQ(4., result.first[2].x());222EXPECT_EQ(2, (int)result.second.size());223EXPECT_DOUBLE_EQ(4., result.second[0].x());224EXPECT_DOUBLE_EQ(5., result.second[1].x());225// split close before inner point226result = vec.splitAt(2 - smallDiff);227EXPECT_EQ(2, (int)result.first.size());228EXPECT_DOUBLE_EQ(0., result.first[0].x());229EXPECT_DOUBLE_EQ(2., result.first[1].x());230EXPECT_EQ(2, (int)result.second.size());231EXPECT_DOUBLE_EQ(2., result.second[0].x());232EXPECT_DOUBLE_EQ(5., result.second[1].x());233// split close after inner point234result = vec.splitAt(2 + smallDiff);235EXPECT_EQ(2, (int)result.first.size());236EXPECT_DOUBLE_EQ(0., result.first[0].x());237EXPECT_DOUBLE_EQ(2., result.first[1].x());238EXPECT_EQ(2, (int)result.second.size());239EXPECT_DOUBLE_EQ(2., result.second[0].x());240EXPECT_DOUBLE_EQ(5., result.second[1].x());241242// catch a bug243vec.push_back(Position(6, 0));244vec.push_back(Position(8, 0));245// split at inner point246result = vec.splitAt(5);247EXPECT_EQ(3, (int)result.first.size());248EXPECT_DOUBLE_EQ(0., result.first[0].x());249EXPECT_DOUBLE_EQ(2., result.first[1].x());250EXPECT_DOUBLE_EQ(5., result.first[2].x());251EXPECT_EQ(3, (int)result.second.size());252EXPECT_DOUBLE_EQ(5., result.second[0].x());253EXPECT_DOUBLE_EQ(6., result.second[1].x());254EXPECT_DOUBLE_EQ(8., result.second[2].x());255256// split short vector257PositionVector vec2;258vec2.push_back(Position(0, 0));259vec2.push_back(Position(2, 0));260result = vec2.splitAt(1);261EXPECT_EQ(2, (int)result.first.size());262EXPECT_DOUBLE_EQ(0., result.first[0].x());263EXPECT_DOUBLE_EQ(1., result.first[1].x());264EXPECT_EQ(2, (int)result.second.size());265EXPECT_DOUBLE_EQ(1., result.second[0].x());266EXPECT_DOUBLE_EQ(2., result.second[1].x());267268// split very short vector269PositionVector vec3;270vec3.push_back(Position(0, 0));271vec3.push_back(Position(POSITION_EPS, 0));272// supress expected warning273MsgHandler::getWarningInstance()->removeRetriever(&OutputDevice::getDevice("stderr"));274result = vec3.splitAt(smallDiff);275MsgHandler::getWarningInstance()->addRetriever(&OutputDevice::getDevice("stderr"));276277EXPECT_EQ(2, (int)result.first.size());278EXPECT_DOUBLE_EQ(0., result.first[0].x());279EXPECT_DOUBLE_EQ(smallDiff, result.first[1].x());280EXPECT_EQ(2, (int)result.second.size());281EXPECT_DOUBLE_EQ(smallDiff, result.second[0].x());282EXPECT_DOUBLE_EQ(POSITION_EPS, result.second[1].x());283}284285286/* Test the method 'intersectsAtLengths2D'*/287TEST_F(PositionVectorTest, test_method_intersectsAtLengths2D) {288PositionVector vec1;289vec1.push_back(Position(0, 0, 42));290vec1.push_back(Position(100, 0, 0));291292PositionVector vec2;293vec2.push_back(Position(0, 0, 0));294vec2.push_back(Position(3, 1, 0));295EXPECT_DOUBLE_EQ(0, vec1.intersectsAtLengths2D(vec2)[0]);296}297298299/* Test the method 'nearest_offset_to_point2D'*/300TEST_F(PositionVectorTest, test_method_nearest_offset_to_point2D) {301PositionVector vec1;302vec1.push_back(Position(0, 1, 0));303vec1.push_back(Position(0, 0, 0));304vec1.push_back(Position(1, 0, 0));305306EXPECT_DOUBLE_EQ(1, vec1.nearest_offset_to_point2D(Position(-1, -1), false));307EXPECT_DOUBLE_EQ(1, vec1.nearest_offset_to_point2D(Position(-1, -1), true));308EXPECT_DOUBLE_EQ(2, vec1.nearest_offset_to_point2D(Position(2, 1), false));309EXPECT_DOUBLE_EQ(0, vec1.nearest_offset_to_point2D(Position(2, 1), true));310EXPECT_DOUBLE_EQ(2, vec1.nearest_offset_to_point2D(Position(3, 2), false));311EXPECT_DOUBLE_EQ(-1, vec1.nearest_offset_to_point2D(Position(3, 2), true));312}313314315TEST_F(PositionVectorTest, test_method_extrapolate2D) {316PositionVector vec1;317vec1.push_back(Position(0, 1, 0));318vec1.push_back(Position(0, 0, 0));319vec1.push_back(Position(1, 0, 0));320vec1.extrapolate2D(1);321EXPECT_EQ(Position(0, 2, 0), vec1[0]);322EXPECT_EQ(Position(0, 0, 0), vec1[1]);323EXPECT_EQ(Position(2, 0, 0), vec1[2]);324325PositionVector vec2;326vec2.push_back(Position(0, 1, 0));327vec2.push_back(Position(0, 0, 1));328vec2.push_back(Position(1, 0, 0));329vec2.extrapolate2D(1);330// EXPECT_EQ(Position(0,2,0), vec2[0]);331// EXPECT_EQ(Position(0,0,0), vec2[1]);332// EXPECT_EQ(Position(2,0,0), vec2[2]);333334PositionVector vec3;335vec3.push_back(Position(-.5, 1));336vec3.push_back(Position(-.5, -.5));337vec3.push_back(Position(1, -.5));338vec3.extrapolate2D(.5);339EXPECT_EQ(Position(-.5, 1.5), vec3[0]);340EXPECT_EQ(Position(-.5, -.5), vec3[1]);341EXPECT_EQ(Position(1.5, -.5), vec3[2]);342343}344345346/* Test the method 'move2side'*/347TEST_F(PositionVectorTest, test_method_move2side) {348PositionVector vec1;349vec1.push_back(Position(0, 1, 0));350vec1.push_back(Position(0, 0, 0));351vec1.push_back(Position(1, 0, 0));352vec1.move2side(.5);353EXPECT_EQ(Position(-.5, 1), vec1[0]);354EXPECT_EQ(Position(-.5, -.5), vec1[1]);355EXPECT_EQ(Position(1, -.5), vec1[2]);356vec1.move2side(-1);357EXPECT_EQ(Position(.5, 1), vec1[0]);358EXPECT_EQ(Position(.5, .5), vec1[1]);359EXPECT_EQ(Position(1, .5), vec1[2]);360361// parallel case362PositionVector vec2;363vec2.push_back(Position(0, 0, 0));364vec2.push_back(Position(1, 0, 0));365vec2.push_back(Position(3, 0, 0));366vec2.move2side(.5);367EXPECT_EQ(Position(0, -.5), vec2[0]);368EXPECT_EQ(Position(1, -.5), vec2[1]);369EXPECT_EQ(Position(3, -.5), vec2[2]);370vec2.move2side(-1);371EXPECT_EQ(Position(0, .5), vec2[0]);372EXPECT_EQ(Position(1, .5), vec2[1]);373EXPECT_EQ(Position(3, .5), vec2[2]);374375// counterparallel case376{377PositionVector vec3;378vec3.push_back(Position(0, 0, 0));379vec3.push_back(Position(3, 0, 0));380vec3.push_back(Position(1, 0, 0));381vec3.move2side(.5);382// clipping removal eliminates the middle point383EXPECT_EQ(Position(0, -.5), vec3[0]);384EXPECT_EQ(Position(1, -.5), vec3[1]);385}386// bad input: subsequent identical points387{388PositionVector vec4;389vec4.push_back(Position(0, 0, 0));390vec4.push_back(Position(0, 0, 0));391vec4.push_back(Position(1, 0, 0));392vec4.move2side(-2);393EXPECT_EQ(2, (int)vec4.size());394EXPECT_EQ(Position(0, 2), vec4[0]);395EXPECT_EQ(Position(1, 2), vec4[1]);396}397}398399/* Test the method 'transformToVectorCoordinates'*/400TEST_F(PositionVectorTest, test_method_transformToVectorCoordinates) {401{402PositionVector vec1;403vec1.push_back(Position(1, 0));404vec1.push_back(Position(10, 0));405vec1.push_back(Position(10, 5));406vec1.push_back(Position(20, 5));407Position on(4, 0);408Position left(4, 1);409Position right(4, -1);410Position left2(4, 2);411Position right2(4, -2);412Position cornerRight(13, -4);413Position cornerLeft(7, 9);414Position before(0, -1);415Position beyond(24, 9);416417EXPECT_EQ(Position(3, 0), vec1.transformToVectorCoordinates(on));418EXPECT_EQ(Position(3, -1), vec1.transformToVectorCoordinates(left));419EXPECT_EQ(Position(3, 1), vec1.transformToVectorCoordinates(right));420EXPECT_EQ(Position(3, -2), vec1.transformToVectorCoordinates(left2));421EXPECT_EQ(Position(3, 2), vec1.transformToVectorCoordinates(right2));422EXPECT_EQ(Position(9, 5), vec1.transformToVectorCoordinates(cornerRight));423EXPECT_EQ(Position(14, -5), vec1.transformToVectorCoordinates(cornerLeft));424425EXPECT_EQ(Position::INVALID, vec1.transformToVectorCoordinates(before));426EXPECT_EQ(Position::INVALID, vec1.transformToVectorCoordinates(beyond));427EXPECT_EQ(Position(-1, 1), vec1.transformToVectorCoordinates(before, true));428EXPECT_EQ(Position(28, -4), vec1.transformToVectorCoordinates(beyond, true));429}430431{432PositionVector vec1; // the same tests as before, mirrored on x-axis433vec1.push_back(Position(1, 0));434vec1.push_back(Position(10, 0));435vec1.push_back(Position(10, -5));436vec1.push_back(Position(20, -5));437Position on(4, 0);438Position left(4, -1);439Position right(4, 1);440Position left2(4, -2);441Position right2(4, 2);442Position cornerRight(13, 4);443Position cornerLeft(7, -9);444Position before(0, 1);445Position beyond(24, -9);446447EXPECT_EQ(Position(3, 0), vec1.transformToVectorCoordinates(on));448EXPECT_EQ(Position(3, 1), vec1.transformToVectorCoordinates(left));449EXPECT_EQ(Position(3, -1), vec1.transformToVectorCoordinates(right));450EXPECT_EQ(Position(3, 2), vec1.transformToVectorCoordinates(left2));451EXPECT_EQ(Position(3, -2), vec1.transformToVectorCoordinates(right2));452EXPECT_EQ(Position(9, -5), vec1.transformToVectorCoordinates(cornerRight));453EXPECT_EQ(Position(14, 5), vec1.transformToVectorCoordinates(cornerLeft));454455EXPECT_EQ(Position::INVALID, vec1.transformToVectorCoordinates(before));456EXPECT_EQ(Position::INVALID, vec1.transformToVectorCoordinates(beyond));457EXPECT_EQ(Position(-1, -1), vec1.transformToVectorCoordinates(before, true));458EXPECT_EQ(Position(28, 4), vec1.transformToVectorCoordinates(beyond, true));459}460}461462463/* Test the method 'distance'*/464TEST_F(PositionVectorTest, test_method_distance) {465{466PositionVector vec1;467vec1.push_back(Position(1, 0));468vec1.push_back(Position(10, 0));469vec1.push_back(Position(10, 5));470vec1.push_back(Position(20, 5));471Position on(4, 0);472Position left(4, 1);473Position right(4, -1);474Position left2(4, 2);475Position right2(4, -2);476Position cornerRight(13, -4);477Position cornerLeft(7, 9);478Position before(-3, -3);479Position beyond(24, 8);480481EXPECT_EQ(0, vec1.distance2D(on));482EXPECT_EQ(1, vec1.distance2D(left));483EXPECT_EQ(1, vec1.distance2D(right));484EXPECT_EQ(2, vec1.distance2D(left2));485EXPECT_EQ(2, vec1.distance2D(right2));486EXPECT_EQ(5, vec1.distance2D(cornerRight));487EXPECT_EQ(5, vec1.distance2D(cornerLeft));488489EXPECT_EQ(GeomHelper::INVALID_OFFSET, vec1.distance2D(before, true));490EXPECT_EQ(GeomHelper::INVALID_OFFSET, vec1.distance2D(beyond, true));491EXPECT_EQ(5, vec1.distance2D(before));492EXPECT_EQ(5, vec1.distance2D(beyond));493}494495{496PositionVector vec1; // the same tests as before, mirrored on x-axis497vec1.push_back(Position(1, 0));498vec1.push_back(Position(10, 0));499vec1.push_back(Position(10, -5));500vec1.push_back(Position(20, -5));501Position on(4, 0);502Position left(4, -1);503Position right(4, 1);504Position left2(4, -2);505Position right2(4, 2);506Position cornerRight(13, 4);507Position cornerLeft(7, -9);508Position before(-3, 3);509Position beyond(24, -8);510511EXPECT_EQ(0, vec1.distance2D(on));512EXPECT_EQ(1, vec1.distance2D(left));513EXPECT_EQ(1, vec1.distance2D(right));514EXPECT_EQ(2, vec1.distance2D(left2));515EXPECT_EQ(2, vec1.distance2D(right2));516EXPECT_EQ(5, vec1.distance2D(cornerRight));517EXPECT_EQ(5, vec1.distance2D(cornerLeft));518519EXPECT_EQ(GeomHelper::INVALID_OFFSET, vec1.distance2D(before, true));520EXPECT_EQ(GeomHelper::INVALID_OFFSET, vec1.distance2D(beyond, true));521EXPECT_EQ(5, vec1.distance2D(before));522EXPECT_EQ(5, vec1.distance2D(beyond));523}524}525526527/* Test the method 'distance'*/528TEST_F(PositionVectorTest, test_method_distances) {529{530PositionVector vec1;531vec1.push_back(Position(0, 0));532vec1.push_back(Position(10, 0));533534PositionVector vec2;535vec2.push_back(Position(1, 0));536vec2.push_back(Position(5, 2));537vec2.push_back(Position(10, 0));538vec2.push_back(Position(14, 3));539540PositionVector vec3;541542std::vector<double> res1;543res1.push_back(1);544res1.push_back(0);545res1.push_back(0);546res1.push_back(2);547res1.push_back(0);548res1.push_back(5);549EXPECT_DOUBLEVEC_EQUAL(res1, vec1.distances(vec2));550551552std::vector<double> res2;553//invalid: res1.push_back(1);554res2.push_back(0);555res2.push_back(0);556res2.push_back(2);557res2.push_back(0);558//invalid: res2.push_back(5);559EXPECT_DOUBLEVEC_EQUAL(res2, vec1.distances(vec2, true));560561562std::vector<double> res3;563res3.push_back(std::numeric_limits<double>::max());564res3.push_back(std::numeric_limits<double>::max());565EXPECT_DOUBLEVEC_EQUAL(res3, vec1.distances(vec3));566}567568}569570571/* Test the method 'overlapsWith'*/572TEST_F(PositionVectorTest, test_method_overlapsWith) {573PositionVector vec1;574vec1.push_back(Position(1, 2));575vec1.push_back(Position(3, 2));576vec1.push_back(Position(3, 6));577vec1.push_back(Position(1, 6));578579PositionVector vec2;580vec2.push_back(Position(10, 17));581vec2.push_back(Position(13, 17));582vec2.push_back(Position(13, 16));583vec2.push_back(Position(10, 16));584585PositionVector vec3;586vec3.push_back(Position(-1, -7));587vec3.push_back(Position(2, -7));588vec3.push_back(Position(2, 4));589vec3.push_back(Position(-1, 4));590591PositionVector vec4;592vec4.push_back(Position(0, 3));593vec4.push_back(Position(4, 3));594vec4.push_back(Position(4, 5));595vec4.push_back(Position(0, 5));596597PositionVector vec5;598vec5.push_back(Position(4, 2));599vec5.push_back(Position(5, 2));600vec5.push_back(Position(5, 7));601vec5.push_back(Position(4, 7));602603PositionVector vec6;604vec6.push_back(Position(4, 0));605vec6.push_back(Position(4, 8));606vec6.push_back(Position(-4, 8));607608PositionVector empty;609610EXPECT_TRUE(vec1.overlapsWith(vec1));611EXPECT_FALSE(vec1.overlapsWith(vec2));612EXPECT_TRUE(vec1.overlapsWith(vec3));613EXPECT_TRUE(vec1.overlapsWith(vec4));614EXPECT_FALSE(vec1.overlapsWith(vec5, 0));615EXPECT_TRUE(vec1.overlapsWith(vec6)); // overlapsWith implicitly closes the shape of vec6616EXPECT_TRUE(vec6.overlapsWith(vec1)); // overlapsWith implicitly closes the shape of vec6617// growth is from centroid and thus different from Boundary behavior618EXPECT_FALSE(vec1.overlapsWith(vec5, 1));619EXPECT_TRUE(vec1.overlapsWith(vec5, 3));620EXPECT_TRUE(vec1.overlapsWith(vec5, 6));621EXPECT_FALSE(vec1.overlapsWith(empty));622}623624625/* Test the method 'sortAsPolyCWByAngle'*/626TEST_F(PositionVectorTest, test_method_sortAsPolyCWByAngle) {627PositionVector vectorTrianglePositiveCoordsClockwiseOrdered;628vectorTrianglePositiveCoordsClockwiseOrdered.push_back(Position(2, 3));629vectorTrianglePositiveCoordsClockwiseOrdered.push_back(Position(3, 0));630vectorTrianglePositiveCoordsClockwiseOrdered.push_back(Position(1, 1));631vectorTrianglePositiveCoords->sortAsPolyCWByAngle();632EXPECT_POSITIONVEC_EQUAL((*vectorTrianglePositiveCoords), vectorTrianglePositiveCoordsClockwiseOrdered);633634PositionVector vectorTriangleNegativeCoordsClockwiseOrdered;635vectorTriangleNegativeCoordsClockwiseOrdered.push_back(Position(1, -1));636vectorTriangleNegativeCoordsClockwiseOrdered.push_back(Position(2, -1));637vectorTriangleNegativeCoordsClockwiseOrdered.push_back(Position(2, -3));638vectorTriangleNegativeCoords->sortAsPolyCWByAngle();639EXPECT_POSITIONVEC_EQUAL((*vectorTriangleNegativeCoords), vectorTriangleNegativeCoordsClockwiseOrdered);640641PositionVector vectorRectangleOriginAlignedCornersClockwiseOrdered;642vectorRectangleOriginAlignedCornersClockwiseOrdered.push_back(Position(1, 3));643vectorRectangleOriginAlignedCornersClockwiseOrdered.push_back(Position(3, 3));644vectorRectangleOriginAlignedCornersClockwiseOrdered.push_back(Position(3, 1));645vectorRectangleOriginAlignedCornersClockwiseOrdered.push_back(Position(1, 1));646vectorRectangleOriginAlignedCorners->sortAsPolyCWByAngle();647EXPECT_POSITIONVEC_EQUAL((*vectorRectangleOriginAlignedCorners), vectorRectangleOriginAlignedCornersClockwiseOrdered);648}649650651/* Test the method 'isClockwiseOriented'*/652TEST_F(PositionVectorTest, test_method_isClockwiseOriented) {653EXPECT_FALSE(vectorTrianglePositiveCoords->isClockwiseOriented());654EXPECT_FALSE(vectorTriangleNegativeCoords->isClockwiseOriented());655EXPECT_FALSE(vectorRectangleOriginAlignedCorners->isClockwiseOriented());656}657658659/* Test the method 'simplified'*/660TEST_F(PositionVectorTest, test_method_simplified) {661const PositionVector vec1(std::vector<Position> {Position(1, 2), Position(1, 2), Position(1, 2)});662const PositionVector result = vec1.simplified();663EXPECT_EQ(3, (int)result.size());664const PositionVector vec2(std::vector<Position> {Position(1, 2), Position(1, 2), Position(1, 2), Position(1, 2)});665const PositionVector result2 = vec2.simplified();666EXPECT_EQ(4, (int)result2.size());667const PositionVector vec3(std::vector<Position> {Position(1, 2), Position(1, 3), Position(1, 4), Position(1, 5)});668const PositionVector result3 = vec3.simplified();669// std::cout << result3 << std::endl;670EXPECT_EQ(3, (int)result3.size());671672const PositionVector vec4(std::vector<Position> {Position(0, 0), Position(0, 8), Position(NUMERICAL_EPS / 2., 7), Position(NUMERICAL_EPS, 6), Position(3. * NUMERICAL_EPS / 2., 5),673Position(2. * NUMERICAL_EPS, 4), Position(3. * NUMERICAL_EPS / 2., 3), Position(NUMERICAL_EPS, 2), Position(NUMERICAL_EPS / 2., 1)674});675const PositionVector result4 = vec4.simplified();676EXPECT_EQ(3, (int)result4.size());677}678679680/* Test the method 'simplified2'*/681TEST_F(PositionVectorTest, test_method_simplified2) {682const PositionVector vec1(std::vector<Position> {Position(1, 2), Position(1, 2), Position(1, 2)});683const PositionVector result = vec1.simplified2(true);684EXPECT_EQ(2, (int)result.size());685const PositionVector vec2(std::vector<Position> {Position(1, 2), Position(1, 2), Position(1, 2), Position(1, 2)});686const PositionVector result2 = vec2.simplified2(true);687EXPECT_EQ(2, (int)result2.size());688const PositionVector vec3(std::vector<Position> {Position(1, 2), Position(1, 3), Position(1, 4), Position(1, 5)});689const PositionVector result3 = vec3.simplified2(true);690// std::cout << result3 << std::endl;691EXPECT_EQ(2, (int)result3.size());692EXPECT_DOUBLE_EQ(2., result3.front().y());693EXPECT_DOUBLE_EQ(5., result3.back().y());694695const PositionVector vec4(std::vector<Position> {Position(0, 0), Position(0, 8), Position(NUMERICAL_EPS / 2., 7), Position(NUMERICAL_EPS, 6), Position(3. * NUMERICAL_EPS / 2., 5),696Position(2. * NUMERICAL_EPS, 4), Position(3. * NUMERICAL_EPS / 2., 3), Position(NUMERICAL_EPS, 2), Position(NUMERICAL_EPS / 2., 1)697});698const PositionVector result4 = vec4.simplified2(true);699EXPECT_EQ(3, (int)result4.size());700EXPECT_DOUBLE_EQ(0., result4.front().y());701EXPECT_DOUBLE_EQ(8., result4[1].y());702EXPECT_DOUBLE_EQ(4., result4.back().y());703}704705706