mirror of https://github.com/KLayout/klayout.git
1352 lines
43 KiB
C++
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);
|
|
}
|