klayout/src/db/unit_tests/dbEdgeTests.cc

605 lines
26 KiB
C++

/*
KLayout Layout Viewer
Copyright (C) 2006-2023 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 "dbEdge.h"
#include "tlUnitTest.h"
TEST(1)
{
db::Edge e (0, 0, 100, 200);
db::Edge ee;
db::Edge empty;
EXPECT_EQ (empty.is_degenerate (), true);
EXPECT_EQ (e.is_degenerate (), false);
EXPECT_EQ (empty, db::Edge (0, 0, 0, 0));
EXPECT_EQ (e, db::Edge (db::Point (0, 0), db::Point (100, 200)));
EXPECT_EQ (e.p1 (), db::Point (0, 0));
EXPECT_EQ (e.p2 (), db::Point (100, 200));
EXPECT_EQ (e.dx (), 100);
EXPECT_EQ (e.dy (), 200);
EXPECT_EQ (e.transformed (db::Trans (1, db::Vector (0, 0))).dx (), -200);
EXPECT_EQ (e.transformed (db::Trans (1, db::Vector (0, 0))).dx_abs (), db::Edge::distance_type (200));
EXPECT_EQ (e.transformed (db::Trans (1, db::Vector (0, -100))).dy_abs (), db::Edge::distance_type (100));
EXPECT_EQ (e.dy (), 200);
EXPECT_EQ (e != db::Edge (db::Point (0, 0), db::Point (100, 200)), false);
EXPECT_EQ (e == db::Edge (db::Point (0, 0), db::Point (100, 200)), true);
EXPECT_EQ (e.moved (db::Vector (10, 20)), db::Edge (db::Point (10, 20), db::Point (110, 220)));
EXPECT_EQ (e.enlarged (db::Vector (10, 20)), db::Edge (db::Point (-10, -20), db::Point (110, 220)));
EXPECT_EQ (e.length (), db::coord_traits <db::Coord>::rounded_distance (sqrt (double (100*100+200*200))));
EXPECT_EQ (e.sq_length (), 100*100+200*200);
EXPECT_EQ (e.ortho_length (), size_t (100+200));
EXPECT_EQ (e.to_string (), "(0,0;100,200)");
EXPECT_EQ (e.swapped_points ().to_string (), "(100,200;0,0)");
EXPECT_EQ (e.to_string (), "(0,0;100,200)");
EXPECT_EQ (e.transformed (db::Trans (1)).to_string (), "(0,0;-200,100)");
EXPECT_EQ (e.transformed (db::Trans (5)).to_string (), "(200,100;0,0)"); // mirroring transformations swap points
ee = e;
ee.transform (db::Trans (5));
EXPECT_EQ (ee.to_string (), "(200,100;0,0)");
EXPECT_EQ (e.swapped_points ().to_string (), "(100,200;0,0)");
e.swap_points ();
EXPECT_EQ (e.to_string (), "(100,200;0,0)");
e.set_p1 (db::Point (1, 2));
e.set_p2 (db::Point (11, 10));
EXPECT_EQ (e.to_string (), "(1,2;11,10)");
EXPECT_EQ (e.bbox ().to_string (), "(1,2;11,10)");
EXPECT_EQ (e.extended (2).to_string (), "(-1,1;13,11)");
EXPECT_EQ (e.extended (1).to_string (), "(0,1;12,11)");
EXPECT_EQ (e.shifted (2).to_string (), "(0,4;10,12)");
EXPECT_EQ (e.shifted (1).to_string (), "(0,3;10,11)");
ee = e;
ee.shift (2);
EXPECT_EQ (ee.to_string (), "(0,4;10,12)");
ee = e;
ee.extend (2);
EXPECT_EQ (ee.to_string (), "(-1,1;13,11)");
EXPECT_EQ (db::Edge ().extended (2).to_string (), "(-2,0;2,0)");
EXPECT_EQ (db::Edge ().shifted (2).to_string (), "(0,0;0,0)");
}
TEST(2)
{
db::Edge e (0, 0, 100, 200);
EXPECT_EQ (e.parallel (db::Edge (10,20,110,220)), true);
EXPECT_EQ (e.parallel (db::Edge (10,20,110,221)), false);
EXPECT_EQ (e.parallel (db::Edge (10,20,110,219)), false);
EXPECT_EQ (e.contains (db::Point (10,20)), true);
EXPECT_EQ (e.contains (db::Point (100,200)), true);
EXPECT_EQ (e.contains (db::Point (101,200)), false);
EXPECT_EQ (e.contains (db::Point (50,100)), true);
EXPECT_EQ (e.contains (db::Point (200,400)), false);
EXPECT_EQ (e.contains (db::Point (-200,-400)), false);
EXPECT_EQ (e.contains (db::Point (0,0)), true);
EXPECT_EQ (db::Edge (10,20,110,230).distance (db::Point (100, 200)), -4);
EXPECT_EQ (db::Edge (10,20,110,230).distance_abs (db::Point (100, 200)), db::Edge::distance_type (4));
EXPECT_EQ (db::Edge (10,20,110,210).distance (db::Point (100, 200)), 4);
EXPECT_EQ (db::Edge (10,20,110,222).distance (db::Point (100, 200)), -1);
EXPECT_EQ (db::Edge (10,20,110,222).distance_abs (db::Point (100, 200)), db::Edge::distance_type (1));
EXPECT_EQ (db::Edge (10,20,110,222).contains (db::Point (0, 0)), false);
EXPECT_EQ (db::Edge (10,20,110,222).contains (db::Point (100, 200)), false);
EXPECT_EQ (db::Edge (10,20,110,20).euclidian_distance (db::Point (100, 120)), 100u);
EXPECT_EQ (db::Edge (10,20,110,20).euclidian_distance (db::Point (100, -80)), 100u);
EXPECT_EQ (db::Edge (10,20,110,20).euclidian_distance (db::Point (-90, 120)), 141u);
EXPECT_EQ (db::Edge (10,20,110,20).euclidian_distance (db::Point (-90, -80)), 141u);
EXPECT_EQ (db::Edge (10,20,110,20).euclidian_distance (db::Point (210, 120)), 141u);
EXPECT_EQ (db::Edge (10,20,110,20).euclidian_distance (db::Point (210, -80)), 141u);
EXPECT_EQ (db::Edge (10,20,110,20).euclidian_distance (db::Point (-90, 20)), 100u);
EXPECT_EQ (db::Edge (10,20,110,20).euclidian_distance (db::Point (10, 20)), 0u);
EXPECT_EQ (db::Edge (10,20,110,20).euclidian_distance (db::Point (50, 20)), 0u);
EXPECT_EQ (db::Edge (10,20,110,20).euclidian_distance (db::Point (110, 20)), 0u);
}
TEST(3)
{
db::Edge e (0, 0, 100, 200);
db::Edge empty;
EXPECT_EQ (e.coincident (db::Edge (10,20,110,220)), true);
EXPECT_EQ (e.coincident (db::Edge (10,20,110,222)), false);
EXPECT_EQ (e.coincident (db::Edge (10,20,110,218)), false);
EXPECT_EQ (e.coincident (db::Edge (110,220,220,440)), false);
EXPECT_EQ (e.coincident (db::Edge (-110,-220,-220,-440)), false);
EXPECT_EQ (e.coincident (db::Edge (100,200,100,400)), false);
EXPECT_EQ (e.coincident (db::Edge (-100,-200,10,20)), true);
EXPECT_EQ (e.coincident (db::Edge (-100,-200,0,0)), false);
}
TEST(4)
{
db::Edge e (0, 0, 100, 200);
EXPECT_EQ (e.intersect (db::Edge (10,20,110,220)), true);
EXPECT_EQ (e.intersect (db::Edge (10,-20,-110,220)), true);
EXPECT_EQ (e.intersect (db::Edge (8,-20,-110,220)), false);
EXPECT_EQ (e.intersect (db::Edge (20,0,-80,200)), true);
EXPECT_EQ (e.intersect (db::Edge (20,10,-80,200)), true);
EXPECT_EQ (e.intersect (db::Edge (10,20,-80,200)), true);
EXPECT_EQ (e.intersect (db::Edge (8,20,-80,200)), false);
EXPECT_EQ (e.intersect_point (db::Edge (10,20,110,220)).first, true);
EXPECT_EQ (e.intersect_point (db::Edge (10,-20,-110,220)).first, true);
EXPECT_EQ (e.intersect_point (db::Edge (8,-20,-110,220)).first, false);
EXPECT_EQ (e.intersect_point (db::Edge (20,0,-80,200)).first, true);
EXPECT_EQ (e.intersect_point (db::Edge (20,10,-80,200)).first, true);
EXPECT_EQ (e.intersect_point (db::Edge (10,20,-80,200)).first, true);
EXPECT_EQ (e.intersect_point (db::Edge (8,20,-80,200)).first, false);
EXPECT_EQ (e.intersect_point (db::Edge (10,20,110,220)).first, true);
EXPECT_EQ (e.intersect_point (db::Edge (10,20,110,220)).second, db::Point (10, 20));
EXPECT_EQ (e.intersect_point (db::Edge (10,-20,-110,220)).second, db::Point (0, 0));
EXPECT_EQ (e.intersect_point (db::Edge (20,0,-80,200)).second, db::Point (10, 20));
EXPECT_EQ (e.intersect_point (db::Edge (20,10,-80,200)).second, db::Point (12, 25));
EXPECT_EQ (e.intersect_point (db::Edge (10,20,-80,200)).second, db::Point (10, 20));
}
TEST(4a)
{
db::Edge e1 (db::Point (-134, 3629), db::Point (-130, 3649));
db::Edge e2 (db::Point (-129, 3710), db::Point (-134, 3631));
EXPECT_EQ (e1.cut_point (e2).second, db::Point (-134, 3628));
EXPECT_EQ (e1.cut_point (e2).first, true);
EXPECT_EQ (e1.intersect_point (e2).first, false);
}
TEST(4b)
{
db::Edge e1 (db::Point (-133, 3629), db::Point (-129, 3649));
db::Edge e2 (db::Point (-129, 3710), db::Point (-134, 3631));
EXPECT_EQ (e1.cut_point (e2).second, db::Point (-135, 3621));
EXPECT_EQ (e1.cut_point (e2).first, true);
EXPECT_EQ (e1.intersect_point (e2).first, false);
}
TEST(4c)
{
db::Edge e1 (db::Point (-135, 3629), db::Point (-129, 3649));
db::Edge e2 (db::Point (-129, 3710), db::Point (-134, 3631));
EXPECT_EQ (e1.cut_point (e2).second, db::Point (-134, 3633));
EXPECT_EQ (e1.cut_point (e2).first, true);
EXPECT_EQ (e1.intersect_point (e2).second, db::Point (-134, 3633));
EXPECT_EQ (e1.intersect_point (e2).first, true);
}
TEST(4d)
{
db::Edge e1 (db::Point (-100, 1000), db::Point (100, 1000));
db::Edge e2 (db::Point (101, 1000), db::Point (200, 1000));
db::Edge e3 (db::Point (100, 1000), db::Point (200, 1000));
db::Edge e4 (db::Point (50, 1000), db::Point (200, 1000));
db::Edge e5 (db::Point (-150, 1000), db::Point (50, 1000));
db::Edge e6 (db::Point (-150, 1000), db::Point (200, 1000));
EXPECT_EQ (e1.intersect (e2), false);
EXPECT_EQ (e1.intersect (e3), true);
EXPECT_EQ (e1.intersect_point (e2).first, false);
EXPECT_EQ (e1.intersect_point (e3).second, db::Point (100, 1000));
EXPECT_EQ (e1.intersect_point (e3).first, true);
EXPECT_EQ (e1.intersect_point (e4).second, db::Point (50, 1000));
EXPECT_EQ (e1.intersect_point (e4).first, true);
EXPECT_EQ (e1.intersect_point (e5).second, db::Point (-100, 1000));
EXPECT_EQ (e1.intersect_point (e5).first, true);
EXPECT_EQ (e1.intersect_point (e6).second, db::Point (-100, 1000));
EXPECT_EQ (e1.intersect_point (e6).first, true);
}
TEST(5)
{
db::Edge e (0, 0, 1000000, 2000000);
EXPECT_EQ (e.intersect (db::Edge (100000,200000,1100000,2200000)), true);
EXPECT_EQ (e.intersect (db::Edge (100000,-200000,-1100000,2200000)), true);
EXPECT_EQ (e.intersect (db::Edge (80000,-200000,-1100000,2200000)), false);
EXPECT_EQ (e.intersect (db::Edge (200000,0,-800000,2000000)), true);
EXPECT_EQ (e.intersect (db::Edge (200000,100000,-800000,2000000)), true);
EXPECT_EQ (e.intersect (db::Edge (100000,200000,-800000,2000000)), true);
EXPECT_EQ (e.intersect (db::Edge (80000,200000,-800000,2000000)), false);
EXPECT_EQ (e.intersect_point (db::Edge (100000,200000,1100000,2200000)).first, true);
EXPECT_EQ (e.intersect_point (db::Edge (100000,-200000,-1100000,2200000)).first, true);
EXPECT_EQ (e.intersect_point (db::Edge (80000,-200000,-1100000,2200000)).first, false);
EXPECT_EQ (e.intersect_point (db::Edge (200000,0,-800000,2000000)).first, true);
EXPECT_EQ (e.intersect_point (db::Edge (200000,100000,-800000,2000000)).first, true);
EXPECT_EQ (e.intersect_point (db::Edge (100000,200000,-800000,2000000)).first, true);
EXPECT_EQ (e.intersect_point (db::Edge (80000,200000,-800000,2000000)).first, false);
EXPECT_EQ (e.intersect_point (db::Edge (100000,200000,1100000,2200000)).first, true);
EXPECT_EQ (e.intersect_point (db::Edge (100000,200000,1100000,2200000)).second, db::Point (100000,200000));
EXPECT_EQ (e.intersect_point (db::Edge (100000,-200000,-1100000,2200000)).second, db::Point (0, 0));
EXPECT_EQ (e.intersect_point (db::Edge (200000,0,-800000,2000000)).second, db::Point (100000, 200000));
EXPECT_EQ (e.intersect_point (db::Edge (200000,100000,-800000,2000000)).second, db::Point (123077,246154));
EXPECT_EQ (e.intersect_point (db::Edge (100000,200000,-800000,2000000)).second, db::Point (100000, 200000));
}
TEST(6)
{
db::Edge e (0, 0, 1000, 2000);
std::pair<bool, db::Point> ret;
ret = e.projected (db::Point (-1000, 0));
EXPECT_EQ (ret.first, false);
ret = e.projected (db::Point (-1000, 500));
EXPECT_EQ (ret.first, true);
EXPECT_EQ (ret.second, db::Point (0, 0));
ret = e.projected (db::Point (-1000, 700));
EXPECT_EQ (ret.first, true);
EXPECT_EQ (ret.second, db::Point (80, 160));
}
TEST(7)
{
db::Edge e1 (100, 200, 1000, 2000);
db::Edge e2 (100, 200, 1000, 2000);
db::Edge e3 (101, 200, 1001, 2000);
db::Edge e4 (-200, 100, -2000, 1000);
std::pair<bool, db::Point> ret;
ret = e1.cut_point (e2);
EXPECT_EQ (ret.first, false);
ret = e1.cut_point (e3);
EXPECT_EQ (ret.first, false);
ret = e1.cut_point (e4);
EXPECT_EQ (ret.first, true);
EXPECT_EQ (ret.second, db::Point (0, 0));
}
TEST (8)
{
db::DEdge e1 (-10.0, 0.0, 10.0, 0.0);
db::DEdge e2 (-sqrt(2.0), -1.0, 2.0 - sqrt(2.0), 1.0);
db::DEdge e3 (0.0, -100.0, 0.0, 10.0);
db::DEdge e4 (-sqrt(2.0), 1.0, 2.0 - sqrt(2.0), -1.0);
std::pair <bool, db::DPoint> i;
db::Point ii;
i = e1.intersect_point (e2);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e2.intersect_point (e1);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e3.intersect_point (e2);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e2.intersect_point (e3);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e1.intersect_point (e4);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e4.intersect_point (e1);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e3.intersect_point (e4);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e4.intersect_point (e3);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
}
TEST (9)
{
db::DEdge e1 (10.0, 0.0, -10.0, 0.0);
db::DEdge e2 (-sqrt(2.0), -1.0, 2.0 - sqrt(2.0), 1.0);
db::DEdge e3 (0.0, 10.0, 0.0, -10.0);
db::DEdge e4 (-sqrt(2.0), 1.0, 2.0 - sqrt(2.0), -1.0);
std::pair <bool, db::DPoint> i;
db::Point ii;
i = e1.intersect_point (e2);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e2.intersect_point (e1);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e3.intersect_point (e2);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e2.intersect_point (e3);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e1.intersect_point (e4);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e4.intersect_point (e1);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e3.intersect_point (e4);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
i = e4.intersect_point (e3);
EXPECT_EQ (i.first, true);
ii = db::Point (i.second);
EXPECT_EQ (ii, db::Point (0, 0));
}
TEST(10)
{
db::Edge b (db::Point (10, 20), db::Point (45, 60));
db::Edge bc (db::Point (0, 1), db::Point (2, 3));
std::string s (b.to_string ());
EXPECT_EQ (s, "(10,20;45,60)");
tl::Extractor ex (s.c_str ());
ex.read (bc);
EXPECT_EQ (bc.to_string (), s);
}
TEST(11)
{
db::DEdge b (db::DPoint (10, 20), db::DPoint (45, 60));
db::DEdge bc (db::DPoint (0, 1), db::DPoint (2, 3));
std::string s (b.to_string ());
EXPECT_EQ (s, "(10,20;45,60)");
tl::Extractor ex (s.c_str ());
ex.read (bc);
EXPECT_EQ (bc.to_string (), s);
}
TEST(12)
{
db::Edge a (db::DPoint (368, 726), db::DPoint (363, 734));
db::Edge b (db::DPoint (353, 733), db::DPoint (375, 733));
std::string s;
s = a.intersect_point (b).second.to_string ();
EXPECT_EQ (s, "364,733");
s = b.intersect_point (a).second.to_string ();
EXPECT_EQ (s, "364,733");
a.swap_points ();
s = a.intersect_point (b).second.to_string ();
EXPECT_EQ (s, "364,733");
s = b.intersect_point (a).second.to_string ();
EXPECT_EQ (s, "364,733");
a.swap_points ();
b.swap_points ();
s = a.intersect_point (b).second.to_string ();
EXPECT_EQ (s, "364,733");
s = b.intersect_point (a).second.to_string ();
EXPECT_EQ (s, "364,733");
a.swap_points ();
s = a.intersect_point (b).second.to_string ();
EXPECT_EQ (s, "364,733");
s = b.intersect_point (a).second.to_string ();
EXPECT_EQ (s, "364,733");
}
TEST(13)
{
std::pair<bool, db::Edge> cl;
cl = db::Edge (db::Point (0, 0), db::Point (100, 0)).clipped(db::Box (db::Point (50, -20), db::Point (60, 20)));
EXPECT_EQ (cl.first, true);
EXPECT_EQ (cl.second.to_string (), "(50,0;60,0)");
cl = db::Edge (db::Point (0, 0), db::Point (100, 0)).clipped(db::Box (db::Point (50, 0), db::Point (60, 20)));
EXPECT_EQ (cl.first, true);
EXPECT_EQ (cl.second.to_string (), "(50,0;60,0)");
cl = db::Edge (db::Point (0, 0), db::Point (100, 0)).clipped(db::Box (db::Point (50, 10), db::Point (60, 20)));
EXPECT_EQ (cl.first, false);
cl = db::Edge (db::Point (0, 0), db::Point (100, 0)).clipped(db::Box (db::Point (100, 0), db::Point (160, 20)));
EXPECT_EQ (cl.first, true);
EXPECT_EQ (cl.second.to_string (), "(100,0;100,0)");
cl = db::Edge (db::Point (0, 0), db::Point (100, 0)).clipped(db::Box (db::Point (80, 0), db::Point (160, 20)));
EXPECT_EQ (cl.first, true);
EXPECT_EQ (cl.second.to_string (), "(80,0;100,0)");
cl = db::Edge (db::Point (0, 0), db::Point (100, 0)).clipped(db::Box (db::Point (-100, 0), db::Point (0, 20)));
EXPECT_EQ (cl.first, true);
EXPECT_EQ (cl.second.to_string (), "(0,0;0,0)");
cl = db::Edge (db::Point (0, 0), db::Point (100, 0)).clipped(db::Box (db::Point (-100, 0), db::Point (20, 20)));
EXPECT_EQ (cl.first, true);
EXPECT_EQ (cl.second.to_string (), "(0,0;20,0)");
cl = db::Edge (db::Point (0, 0), db::Point (0, 0)).clipped(db::Box (db::Point (-100, 0), db::Point (20, 20)));
EXPECT_EQ (cl.first, true);
EXPECT_EQ (cl.second.to_string (), "(0,0;0,0)");
cl = db::Edge (db::Point (0, 0), db::Point (0, 0)).clipped(db::Box (db::Point (-100, 0), db::Point (0, 20)));
EXPECT_EQ (cl.first, true);
EXPECT_EQ (cl.second.to_string (), "(0,0;0,0)");
cl = db::Edge (db::Point (851, 98), db::Point (343, 466)).clipped(db::Box (db::Point (48, 134), db::Point (555, 438)));
EXPECT_EQ (cl.first, true);
EXPECT_EQ (cl.second.to_string (), "(555,312;382,438)");
cl = db::Edge (db::Point (4, 0), db::Point (9, 2)).clipped(db::Box (db::Point (1, 2), db::Point (8, 6)));
EXPECT_EQ (cl.first, true);
// Not nice but correct if you imagine that clipping "attracts" an edge:
EXPECT_EQ (cl.second.to_string (), "(8,2;8,2)");
// It's important the both edges are connected:
EXPECT_EQ (db::Edge (db::Point (0, 100), db::Point (600, 500)).clipped (db::Box (db::Point (100, 200), db::Point (200, 300))).second.to_string (), "(150,200;200,233)");
EXPECT_EQ (db::Edge (db::Point (0, 100), db::Point (600, 500)).clipped (db::Box (db::Point (200, 200), db::Point (300, 300))).second.to_string (), "(200,233;300,300)");
}
TEST(14)
{
db::Edge e = db::Edge (db::Point (0, 0), db::Point (100, 0));
EXPECT_EQ (e.coincident (db::Edge (db::Point (0, 0), db::Point (100, 0))), true);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (100, 0))), true);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (200, 0))), true);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (0, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (1, 0))), true);
EXPECT_EQ (e.coincident (db::Edge (db::Point (100, 0), db::Point (200, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (99, 0), db::Point (200, 0))), true);
EXPECT_EQ (e.coincident (db::Edge (db::Point (99, 0), db::Point (99, 0))), false);
e = db::Edge (db::Point (100, 0), db::Point (0, 0));
EXPECT_EQ (e.coincident (db::Edge (db::Point (0, 0), db::Point (100, 0))), true);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (100, 0))), true);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (200, 0))), true);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (0, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (1, 0))), true);
EXPECT_EQ (e.coincident (db::Edge (db::Point (100, 0), db::Point (200, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (99, 0), db::Point (200, 0))), true);
EXPECT_EQ (e.coincident (db::Edge (db::Point (99, 0), db::Point (99, 0))), false);
e = db::Edge (db::Point (100, 1), db::Point (0, 1));
EXPECT_EQ (e.coincident (db::Edge (db::Point (0, 0), db::Point (100, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (100, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (200, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (0, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (1, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (100, 0), db::Point (200, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (99, 0), db::Point (200, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (99, 0), db::Point (99, 0))), false);
e = db::Edge (db::Point (100, -1), db::Point (0, 1));
EXPECT_EQ (e.coincident (db::Edge (db::Point (0, 0), db::Point (100, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (100, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (200, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (0, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (1, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (100, 0), db::Point (200, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (99, 0), db::Point (200, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (99, 0), db::Point (99, 0))), false);
e = db::Edge (db::Point (50, 0), db::Point (50, 0));
EXPECT_EQ (e.coincident (db::Edge (db::Point (0, 0), db::Point (100, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (100, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (200, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (0, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (-100, 0), db::Point (1, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (50, 0), db::Point (50, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (100, 0), db::Point (200, 0))), false);
EXPECT_EQ (e.coincident (db::Edge (db::Point (49, 0), db::Point (200, 0))), false);
}
// exact rounding behaviour
TEST(15)
{
typedef db::coord_traits<db::Coord>::area_type area_type;
// div_exact(a, b, d) computes a*b/d with exact rounding behaviour
EXPECT_EQ (db::div_exact (area_type (0), area_type (22), area_type (176)), 0);
EXPECT_EQ (db::div_exact (area_type (5), area_type (0), area_type (176)), 0);
EXPECT_EQ (db::div_exact (area_type (3), area_type (22), area_type (176)), 0);
EXPECT_EQ (db::div_exact (area_type (4), area_type (22), area_type (176)), 0);
EXPECT_EQ (db::div_exact (area_type (5), area_type (22), area_type (176)), 1);
EXPECT_EQ (db::div_exact (area_type (7), area_type (22), area_type (176)), 1);
EXPECT_EQ (db::div_exact (area_type (8), area_type (22), area_type (176)), 1);
EXPECT_EQ (db::div_exact (area_type (12), area_type (22), area_type (176)), 1);
EXPECT_EQ (db::div_exact (area_type (13), area_type (22), area_type (176)), 2);
EXPECT_EQ (db::div_exact (area_type (3 * 11), area_type (2), area_type (176)), 0);
EXPECT_EQ (db::div_exact (area_type (4 * 11), area_type (2), area_type (176)), 0);
EXPECT_EQ (db::div_exact (area_type (5 * 11), area_type (2), area_type (176)), 1);
EXPECT_EQ (db::div_exact (area_type (7 * 11), area_type (2), area_type (176)), 1);
EXPECT_EQ (db::div_exact (area_type (8 * 11), area_type (2), area_type (176)), 1);
EXPECT_EQ (db::div_exact (area_type (12 * 11), area_type (2), area_type (176)), 1);
EXPECT_EQ (db::div_exact (area_type (13 * 11), area_type (2), area_type (176)), 2);
EXPECT_EQ (db::div_exact (area_type (-3), area_type (22), area_type (176)), 0);
EXPECT_EQ (db::div_exact (area_type (-4), area_type (22), area_type (176)), -1);
EXPECT_EQ (db::div_exact (area_type (-5), area_type (22), area_type (176)), -1);
EXPECT_EQ (db::div_exact (area_type (-7), area_type (22), area_type (176)), -1);
EXPECT_EQ (db::div_exact (area_type (-8), area_type (22), area_type (176)), -1);
EXPECT_EQ (db::div_exact (area_type (-12), area_type (22), area_type (176)), -2);
EXPECT_EQ (db::div_exact (area_type (-13), area_type (22), area_type (176)), -2);
EXPECT_EQ (db::div_exact (area_type (-3 * 11), area_type (2), area_type (176)), 0);
EXPECT_EQ (db::div_exact (area_type (-4 * 11), area_type (2), area_type (176)), -1);
EXPECT_EQ (db::div_exact (area_type (-5 * 11), area_type (2), area_type (176)), -1);
EXPECT_EQ (db::div_exact (area_type (-7 * 11), area_type (2), area_type (176)), -1);
EXPECT_EQ (db::div_exact (area_type (-8 * 11), area_type (2), area_type (176)), -1);
EXPECT_EQ (db::div_exact (area_type (-12 * 11), area_type (2), area_type (176)), -2);
EXPECT_EQ (db::div_exact (area_type (-13 * 11), area_type (2), area_type (176)), -2);
area_type f = 790014345;
EXPECT_EQ (db::div_exact (area_type (4), area_type (22) * f, area_type (176) * f), 0);
EXPECT_EQ (db::div_exact (area_type (5), area_type (22) * f, area_type (176) * f), 1);
EXPECT_EQ (db::div_exact (area_type (8), area_type (22) * f, area_type (176) * f), 1);
EXPECT_EQ (db::div_exact (area_type (-3), area_type (22) * f, area_type (176) * f), 0);
EXPECT_EQ (db::div_exact (area_type (-4), area_type (22) * f, area_type (176) * f), -1);
EXPECT_EQ (db::div_exact (area_type (-5), area_type (22) * f, area_type (176) * f), -1);
EXPECT_EQ (db::div_exact (area_type (-8), area_type (22) * f, area_type (176) * f), -1);
EXPECT_EQ (db::div_exact (area_type (4) * 100000000, area_type (22) * f, area_type (176) * f), 50000000);
EXPECT_EQ (db::div_exact (area_type (5) * 100000000, area_type (22) * f, area_type (176) * f), 62500000);
EXPECT_EQ (db::div_exact (area_type (-4) * 100000000, area_type (22) * f, area_type (176) * f), -50000000);
EXPECT_EQ (db::div_exact (area_type (-5) * 100000000, area_type (22) * f, area_type (176) * f), -62500000);
EXPECT_EQ (db::div_exact (1000000004, area_type (22) * f, area_type (176) * f), 125000000);
EXPECT_EQ (db::div_exact (1000000005, area_type (22) * f, area_type (176) * f), 125000001);
EXPECT_EQ (db::div_exact (-1000000003, area_type (22) * f, area_type (176) * f), -125000000);
EXPECT_EQ (db::div_exact (-1000000004, area_type (22) * f, area_type (176) * f), -125000001);
EXPECT_EQ (db::div_exact (-1000000005, area_type (22) * f, area_type (176) * f), -125000001);
db::Edge e1 (db::Point (3, -3), db::Point (-8, -1));
db::Edge e2 (db::Point (-4, -2), db::Point (13, -4));
std::pair<bool, db::Point> ip;
ip = e1.intersect_point (e2);
EXPECT_EQ (ip.second.to_string ().c_str (), "0,-3");
ip = e2.intersect_point (e1);
EXPECT_EQ (ip.second.to_string ().c_str (), "0,-3");
}