klayout/src/db/unit_tests/dbPolygon.cc

1352 lines
43 KiB
C++

/*
KLayout Layout Viewer
Copyright (C) 2006-2019 Matthias Koefferlein
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "dbPolygon.h"
#include "dbPolygonTools.h"
#include "dbPath.h"
#include "dbBox.h"
#include "dbEdge.h"
#include "dbText.h"
#include "dbShapeRepository.h"
#include "tlReuseVector.h"
#include "tlUnitTest.h"
#include <vector>
namespace
{
class TestMemStatistics
: public db::MemStatistics
{
public:
TestMemStatistics ()
: used (0), reqd (0)
{ }
virtual void add (const std::type_info & /*ti*/, void * /*ptr*/, size_t r, size_t u, void * /*parent*/, purpose_t /*purpose*/ = None, int /*cat*/ = 0)
{
used += u;
reqd += r;
}
void clear ()
{
used = reqd = 0;
}
public:
size_t used, reqd;
};
}
TEST(1)
{
db::Polygon p;
db::Polygon empty;
db::Box b;
EXPECT_EQ (empty == p, true);
EXPECT_EQ (p.is_box (), false);
std::vector <db::Point> c1, c2, c3;
c1.push_back (db::Point (0, 0));
c1.push_back (db::Point (0, 1000));
c1.push_back (db::Point (100, 1000));
c1.push_back (db::Point (100, 0));
p.assign_hull (c1.begin (), c1.end ());
b = p.box ();
EXPECT_EQ (p.holes (), size_t (0));
EXPECT_EQ (p.area (), 1000*100);
EXPECT_EQ (p.area2 (), 2*1000*100);
EXPECT_EQ (tl::to_string (p.area_ratio ()), "1");
EXPECT_EQ (p.perimeter (), db::Polygon::perimeter_type (2200));
EXPECT_EQ (p.is_box (), true);
c2.push_back (db::Point (10, 10));
c2.push_back (db::Point (10, 390));
c2.push_back (db::Point (90, 390));
c2.push_back (db::Point (90, 10));
p.insert_hole (c2.begin (), c2.end ());
c3.push_back (db::Point (10, 510));
c3.push_back (db::Point (10, 890));
c3.push_back (db::Point (90, 890));
c3.push_back (db::Point (90, 510));
p.insert_hole (c3.begin (), c3.end ());
EXPECT_EQ (p.holes (), size_t (2));
EXPECT_EQ (p.to_string (), std::string ("(0,0;0,1000;100,1000;100,0/10,10;90,10;90,390;10,390/10,510;90,510;90,890;10,890)"));
db::DPolygon dp (p, db::cast_op<db::DPoint, db::Point> ());
EXPECT_EQ (dp.to_string (), std::string ("(0,0;0,1000;100,1000;100,0/10,10;90,10;90,390;10,390/10,510;90,510;90,890;10,890)"));
db::Polygon ip = db::Polygon (dp);
EXPECT_EQ (ip.to_string (), std::string ("(0,0;0,1000;100,1000;100,0/10,10;90,10;90,390;10,390/10,510;90,510;90,890;10,890)"));
EXPECT_EQ (ip.vertices (), size_t (12));
EXPECT_EQ (p.area (), 1000*100-2*380*80);
EXPECT_EQ (p.area2 (), 2*(1000*100-2*380*80));
EXPECT_EQ (tl::to_string (p.area_ratio (), 6), "2.55102");
EXPECT_EQ (p.perimeter (), db::Polygon::perimeter_type (2000+200+4*(380+80)));
EXPECT_EQ (p.is_box (), false);
EXPECT_EQ (p.box (), b);
unsigned int e = 0;
db::Edge::distance_type u = 0;
for (db::Polygon::polygon_edge_iterator i = p.begin_edge (); ! i.at_end (); ++i) {
++e;
u += (*i).length ();
}
EXPECT_EQ (e, (unsigned int) 12);
EXPECT_EQ (u, db::Edge::distance_type (2*(1000+100)+4*(380+80)));
db::Polygon pp;
pp.insert_hole (c3.begin (), c3.end ());
pp.insert_hole (c2.begin (), c2.end ());
pp.assign_hull (c1.begin (), c1.end ());
EXPECT_EQ (pp.area (), 1000*100-2*380*80);
EXPECT_EQ (pp.area2 (), 2*(1000*100-2*380*80));
EXPECT_EQ (pp.box (), b);
EXPECT_EQ (p, pp);
pp.transform (db::Trans (1, true, db::Vector (0, 0)));
EXPECT_EQ (p == pp, false);
EXPECT_EQ (p != pp, true);
EXPECT_EQ (pp.box (), b.transformed (db::Trans (1, true, db::Vector (0, 0))));
pp.transform (db::Trans (3, false, db::Vector (0, 0)));
pp.transform (db::Trans (0, true, db::Vector (0, 0)));
EXPECT_EQ (pp.area (), 1000*100-2*380*80);
EXPECT_EQ (pp.box (), b);
EXPECT_EQ (pp, p);
pp.transform (db::Trans (0, false, db::Vector (100, -200)));
EXPECT_EQ (pp.box (), b.moved (db::Vector (100, -200)));
pp.move (-db::Vector (100, -200));
EXPECT_EQ (pp, p);
EXPECT_EQ (pp.box (), b);
p.clear ();
EXPECT_EQ (p, empty);
}
TEST(2)
{
db::SimplePolygon p;
db::SimplePolygon empty;
db::Box b;
EXPECT_EQ (empty == p, true);
std::vector <db::Point> c1;
c1.push_back (db::Point (0, 0));
c1.push_back (db::Point (0, 1000));
c1.push_back (db::Point (100, 1000));
c1.push_back (db::Point (100, 0));
p.assign_hull (c1.begin (), c1.end ());
b = p.box ();
EXPECT_EQ (p.holes (), size_t (0));
EXPECT_EQ (p.area (), 1000*100);
EXPECT_EQ (p.area2 (), 2*1000*100);
EXPECT_EQ (tl::to_string (p.area_ratio ()), "1");
EXPECT_EQ (p.perimeter (), db::SimplePolygon::perimeter_type (2000+200));
EXPECT_EQ (p.is_box (), true);
EXPECT_EQ (p.to_string (), "(0,0;0,1000;100,1000;100,0)");
db::DSimplePolygon dp (p, db::cast_op<db::DPoint, db::Point> ());
EXPECT_EQ (dp.to_string (), "(0,0;0,1000;100,1000;100,0)");
db::SimplePolygon ip = db::SimplePolygon (dp);
EXPECT_EQ (ip.to_string (), "(0,0;0,1000;100,1000;100,0)");
unsigned int e = 0;
db::Edge::distance_type u = 0;
for (db::SimplePolygon::polygon_edge_iterator i = p.begin_edge (); ! i.at_end (); ++i) {
++e;
u += (*i).length ();
}
EXPECT_EQ (e, (unsigned int) 4);
EXPECT_EQ (u, db::Edge::distance_type (2*(1000+100)));
db::SimplePolygon pp;
pp = p;
EXPECT_EQ (pp.area (), 1000*100);
EXPECT_EQ (pp.box (), b);
EXPECT_EQ (p, pp);
pp.transform (db::Trans (1, true, db::Vector (0, 0)));
EXPECT_EQ (p == pp, false);
EXPECT_EQ (p != pp, true);
EXPECT_EQ (pp.box (), b.transformed (db::Trans (1, true, db::Vector (0, 0))));
pp.transform (db::Trans (3, false, db::Vector (0, 0)));
pp.transform (db::Trans (0, true, db::Vector (0, 0)));
EXPECT_EQ (pp.area (), 1000*100);
EXPECT_EQ (pp.box (), b);
EXPECT_EQ (pp, p);
pp.transform (db::Trans (0, false, db::Vector (100, -200)));
EXPECT_EQ (pp.box (), b.moved (db::Vector (100, -200)));
pp.move (-db::Vector (100, -200));
EXPECT_EQ (pp, p);
EXPECT_EQ (pp.box (), b);
p.clear ();
EXPECT_EQ (p, empty);
}
TEST(3)
{
db::Point pts [] = {
db::Point (100, 120),
db::Point (100, 140),
db::Point (100, 160),
db::Point (100, 180),
db::Point (100, 200),
db::Point (0, 200),
db::Point (0, 300),
db::Point (300, 300),
db::Point (300, 100),
db::Point (100, 100)
};
for (unsigned int off = 0; off < sizeof (pts) / sizeof (pts [0]); ++off) {
typedef db::polygon_contour<db::Coord> Ctr;
Ctr contour;
std::vector <db::Point> c1;
for (unsigned int i = 0; i < sizeof (pts) / sizeof (pts [0]); ++i) {
c1.push_back (pts [(i + off) % (sizeof (pts) / sizeof (pts [0]))]);
}
contour.assign (c1.begin (), c1.end (), false);
TestMemStatistics ms;
EXPECT_EQ (contour.size (), size_t (6));
EXPECT_EQ (contour.is_hole (), false);
ms.clear ();
contour.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.used, 3 * sizeof(db::Point) + sizeof(Ctr));
EXPECT_EQ (contour[0], db::Point (100,100));
EXPECT_EQ (contour[1], db::Point (100,200));
EXPECT_EQ (contour[2], db::Point (0,200));
EXPECT_EQ (contour[3], db::Point (0,300));
EXPECT_EQ (contour[4], db::Point (300,300));
EXPECT_EQ (contour[5], db::Point (300,100));
contour.assign (c1.begin (), c1.end (), true);
EXPECT_EQ (contour.size (), size_t (6));
EXPECT_EQ (contour.is_hole (), true);
ms.clear ();
contour.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.used, 3 * sizeof(db::Point) + sizeof(Ctr));
EXPECT_EQ (contour[0], db::Point (100,100));
EXPECT_EQ (contour[1], db::Point (300,100));
EXPECT_EQ (contour[2], db::Point (300,300));
EXPECT_EQ (contour[3], db::Point (0,300));
EXPECT_EQ (contour[4], db::Point (0,200));
EXPECT_EQ (contour[5], db::Point (100,200));
Ctr contour2;
contour2 = contour;
db::Trans t (db::Trans::m45, db::Vector (123, -456));
contour2.transform (t);
EXPECT_EQ (contour2 == contour, false);
EXPECT_EQ (contour2 != contour, true);
contour2.transform (t.inverted ());
EXPECT_EQ (contour2 == contour, true);
EXPECT_EQ (contour2.size (), size_t (6));
EXPECT_EQ (contour2.is_hole (), true);
ms.clear ();
contour.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.used, 3 * sizeof(db::Point) + sizeof(Ctr));
EXPECT_EQ (contour2[0], db::Point (100,100));
EXPECT_EQ (contour2[1], db::Point (300,100));
EXPECT_EQ (contour2[2], db::Point (300,300));
EXPECT_EQ (contour2[3], db::Point (0,300));
EXPECT_EQ (contour2[4], db::Point (0,200));
EXPECT_EQ (contour2[5], db::Point (100,200));
}
}
TEST(4)
{
TestMemStatistics ms;
db::Point pts [] = {
db::Point (100, 150),
db::Point (100, 200),
db::Point (0, 300),
db::Point (300, 300),
db::Point (300, 100),
db::Point (100, 100)
};
for (unsigned int off = 0; off < sizeof (pts) / sizeof (pts [0]); ++off) {
typedef db::polygon_contour<db::Coord> Ctr;
Ctr contour;
std::vector <db::Point> c1;
for (unsigned int i = 0; i < sizeof (pts) / sizeof (pts [0]); ++i) {
c1.push_back (pts [(i + off) % (sizeof (pts) / sizeof (pts [0]))]);
}
contour.assign (c1.begin (), c1.end (), false);
EXPECT_EQ (contour.size (), size_t (5));
EXPECT_EQ (contour.is_hole (), false);
ms.clear ();
contour.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.used, 5 * sizeof(db::Point) + sizeof(Ctr));
EXPECT_EQ (contour[0], db::Point (100,100));
EXPECT_EQ (contour[1], db::Point (100,200));
EXPECT_EQ (contour[2], db::Point (0,300));
EXPECT_EQ (contour[3], db::Point (300,300));
EXPECT_EQ (contour[4], db::Point (300,100));
contour.assign (c1.begin (), c1.end (), true);
EXPECT_EQ (contour.size (), size_t (5));
EXPECT_EQ (contour.is_hole (), true);
ms.clear ();
contour.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.used, 5 * sizeof(db::Point) + sizeof(Ctr));
EXPECT_EQ (contour[0], db::Point (100,100));
EXPECT_EQ (contour[1], db::Point (300,100));
EXPECT_EQ (contour[2], db::Point (300,300));
EXPECT_EQ (contour[3], db::Point (0,300));
EXPECT_EQ (contour[4], db::Point (100,200));
Ctr contour2;
db::Trans t (db::Trans::m45, db::Vector (123, -456));
contour2 = contour.transformed (t);
EXPECT_EQ (contour2 == contour, false);
EXPECT_EQ (contour2 != contour, true);
EXPECT_EQ (contour2.area (), contour.area ());
EXPECT_EQ (contour2.perimeter (), contour.perimeter ());
contour2.transform (t.inverted ());
EXPECT_EQ (contour2 == contour, true);
EXPECT_EQ (contour2.size (), size_t (5));
EXPECT_EQ (contour2.is_hole (), true);
ms.clear ();
contour.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.used, 5 * sizeof(db::Point) + sizeof(Ctr));
EXPECT_EQ (contour2[0], db::Point (100,100));
EXPECT_EQ (contour2[1], db::Point (300,100));
EXPECT_EQ (contour2[2], db::Point (300,300));
EXPECT_EQ (contour2[3], db::Point (0,300));
EXPECT_EQ (contour2[4], db::Point (100,200));
}
}
TEST(5)
{
db::Polygon p;
std::vector <db::Point> c1;
c1.push_back (db::Point (0, 0));
c1.push_back (db::Point (0, 1000));
c1.push_back (db::Point (100, 1000));
c1.push_back (db::Point (100, 0));
p.assign_hull (c1.begin (), c1.end ());
EXPECT_EQ (p.vertices (), size_t (4));
std::vector <db::Point> c2;
c2.push_back (db::Point (10, 10));
c2.push_back (db::Point (10, 110));
c2.push_back (db::Point (20, 110));
c2.push_back (db::Point (20, 10));
p.insert_hole (c2.begin (), c2.end ());
EXPECT_EQ (p.vertices (), size_t (8));
{
db::Polygon::polygon_contour_iterator pt = p.begin_hull ();
EXPECT_EQ (*pt, db::Point (0, 0)); ++pt;
EXPECT_EQ (*pt, db::Point (0, 1000)); ++pt;
EXPECT_EQ (*pt, db::Point (100, 1000)); ++pt;
EXPECT_EQ (*pt, db::Point (100, 0)); ++pt;
EXPECT_EQ (pt == p.end_hull (), true);
}
{
db::Polygon::polygon_contour_iterator pt = p.begin_hole (0);
EXPECT_EQ (*pt, db::Point (10, 10)); ++pt;
EXPECT_EQ (*pt, db::Point (20, 10)); ++pt;
EXPECT_EQ (*pt, db::Point (20, 110)); ++pt;
EXPECT_EQ (*pt, db::Point (10, 110)); ++pt;
EXPECT_EQ (pt == p.end_hole (0), true);
}
db::GenericRepository rep;
db::polygon_ref<db::Polygon, db::Trans> pref (p, rep);
{
db::polygon_ref<db::Polygon, db::Trans>::polygon_contour_iterator pt = pref.begin_hull ();
EXPECT_EQ (*pt, db::Point (0, 0)); ++pt;
EXPECT_EQ (*pt, db::Point (0, 1000)); ++pt;
EXPECT_EQ (*pt, db::Point (100, 1000)); ++pt;
EXPECT_EQ (*pt, db::Point (100, 0)); ++pt;
EXPECT_EQ (pt == pref.end_hull (), true);
}
{
db::polygon_ref<db::Polygon, db::Trans>::polygon_contour_iterator pt = pref.begin_hole (0);
EXPECT_EQ (*pt, db::Point (10, 10)); ++pt;
EXPECT_EQ (*pt, db::Point (20, 10)); ++pt;
EXPECT_EQ (*pt, db::Point (20, 110)); ++pt;
EXPECT_EQ (*pt, db::Point (10, 110)); ++pt;
EXPECT_EQ (pt == pref.end_hole (0), true);
}
db::Trans t (db::Trans::m45, db::Vector (123, -456));
p.transform (t);
pref.transform (t);
{
db::Polygon::polygon_contour_iterator pt = p.begin_hull ();
EXPECT_EQ (*pt, db::Point (123, -456)); ++pt;
EXPECT_EQ (*pt, db::Point (123, -356)); ++pt;
EXPECT_EQ (*pt, db::Point (1123, -356)); ++pt;
EXPECT_EQ (*pt, db::Point (1123, -456)); ++pt;
EXPECT_EQ (pt == p.end_hull (), true);
}
{
db::Polygon::polygon_contour_iterator pt = p.begin_hole (0);
EXPECT_EQ (*pt, db::Point (133, -446)); ++pt;
EXPECT_EQ (*pt, db::Point (233, -446)); ++pt;
EXPECT_EQ (*pt, db::Point (233, -436)); ++pt;
EXPECT_EQ (*pt, db::Point (133, -436)); ++pt;
EXPECT_EQ (pt == p.end_hole (0), true);
}
{
db::polygon_ref<db::Polygon, db::Trans>::polygon_contour_iterator pt = pref.begin_hull ();
EXPECT_EQ (*pt, db::Point (123, -356)); ++pt;
EXPECT_EQ (*pt, db::Point (1123, -356)); ++pt;
EXPECT_EQ (*pt, db::Point (1123, -456)); ++pt;
EXPECT_EQ (*pt, db::Point (123, -456)); ++pt;
EXPECT_EQ (pt == pref.end_hull (), true);
}
{
db::polygon_ref<db::Polygon, db::Trans>::polygon_contour_iterator pt = pref.begin_hole (0);
EXPECT_EQ (*pt, db::Point (233, -446)); ++pt;
EXPECT_EQ (*pt, db::Point (233, -436)); ++pt;
EXPECT_EQ (*pt, db::Point (133, -436)); ++pt;
EXPECT_EQ (*pt, db::Point (133, -446)); ++pt;
EXPECT_EQ (pt == pref.end_hole (0), true);
}
EXPECT_EQ (p.area (), 100*1000-10*100);
EXPECT_EQ (p.area2 (), 2*(100*1000-10*100));
EXPECT_EQ (tl::to_string (p.area_ratio (), 6), "1.0101");
EXPECT_EQ (p.perimeter (), db::Polygon::perimeter_type (200+2000+20+200));
EXPECT_EQ (pref.area (), 100*1000-10*100);
EXPECT_EQ (pref.area2 (), 2*(100*1000-10*100));
EXPECT_EQ (pref.perimeter (), db::Polygon::perimeter_type (200+2000+20+200));
}
TEST(6)
{
db::Box bx (db::Point (0, 0), db::Point (1000, 2000));
db::Polygon p(bx);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (-1, 0)), -1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (0, -1)), -1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (0, 0)), 0);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (1, 0)), 0);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (1, 1)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (999, 1999)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (999, 2000)), 0);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (1000, 2000)), 0);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (1000, 1999)), 0);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (1000, 2001)), -1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (1001, 2000)), -1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (500, 500)), 1);
db::inside_poly_test<db::Polygon> it (p);
EXPECT_EQ (it (db::Point (-1, 0)), -1);
EXPECT_EQ (it (db::Point (0, -1)), -1);
EXPECT_EQ (it (db::Point (0, 0)), 0);
EXPECT_EQ (it (db::Point (1, 0)), 0);
EXPECT_EQ (it (db::Point (1, 1)), 1);
EXPECT_EQ (it (db::Point (999, 1999)), 1);
EXPECT_EQ (it (db::Point (999, 2000)), 0);
EXPECT_EQ (it (db::Point (1000, 2000)), 0);
EXPECT_EQ (it (db::Point (1000, 1999)), 0);
EXPECT_EQ (it (db::Point (1000, 2001)), -1);
EXPECT_EQ (it (db::Point (1001, 2000)), -1);
EXPECT_EQ (it (db::Point (500, 500)), 1);
std::vector <db::Point> c1;
c1.push_back (db::Point (0, 0));
c1.push_back (db::Point (0, 4));
c1.push_back (db::Point (0, 7));
c1.push_back (db::Point (2, 7));
c1.push_back (db::Point (3, 2));
c1.push_back (db::Point (4, 7));
c1.push_back (db::Point (5, 7));
c1.push_back (db::Point (6, 4));
c1.push_back (db::Point (7, 7));
c1.push_back (db::Point (8, 7));
c1.push_back (db::Point (9, 3));
c1.push_back (db::Point (10, 7));
c1.push_back (db::Point (12, 7));
c1.push_back (db::Point (12, 4));
c1.push_back (db::Point (12, 0));
p.assign_hull (c1.begin (), c1.end ());
EXPECT_EQ (p.is_box (), false);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (-1, 2)), -1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (0, 2)), 0);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (1, 2)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (2, 2)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (3, 2)), 0);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (4, 2)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (11, 2)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (12, 2)), 0);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (13, 2)), -1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (-1, 4)), -1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (0, 4)), 0);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (1, 4)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (2, 4)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (3, 4)), -1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (4, 4)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (5, 4)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (6, 4)), 0);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (7, 4)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (8, 4)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (9, 4)), -1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (10, 4)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (11, 4)), 1);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (12, 4)), 0);
EXPECT_EQ (db::inside_poly (p.begin_edge (), db::Point (13, 4)), -1);
db::inside_poly_test<db::Polygon> it2 (p);
EXPECT_EQ (it2 (db::Point (-1, 2)), -1);
EXPECT_EQ (it2 (db::Point (0, 2)), 0);
EXPECT_EQ (it2 (db::Point (1, 2)), 1);
EXPECT_EQ (it2 (db::Point (2, 2)), 1);
EXPECT_EQ (it2 (db::Point (3, 2)), 0);
EXPECT_EQ (it2 (db::Point (4, 2)), 1);
EXPECT_EQ (it2 (db::Point (11, 2)), 1);
EXPECT_EQ (it2 (db::Point (12, 2)), 0);
EXPECT_EQ (it2 (db::Point (13, 2)), -1);
EXPECT_EQ (it2 (db::Point (-1, 4)), -1);
EXPECT_EQ (it2 (db::Point (0, 4)), 0);
EXPECT_EQ (it2 (db::Point (1, 4)), 1);
EXPECT_EQ (it2 (db::Point (2, 4)), 1);
EXPECT_EQ (it2 (db::Point (3, 4)), -1);
EXPECT_EQ (it2 (db::Point (4, 4)), 1);
EXPECT_EQ (it2 (db::Point (5, 4)), 1);
EXPECT_EQ (it2 (db::Point (6, 4)), 0);
EXPECT_EQ (it2 (db::Point (7, 4)), 1);
EXPECT_EQ (it2 (db::Point (8, 4)), 1);
EXPECT_EQ (it2 (db::Point (9, 4)), -1);
EXPECT_EQ (it2 (db::Point (10, 4)), 1);
EXPECT_EQ (it2 (db::Point (11, 4)), 1);
EXPECT_EQ (it2 (db::Point (12, 4)), 0);
EXPECT_EQ (it2 (db::Point (13, 4)), -1);
}
TEST(7)
{
TestMemStatistics ms;
db::Point pts [] = {
db::Point (0, 0),
db::Point (0, 4),
db::Point (4, 4),
db::Point (4, 0),
db::Point (4, 4),
db::Point (0, 4),
};
for (unsigned int off = 0; off < sizeof (pts) / sizeof (pts [0]); ++off) {
typedef db::polygon_contour<db::Coord> Ctr;
Ctr contour;
std::vector <db::Point> c1;
for (unsigned int i = 0; i < sizeof (pts) / sizeof (pts [0]); ++i) {
c1.push_back (pts [(i + off) % (sizeof (pts) / sizeof (pts [0]))]);
}
contour.assign (c1.begin (), c1.end (), false);
EXPECT_EQ (contour.size (), size_t (6));
EXPECT_EQ (contour.is_hole (), false);
ms.clear ();
contour.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.used, 6 * sizeof(db::Point) + sizeof(Ctr));
EXPECT_EQ (contour[0], db::Point (0,0));
EXPECT_EQ (contour[1], db::Point (0,4));
EXPECT_EQ (contour[2], db::Point (4,4));
EXPECT_EQ (contour[3], db::Point (4,0));
EXPECT_EQ (contour[4], db::Point (4,4));
EXPECT_EQ (contour[5], db::Point (0,4));
contour.assign (c1.begin (), c1.end (), true);
EXPECT_EQ (contour.size (), size_t (6));
EXPECT_EQ (contour.is_hole (), true);
ms.clear ();
contour.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.used, 6 * sizeof(db::Point) + sizeof(Ctr));
EXPECT_EQ (contour[0], db::Point (0,0));
EXPECT_EQ (contour[1], db::Point (0,4));
EXPECT_EQ (contour[2], db::Point (4,4));
EXPECT_EQ (contour[3], db::Point (4,0));
EXPECT_EQ (contour[4], db::Point (4,4));
EXPECT_EQ (contour[5], db::Point (0,4));
Ctr contour2;
contour2 = contour;
db::Trans t (db::Trans::m45, db::Vector (123, -456));
contour2.transform (t);
EXPECT_EQ (contour2 == contour, false);
EXPECT_EQ (contour2 != contour, true);
contour2.transform (t.inverted ());
EXPECT_EQ (contour2 == contour, true);
EXPECT_EQ (contour2.size (), size_t (6));
EXPECT_EQ (contour2.is_hole (), true);
ms.clear ();
contour.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.used, 6 * sizeof(db::Point) + sizeof(Ctr));
EXPECT_EQ (contour2[0], db::Point (0,0));
EXPECT_EQ (contour2[1], db::Point (0,4));
EXPECT_EQ (contour2[2], db::Point (4,4));
EXPECT_EQ (contour2[3], db::Point (4,0));
EXPECT_EQ (contour2[4], db::Point (4,4));
EXPECT_EQ (contour2[5], db::Point (0,4));
}
}
TEST(8)
{
db::SimplePolygon p;
std::vector<db::Point> pts;
pts.push_back (db::Point (6800, -35)); // redundant
pts.push_back (db::Point (6800, -325));
pts.push_back (db::Point (5240, -325));
pts.push_back (db::Point (5240, 5915));
pts.push_back (db::Point (6800, 5915)); // redundant
pts.push_back (db::Point (10200, 5915));
pts.push_back (db::Point (10200, 5685));
pts.push_back (db::Point (6800, 5685));
pts.push_back (db::Point (6800, 195)); // redundant
for (unsigned int i = 0; i < 16; ++i) {
p.assign_hull (pts.begin (), pts.end ());
db::SimplePolygon::polygon_contour_iterator h = p.begin_hull ();
EXPECT_EQ (*h, db::Point (5240, -325)); h++;
EXPECT_EQ (*h, db::Point (5240, 5915)); h++;
EXPECT_EQ (*h, db::Point (10200, 5915)); h++;
EXPECT_EQ (*h, db::Point (10200, 5685)); h++;
EXPECT_EQ (*h, db::Point (6800, 5685)); h++;
EXPECT_EQ (*h, db::Point (6800, -325)); h++;
EXPECT_EQ (h == p.end_hull (), true);
db::Point p0 = pts [0];
pts.erase (pts.begin ());
pts.push_back (p0);
}
std::reverse (pts.begin (), pts.end ());
for (unsigned int i = 0; i < 16; ++i) {
p.assign_hull (pts.begin (), pts.end ());
db::SimplePolygon::polygon_contour_iterator h = p.begin_hull ();
EXPECT_EQ (*h, db::Point (5240, -325)); h++;
EXPECT_EQ (*h, db::Point (5240, 5915)); h++;
EXPECT_EQ (*h, db::Point (10200, 5915)); h++;
EXPECT_EQ (*h, db::Point (10200, 5685)); h++;
EXPECT_EQ (*h, db::Point (6800, 5685)); h++;
EXPECT_EQ (*h, db::Point (6800, -325)); h++;
EXPECT_EQ (h == p.end_hull (), true);
db::Point p0 = pts [0];
pts.erase (pts.begin ());
pts.push_back (p0);
}
std::vector<db::Point> ppts;
for (std::vector<db::Point>::const_iterator pp = pts.begin (); pp != pts.end (); ++pp) {
ppts.push_back (*pp);
ppts.push_back (*pp);
}
pts = ppts;
for (unsigned int i = 0; i < 32; ++i) {
p.assign_hull (pts.begin (), pts.end ());
db::SimplePolygon::polygon_contour_iterator h = p.begin_hull ();
EXPECT_EQ (*h, db::Point (5240, -325)); h++;
EXPECT_EQ (*h, db::Point (5240, 5915)); h++;
EXPECT_EQ (*h, db::Point (10200, 5915)); h++;
EXPECT_EQ (*h, db::Point (10200, 5685)); h++;
EXPECT_EQ (*h, db::Point (6800, 5685)); h++;
EXPECT_EQ (*h, db::Point (6800, -325)); h++;
EXPECT_EQ (h == p.end_hull (), true);
db::Point p0 = pts [0];
pts.erase (pts.begin ());
pts.push_back (p0);
}
std::reverse (pts.begin (), pts.end ());
for (unsigned int i = 0; i < 32; ++i) {
p.assign_hull (pts.begin (), pts.end ());
db::SimplePolygon::polygon_contour_iterator h = p.begin_hull ();
EXPECT_EQ (*h, db::Point (5240, -325)); h++;
EXPECT_EQ (*h, db::Point (5240, 5915)); h++;
EXPECT_EQ (*h, db::Point (10200, 5915)); h++;
EXPECT_EQ (*h, db::Point (10200, 5685)); h++;
EXPECT_EQ (*h, db::Point (6800, 5685)); h++;
EXPECT_EQ (*h, db::Point (6800, -325)); h++;
EXPECT_EQ (h == p.end_hull (), true);
db::Point p0 = pts [0];
pts.erase (pts.begin ());
pts.push_back (p0);
}
}
TEST(9)
{
db::SimplePolygon p;
std::vector<db::Point> pts;
pts.push_back (db::Point (6800, -35)); // redundant
pts.push_back (db::Point (6800, -35)); // redundant
pts.push_back (db::Point (6800, -35)); // redundant
pts.push_back (db::Point (6800, -35)); // redundant
pts.push_back (db::Point (6800, -35)); // redundant
pts.push_back (db::Point (6800, -35)); // redundant
pts.push_back (db::Point (6800, -35)); // redundant
p.assign_hull (pts.begin (), pts.end ());
db::SimplePolygon::polygon_contour_iterator h = p.begin_hull ();
EXPECT_EQ (h == p.end_hull (), true);
}
TEST(10)
{
db::SimplePolygon p;
std::vector<db::Point> pts;
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 3000));
pts.push_back (db::Point (0, 2000));
pts.push_back (db::Point (0, 0));
pts.push_back (db::Point (1000, 1000));
pts.push_back (db::Point (1000, 2000));
p.assign_hull (pts.begin (), pts.end ());
db::SimplePolygon::polygon_contour_iterator h = p.begin_hull ();
EXPECT_EQ (*h, db::Point (0, 0)); h++;
EXPECT_EQ (*h, db::Point (0, 2000)); h++;
EXPECT_EQ (*h, db::Point (1000, 3000)); h++;
EXPECT_EQ (*h, db::Point (1000, 1000)); h++;
EXPECT_EQ (h == p.end_hull (), true);
}
TEST(11)
{
db::SimplePolygon p;
std::vector<db::Point> pts;
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 3000));
pts.push_back (db::Point (0, 2000));
pts.push_back (db::Point (0, 0));
pts.push_back (db::Point (1000, 1000));
pts.push_back (db::Point (1000, 2000));
p.assign_hull (pts.begin (), pts.end (), false /*not compressed*/);
db::SimplePolygon::polygon_contour_iterator h = p.begin_hull ();
EXPECT_EQ (*h, db::Point (0, 0)); h++;
EXPECT_EQ (*h, db::Point (0, 2000)); h++;
EXPECT_EQ (*h, db::Point (1000, 3000)); h++;
EXPECT_EQ (*h, db::Point (1000, 2000)); h++;
EXPECT_EQ (*h, db::Point (1000, 2000)); h++;
EXPECT_EQ (*h, db::Point (1000, 1000)); h++;
EXPECT_EQ (h == p.end_hull (), true);
}
TEST(12)
{
db::Polygon p;
std::vector<db::Point> pts;
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 3000));
pts.push_back (db::Point (0, 2000));
pts.push_back (db::Point (0, 0));
pts.push_back (db::Point (1000, 1000));
pts.push_back (db::Point (1000, 2000));
p.assign_hull (pts.begin (), pts.end (), false /*not compressed*/);
db::SimplePolygon::polygon_contour_iterator h = p.begin_hull ();
EXPECT_EQ (*h, db::Point (0, 0)); h++;
EXPECT_EQ (*h, db::Point (0, 2000)); h++;
EXPECT_EQ (*h, db::Point (1000, 3000)); h++;
EXPECT_EQ (*h, db::Point (1000, 2000)); h++;
EXPECT_EQ (*h, db::Point (1000, 2000)); h++;
EXPECT_EQ (*h, db::Point (1000, 1000)); h++;
EXPECT_EQ (h == p.end_hull (), true);
}
TEST(13)
{
db::Polygon p;
std::vector<db::Point> pts;
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 3000));
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (0, 2000));
pts.push_back (db::Point (0, 0));
pts.push_back (db::Point (1000, 1000));
pts.push_back (db::Point (1000, 1500));
pts.push_back (db::Point (1000, 2000));
p.assign_hull (pts.begin (), pts.end (), false /*not compressed*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,3000;1000,2000;1000,2000;1000,2000;1000,1500;1000,1000)");
p.compress (true /*remove reflected*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,1000)");
p.assign_hull (pts.begin (), pts.end (), true /*compressed*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,3000;1000,1000)");
p.assign_hull (pts.begin (), pts.end (), true /*compressed*/, true /*remove reflected*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,1000)");
}
TEST(14)
{
db::Polygon p;
std::vector<db::Point> pts;
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 3000));
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (0, 2000));
pts.push_back (db::Point (0, 0));
pts.push_back (db::Point (200, 200));
pts.push_back (db::Point (500, 500));
pts.push_back (db::Point (1000, 1000));
pts.push_back (db::Point (1000, 1500));
pts.push_back (db::Point (1000, 2000));
p.assign_hull (pts.begin (), pts.end (), false /*not compressed*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,3000;1000,2000;1000,2000;1000,2000;1000,1500;1000,1000;500,500;200,200)");
p.compress (true);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,1000)");
p.assign_hull (pts.begin (), pts.end (), true /*not compressed*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,3000;1000,1000)");
p.assign_hull (pts.begin (), pts.end (), true /*not compressed*/, true /*remove reflected*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,1000)");
}
TEST(13M)
{
db::Polygon p;
std::vector<db::Point> pts;
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 3000));
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (0, 2000));
pts.push_back (db::Point (0, 0));
pts.push_back (db::Point (1000, 0));
pts.push_back (db::Point (1000, 1000));
pts.push_back (db::Point (1000, 1500));
pts.push_back (db::Point (1000, 2000));
p.assign_hull (pts.begin (), pts.end (), false /*not compressed*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,3000;1000,2000;1000,2000;1000,2000;1000,1500;1000,1000;1000,0)");
EXPECT_EQ (p.vertices (), size_t (10));
p.compress (true /*remove reflected*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,0)");
EXPECT_EQ (p.vertices (), size_t (4));
p.assign_hull (pts.begin (), pts.end (), true /*compressed*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,3000;1000,0)");
EXPECT_EQ (p.vertices (), size_t (5));
p.assign_hull (pts.begin (), pts.end (), true /*compressed*/, true /*remove reflected*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,0)");
EXPECT_EQ (p.vertices (), size_t (4));
}
TEST(13S)
{
db::SimplePolygon p;
std::vector<db::Point> pts;
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 3000));
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (0, 2000));
pts.push_back (db::Point (0, 0));
pts.push_back (db::Point (1000, 1000));
pts.push_back (db::Point (1000, 1500));
pts.push_back (db::Point (1000, 2000));
p.assign_hull (pts.begin (), pts.end (), false /*not compressed*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,3000;1000,2000;1000,2000;1000,2000;1000,1500;1000,1000)");
p.compress (true /*remove reflected*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,1000)");
p.assign_hull (pts.begin (), pts.end (), true /*compressed*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,3000;1000,1000)");
p.assign_hull (pts.begin (), pts.end (), true /*compressed*/, true /*remove reflected*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,1000)");
}
TEST(14S)
{
db::SimplePolygon p;
std::vector<db::Point> pts;
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (1000, 3000));
pts.push_back (db::Point (1000, 2000));
pts.push_back (db::Point (0, 2000));
pts.push_back (db::Point (0, 0));
pts.push_back (db::Point (200, 200));
pts.push_back (db::Point (500, 500));
pts.push_back (db::Point (1000, 1000));
pts.push_back (db::Point (1000, 1500));
pts.push_back (db::Point (1000, 2000));
p.assign_hull (pts.begin (), pts.end (), false /*not compressed*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,3000;1000,2000;1000,2000;1000,2000;1000,1500;1000,1000;500,500;200,200)");
EXPECT_EQ (p.vertices (), size_t (11));
p.compress (true);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,1000)");
EXPECT_EQ (p.vertices (), size_t (4));
p.assign_hull (pts.begin (), pts.end (), true /*not compressed*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,3000;1000,1000)");
p.assign_hull (pts.begin (), pts.end (), true /*not compressed*/, true /*remove reflected*/);
EXPECT_EQ (p.to_string(), "(0,0;0,2000;1000,2000;1000,1000)");
}
TEST(14S2)
{
db::SimplePolygon p;
std::vector<db::Point> pts;
pts.push_back (db::Point (200, 200));
pts.push_back (db::Point (200, 200));
pts.push_back (db::Point (300, 100));
pts.push_back (db::Point (400, 100));
pts.push_back (db::Point (400, 200));
pts.push_back (db::Point (500, 200));
pts.push_back (db::Point (500, 0));
pts.push_back (db::Point (0, 0));
pts.push_back (db::Point (0, 100));
pts.push_back (db::Point (100, 100));
p.assign_hull (pts.begin (), pts.end (), false /*not compressed*/);
EXPECT_EQ (p.to_string(), "(0,0;0,100;100,100;200,200;200,200;300,100;400,100;400,200;500,200;500,0)");
p.compress (true);
EXPECT_EQ (p.to_string(), "(0,0;0,100;100,100;200,200;300,100;400,100;400,200;500,200;500,0)");
p.assign_hull (pts.begin (), pts.end (), true /*not compressed*/);
EXPECT_EQ (p.to_string(), "(0,0;0,100;100,100;200,200;300,100;400,100;400,200;500,200;500,0)");
p.assign_hull (pts.begin (), pts.end (), true /*not compressed*/, true /*remove reflected*/);
EXPECT_EQ (p.to_string(), "(0,0;0,100;100,100;200,200;300,100;400,100;400,200;500,200;500,0)");
}
TEST(20)
{
db::Polygon poly;
EXPECT_EQ (poly.to_string (), "()");
poly.size (100);
EXPECT_EQ (poly.to_string (), "()");
db::Point pts[] = {
db::Point (100, 100),
db::Point (400, 100),
db::Point (400, 400),
db::Point (100, 400)
};
poly.assign_hull (pts, pts + sizeof (pts) / sizeof (pts[0]));
poly.size (100);
EXPECT_EQ (poly.to_string (), "(0,0;0,500;500,500;500,0)");
poly.assign_hull (pts, pts + sizeof (pts) / sizeof (pts[0]));
poly.size (-100);
EXPECT_EQ (poly.to_string (), "(100,100;200,100;200,400;100,400;100,300;400,300;400,400;300,400;300,100;400,100;400,200;100,200)");
poly.assign_hull (pts, pts + sizeof (pts) / sizeof (pts[0]));
poly.size (db::Coord (100), db::Coord (0));
EXPECT_EQ (poly.to_string (), "(0,100;0,400;500,400;500,100)");
poly.assign_hull (pts, pts + sizeof (pts) / sizeof (pts[0]));
poly.size (db::Coord (0), db::Coord (100));
EXPECT_EQ (poly.to_string (), "(100,0;100,500;400,500;400,0)");
poly.assign_hull (pts, pts + sizeof (pts) / sizeof (pts[0]));
poly.size (db::Coord (-100), db::Coord (0));
EXPECT_EQ (poly.to_string (), "(100,100;200,100;200,400;100,400;400,400;300,400;300,100;400,100)");
poly.assign_hull (pts, pts + sizeof (pts) / sizeof (pts[0]));
poly.size (db::Coord (0), db::Coord (-100));
EXPECT_EQ (poly.to_string (), "(100,100;100,400;100,300;400,300;400,400;400,100;400,200;100,200)");
poly.assign_hull (pts, pts + sizeof (pts) / sizeof (pts[0]));
poly.size (-400);
EXPECT_EQ (poly.to_string (), "(100,0;400,0;400,400;0,400;0,100;400,100;400,500;100,500;100,100;500,100;500,400;100,400)");
poly.assign_hull (pts, pts + sizeof (pts) / sizeof (pts[0]));
poly.size (100, 100, 0);
EXPECT_EQ (poly.to_string (), "(100,0;0,100;0,400;100,500;400,500;500,400;500,100;400,0)");
db::Point pts2[] = {
db::Point (0, 0),
db::Point (0, 400),
db::Point (100, 400),
db::Point (100, 100),
db::Point (400, 100),
db::Point (400, 0)
};
poly.assign_hull (pts2, pts2 + sizeof (pts2) / sizeof (pts2[0]));
poly.size (0, -100, 2);
EXPECT_EQ (poly.to_string (), "(0,0;0,400;0,300;100,300;100,400;100,0;400,0;400,100;400,0;400,100;0,100)");
db::Point pts3[] = {
db::Point (0, 0),
db::Point (0, 100),
db::Point (50, 100),
db::Point (75, 50),
db::Point (150, 300),
db::Point (200, 300),
db::Point (200, 0)
};
poly.assign_hull (pts3, pts3 + sizeof (pts3) / sizeof (pts3[0]));
poly.size (100, 100, 4);
EXPECT_EQ (poly.to_string (), "(-100,-100;-100,200;112,200;164,95;75,50;-21,79;76,400;300,400;300,-100)");
poly.assign_hull (pts3, pts3 + sizeof (pts3) / sizeof (pts3[0]));
poly.size (100, 100, 5);
EXPECT_EQ (poly.to_string (), "(-100,-100;-100,200;112,200;164,95;75,50;-21,79;76,400;300,400;300,-100)");
db::Point pts4[] = {
db::Point (0, 0),
db::Point (0, 200),
db::Point (100, 300),
db::Point (400, 300),
db::Point (200, 100),
db::Point (200, 0)
};
poly.assign_hull (pts4, pts4 + sizeof (pts4) / sizeof (pts4[0]));
poly.size (-100, -100, 2);
EXPECT_EQ (poly.to_string (), "(0,0;100,0;100,200;0,200;71,129;171,229;100,300;100,200;400,200;400,300;329,371;100,142;100,0;200,0;200,100;0,100)");
db::Point pts5[] = {
db::Point (0, 0),
db::Point (0, 100),
db::Point (100, 100),
db::Point (100, 50),
db::Point (150, 250),
db::Point (250, 250),
db::Point (250, 0)
};
poly.assign_hull (pts5, pts5 + sizeof (pts5) / sizeof (pts5[0]));
poly.size (50, 50, 4);
EXPECT_EQ (poly.to_string (), "(-50,-50;-50,150;150,150;150,50;100,50;51,62;111,300;300,300;300,-50)");
db::Point pts6[] = {
db::Point (100, 0),
db::Point (100, 100),
db::Point (0, 200),
db::Point (50, 250),
db::Point (200, 100),
db::Point (200, 0)
};
poly.assign_hull (pts6, pts6 + sizeof (pts6) / sizeof (pts6[0]));
poly.size (2, 2, 4);
EXPECT_EQ (poly.to_string (), "(98,-2;98,100;100,100;99,99;-2,200;50,252;202,100;202,-2)");
db::Point pts7[] = {
db::Point (-90122, -84700),
db::Point (-90162, -84652),
db::Point (-90195, -84613),
db::Point (-90229, -84572),
db::Point (-90265, -84528),
db::Point (-90304, -84481),
db::Point (-90346, -84431),
db::Point (-90390, -84378),
db::Point (-90400, -84366),
db::Point (-90400, -84300),
db::Point (-90000, -84300),
db::Point (-90000, -84700)
};
poly.assign_hull (pts7, pts7 + sizeof (pts7) / sizeof (pts7[0]));
poly.size (50, 50, 4);
EXPECT_EQ (poly.to_string (), "(-90145,-84750;-90200,-84684;-90233,-84645;-90267,-84604;-90304,-84560;-90342,-84513;-90384,-84463;-90428,-84410;-90450,-84384;-90450,-84250;-89950,-84250;-89950,-84750)");
}
TEST(21)
{
TestMemStatistics ms;
{
db::Box box (0,0,2048,1536);
db::Polygon poly (box);
db::ICplxTrans t (7, 45, false, db::Vector (123,-10152));
EXPECT_EQ (poly.to_string (), "(0,0;0,1536;2048,1536;2048,0)");
poly.transform (t);
EXPECT_EQ (poly.to_string (), "(123,-10152;-7480,-2549;2657,7588;10260,-15)");
#if !defined(_MSC_VER)
ms.clear ();
poly.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.reqd, (sizeof(void *)-4)*5+68);
#endif
}
{
db::Box box (0,0,2048,1536);
db::Polygon poly (box);
db::ICplxTrans t (7, 0, false, db::Vector (123,-10152));
EXPECT_EQ (poly.to_string (), "(0,0;0,1536;2048,1536;2048,0)");
poly.transform (t);
EXPECT_EQ (poly.to_string (), "(123,-10152;123,600;14459,600;14459,-10152)");
#if !defined(_MSC_VER)
ms.clear ();
poly.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.reqd, (sizeof(void *)-4)*5+52);
#endif
}
{
db::DBox box (0,0,2048,1536);
db::DPolygon poly (box);
EXPECT_EQ (poly.is_box (), true);
db::DCplxTrans t (7.02268521, 45, false, db::DVector (123.88147866,-10152.0640046));
EXPECT_EQ (poly.to_string (), "(0,0;0,1536;2048,1536;2048,0)");
poly.transform (t);
EXPECT_EQ (poly.is_box (), false);
EXPECT_EQ (poly.to_string (), "(123.88147866,-10152.0640046;-7503.56940256,-2524.61312338;2666.36510573,7645.32138492;10293.815987,17.8705036972)");
#if !defined(_MSC_VER)
ms.clear ();
poly.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.reqd, (sizeof(void *)-4)*5+116);
#endif
}
{
db::DBox box (0,0,2048,1536);
db::DPolygon poly (box);
db::DCplxTrans t (7.02268521, 0, false, db::DVector (123.88147866,-10152.0640046));
EXPECT_EQ (poly.to_string (), "(0,0;0,1536;2048,1536;2048,0)");
// This transformation was not terminating in some builds (release):
poly.transform (t);
EXPECT_EQ (poly.to_string (), "(123.88147866,-10152.0640046;123.88147866,634.78047796;14506.3407887,634.78047796;14506.3407887,-10152.0640046)");
#if !defined(_MSC_VER)
ms.clear ();
poly.mem_stat (&ms, db::MemStatistics::None, 0);
EXPECT_EQ (ms.reqd, (sizeof(void *)-4)*5+116); // no compression for doubles!
#endif
}
}
TEST(22)
{
db::Polygon poly;
std::string s ("(0,0;0,1000;100,1000;100,0/10,10;90,10;90,390;10,390/10,510;90,510;90,890;10,890)");
tl::Extractor ex (s.c_str ());
ex.read (poly);
EXPECT_EQ (poly.to_string (), s);
}
TEST(23)
{
db::DPolygon poly;
std::string s ("(0,0;0,1000;100,1000;100,0/10,10;90,10;90,390;10,390/10,510;90,510;90,890;10,890)");
tl::Extractor ex (s.c_str ());
ex.read (poly);
EXPECT_EQ (poly.to_string (), s);
}
TEST(24)
{
db::SimplePolygon poly;
std::string s ("(0,0;0,1000;100,1000;100,0)");
tl::Extractor ex (s.c_str ());
ex.read (poly);
EXPECT_EQ (poly.to_string (), s);
}
TEST(25)
{
db::DSimplePolygon poly;
std::string s ("(0,0;0,1000;100,1000;100,0)");
tl::Extractor ex (s.c_str ());
ex.read (poly);
EXPECT_EQ (poly.to_string (), s);
}
TEST(26)
{
db::DSimplePolygon poly;
std::string s ("(0,0;0,1000;100,1000;100,0)");
tl::Extractor ex (s.c_str ());
ex.read (poly);
tl::reuse_vector<db::DSimplePolygon> v;
for (int i = 0; i < 10; ++i) {
v.insert (poly);
}
EXPECT_EQ (v.begin ()->to_string (), s);
for (int i = 0; i < 9; ++i) {
v.erase (v.begin ());
}
EXPECT_EQ (v.begin ()->to_string (), s);
v.clear ();
}
TEST(27)
{
db::DPolygon poly;
std::string s ("(0,0;0,1000;100,1000;100,0)");
tl::Extractor ex (s.c_str ());
ex.read (poly);
tl::reuse_vector<db::DPolygon> v;
for (int i = 0; i < 10; ++i) {
v.insert (poly);
}
EXPECT_EQ (v.begin ()->to_string (), s);
for (int i = 0; i < 9; ++i) {
v.erase (v.begin ());
}
EXPECT_EQ (v.begin ()->to_string (), s);
v.clear ();
}
TEST(28)
{
// 32bit overflow for perimeter
db::Polygon b (db::Box (-1000000000, -1000000000, 1000000000, 1000000000));
EXPECT_EQ (b.perimeter (), 8000000000.0);
}