/* 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 ::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 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 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 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 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 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::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 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"); }