summaryrefslogtreecommitdiffstats
path: root/src/cython/test-primitives.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/cython/test-primitives.py288
1 files changed, 288 insertions, 0 deletions
diff --git a/src/cython/test-primitives.py b/src/cython/test-primitives.py
new file mode 100644
index 0000000..0edf218
--- /dev/null
+++ b/src/cython/test-primitives.py
@@ -0,0 +1,288 @@
+import unittest
+from math import pi, sqrt
+
+import cy2geom
+from cy2geom import Angle, AngleInterval, Point, IntPoint, Line, Ray
+from cy2geom import LineSegment, Curve
+
+class TestPrimitives(unittest.TestCase):
+
+ def test_angle(self):
+ self.assertAlmostEqual(Angle.rad_from_deg(45), pi/4)
+ self.assertAlmostEqual(Angle.deg_from_rad(pi/6), 30)
+
+ p = Point(1, sqrt(3))
+ alpha = Angle.from_Point(p)
+ self.assertAlmostEqual(alpha.degrees(), 60)
+
+ beta = Angle.from_radians(pi/5)
+ gamma = Angle.from_degrees(36)
+ self.assertAlmostEqual(beta.radians0(), gamma.radians0())
+ self.assertTrue(beta==gamma)
+ omega = Angle.from_degrees_clock(0)
+ self.assertAlmostEqual(omega.radians(), pi/2)
+
+ delta = Angle(-pi * 0.5)
+ self.assertAlmostEqual(delta.degrees(), -90)
+ self.assertAlmostEqual(delta.radians0(), 1.5*pi)
+ #degreesClock roughly means [ 90 - Angle.degrees() ] mod 360
+ self.assertAlmostEqual(delta.degrees_clock(), 180)
+
+ self.assertAlmostEqual(
+ (beta + gamma).radians(),
+ beta.radians()+gamma.radians() )
+ self.assertAlmostEqual( (beta - gamma).degrees(), 0)
+
+ def test_angleInterval(self):
+ A = AngleInterval(Angle(pi/6), Angle(pi/4))
+ B = AngleInterval( 0, pi/4, cw = True )
+ self.assertEqual(A(0), Angle(pi/6))
+ self.assertEqual(A(0.5), A.angle_at(0.5))
+ self.assertEqual(A(0), A.initial_angle())
+ self.assertEqual(B(1), B.final_angle())
+ self.assertFalse(B.is_degenerate())
+ self.assertTrue(B.contains(Angle(pi/6)))
+ self.assertTrue(A.contains(Angle(pi)))
+
+ self.assertAlmostEqual( B.extent(), pi/4 )
+ def test_point(self):
+ p = Point(3, 4)
+ q = Point(8, 16)
+ p_inf = Point(float('inf'), 1)
+ #y axis points downwards
+ p_ccw = Point(4, -3)
+
+ self.assertAlmostEqual(p.length(), 5)
+ self.assertAlmostEqual(p.ccw(), p_ccw)
+ self.assertAlmostEqual(p_ccw.cw(), p)
+ self.assertAlmostEqual(p[0], 3)
+ self.assertAlmostEqual(p[1], 4)
+
+ self.assertFalse(p_inf.isFinite())
+ self.assertTrue(p.isFinite())
+ self.assertFalse(p.isNormalized())
+ self.assertTrue((p/p.length()).isNormalized())
+ self.assertFalse(p.isZero())
+ self.assertTrue((p*0).isZero())
+
+ self.assertTrue( (p + p.ccw().ccw()).isZero)
+ self.assertAlmostEqual( (q-p).length(), 13)
+
+ self.assertGreater(q, p)
+ self.assertGreaterEqual(q, p)
+ self.assertEqual(p, p)
+ self.assertNotEqual(p, q)
+ self.assertLess( Point(1, 1), Point(1, 2) )
+ self.assertLessEqual(p, p)
+
+ self.assertTrue( Point.are_near(
+ Point.polar(pi/4, sqrt(2)),
+ Point(1, 1) ))
+ self.assertAlmostEqual(sqrt(2), Point.L2(Point(1, 1)))
+ self.assertAlmostEqual(2, Point.L2sq(Point(1, 1)))
+ self.assertAlmostEqual( Point.middle_point(Point(), q), q/2 )
+ self.assertAlmostEqual( Point.rot90(p), p.cw() )
+ self.assertAlmostEqual(
+ Point.lerp(0.2, Point(), Point(3,4)).length(),
+ 1)
+ self.assertAlmostEqual(Point.dot(p, p_ccw), 0)
+ self.assertAlmostEqual(Point.dot(p, p_inf), float('inf'))
+ self.assertAlmostEqual(Point.dot(p, q), 88)
+ #TODO this might be implemented incorrectly in lib2geom!
+ self.assertAlmostEqual(Point.cross(p, q), -16)
+
+ self.assertAlmostEqual(Point.distance(p, q), 13)
+ self.assertAlmostEqual(Point.distanceSq(p, p_ccw), 50)
+ self.assertAlmostEqual(Point.unit_vector(p), p/5)
+
+ self.assertAlmostEqual(Point.L1(p), 7)
+ self.assertAlmostEqual(Point.L1(p_inf), float('inf'))
+ self.assertAlmostEqual(Point.LInfty(q), 16)
+ self.assertAlmostEqual(Point.LInfty(p_inf), float('inf'))
+
+ self.assertTrue(Point.is_zero(Point()))
+ self.assertFalse(Point.is_zero(p))
+ self.assertTrue(Point.is_unit_vector(p/5))
+ self.assertFalse(Point.is_unit_vector(q))
+
+ self.assertAlmostEqual(Point.atan2(Point(1, 1)), pi/4)
+ self.assertAlmostEqual(Point.angle_between(p, p_ccw), -pi/2)
+ self.assertAlmostEqual(Point.abs(-p), p)
+ #TODO I have no idea what should this function do
+ # self.assertAlmostEqual(
+ # Point.constrain_angle(Point(1, 0), Point(0, 1), 1, Point(sqrt(2)/2, sqrt(2)/2)),
+ #
+ # ))
+
+ def test_intPoint(self):
+ p = Point(4.89, 3.21)
+ self.assertEqual(p.round(), IntPoint(5, 3))
+ self.assertEqual(p.floor(), IntPoint(4, 3))
+ self.assertEqual(p.ceil(), IntPoint(5, 4))
+
+ self.assertEqual(p.ceil().x, 5)
+ self.assertEqual(p.floor().y, 3)
+ self.assertEqual(IntPoint(), p.floor()-p.floor())
+
+ a = IntPoint(2, -5)
+ b = IntPoint(5, 3)
+ self.assertEqual(IntPoint(7, -2), a+b)
+ self.assertEqual(IntPoint(3, 8), b-a)
+ self.assertGreater(b, a)
+ self.assertGreaterEqual(b, b)
+ self.assertNotEqual(a, b)
+
+ def test_line(self):
+
+ l = Line(Point(), pi/4)
+ self.assertAlmostEqual( l.origin(), Point() )
+ self.assertAlmostEqual( l.versor(), Point(1, 1)/sqrt(2) )
+ self.assertAlmostEqual( l.angle(), pi/4 )
+
+ k = Line.from_points(Point(), Point(2, 1))
+ self.assertFalse(k.is_degenerate())
+ self.assertFalse(Line().is_degenerate())
+ self.assertAlmostEqual( l.point_at(sqrt(2)), Point(1,1) )
+ self.assertAlmostEqual(
+ k.point_at(43),
+ Point(k.value_at(43, 0), k.value_at(43, 1)))
+ self.assertAlmostEqual(k.time_at(Point(4, 2)), sqrt(20))
+ self.assertAlmostEqual(
+ k.time_at_projection(Point(4, 2) + Point(2, -4)),
+ sqrt(20))
+ self.assertAlmostEqual(
+ k.point_at(k.nearest_time(Point(4, 2) + Point(2, -4))),
+ Point(4,2))
+ self.assertAlmostEqual(
+ k.time_at_projection(Point(3, 3)),
+ -k.reverse().time_at_projection(Point(3, 3)))
+ self.assertAlmostEqual( k.derivative().origin(), k.versor())
+ self.assertAlmostEqual(k.normal(), k.versor().cw())
+
+ roots = k.roots( 3, 0 )
+ for root in roots:
+ self.assertAlmostEqual( k.value_at(root, 0), 3)
+
+ self.assertAlmostEqual(l.normal(), l.normal_and_dist()[0])
+ self.assertAlmostEqual(Line.distance(Point(), l), l.normal_and_dist()[1])
+
+ self.assertAlmostEqual(Line.distance(Point(-1, 1), l), sqrt(2))
+ self.assertTrue(Line.are_near(Point(0), l))
+ self.assertFalse(Line.are_near(Point(1, 1), k))
+ self.assertTrue(Line.are_near(Point(1, 1), k, 2))
+
+ p = Line(Point(1, 1))
+ p_orto = Line(Point(2, 3), pi/2)
+ p_para = Line(Point(2, 3))
+ p_same = Line.from_points(Point(1, 1), Point(5, 1))
+
+ self.assertTrue(Line.are_orthogonal(p, p_orto))
+ self.assertFalse(Line.are_orthogonal(p, p_para))
+ self.assertTrue(Line.are_parallel(p, p_para))
+ self.assertFalse(Line.are_parallel(p, p_orto))
+ self.assertTrue(Line.are_same(p, p_same))
+ self.assertFalse(Line.are_same(p, p_para))
+
+ self.assertTrue(Line.are_collinear(
+ Point(1,1),
+ Point(2, 3),
+ Point(4, 7)))
+ self.assertAlmostEqual(Line.angle_between(p, p_orto), pi/2)
+
+ m = Line.from_normal_distance(Point(1, -1), 1)
+ self.assertAlmostEqual(m.angle(), pi/4)
+
+ m = Line.from_LineSegment( LineSegment( Point(2, 2), Point(4, 4) ) )
+ self.assertAlmostEqual(m.angle(), pi/4)
+
+ m = Line.from_Ray( Ray(Point(2, 3), 0.2) )
+ self.assertAlmostEqual(m.angle(), 0.2)
+ self.assertAlmostEqual(m.origin(), Point(2, 3))
+
+ self.assertIsInstance(m.portion(2, 4), Curve)
+ self.assertAlmostEqual(m.portion(2, 4)(0), m.point_at(2))
+
+ self.assertIsInstance(m.segment(1, 5), LineSegment)
+ self.assertAlmostEqual(m.segment(1, 5)(1), m.point_at(5))
+
+ self.assertAlmostEqual(m.ray(4).origin(), m.point_at(4))
+
+ m.set_origin(Point())
+ self.assertAlmostEqual(m.origin(), Point())
+
+ m.set_angle(0.2)
+ self.assertAlmostEqual(m.angle(), 0.2)
+
+ m.set_versor(Point())
+ self.assertTrue(m.is_degenerate())
+
+ m.set_points(Point(2, 9), Point(1, 8))
+ self.assertAlmostEqual(m.versor(), Point.unit_vector(Point(1, 8) - Point(2, 9)))
+
+ def test_ray(self):
+ r = Ray(Point(1,1), pi/4)
+ self.assertAlmostEqual(r.origin(), Point(1, 1))
+ self.assertAlmostEqual(r.versor(), Point(1, 1)/sqrt(2))
+ self.assertAlmostEqual(r.angle(), pi/4)
+
+ r.set_origin(Point(4, 3))
+ #TODO this should maybe normalize the versor!
+ r.set_versor(Point(1, -1)/sqrt(2))
+ self.assertAlmostEqual(r.origin(), Point(4, 3))
+ self.assertAlmostEqual(r.versor(), Point(1, -1)/sqrt(2))
+ self.assertAlmostEqual(r.angle(), -pi/4)
+
+ r.set_points(Point(1, 1), Point(1, 3))
+ self.assertFalse(r.is_degenerate())
+ self.assertFalse(Ray().is_degenerate())
+ self.assertAlmostEqual(r.point_at(4), Point(1, 5))
+
+ #TODO I think this should be expected behaviour
+# self.assertAlmostEqual(
+# r.pointAt(-3),
+# Point(1, 1)))
+ self.assertAlmostEqual(r.value_at(4, 0), 1)
+ self.assertAlmostEqual(r.value_at(4, 1), 5)
+
+ roots = r.roots( 3, 1 )
+ for root in roots:
+ self.assertAlmostEqual( r.value_at(root, 1), 3)
+
+ self.assertAlmostEqual(
+ r.point_at(3) - r.origin(),
+ r.origin()-r.reverse().point_at(3))
+
+ self.assertAlmostEqual(Ray.distance(Point(), r), sqrt(2))
+ self.assertAlmostEqual(Ray.distance(Point()+r.versor(), r), 1)
+
+ self.assertTrue(Ray.are_near(Point(), r, 2))
+ self.assertFalse(Ray.are_near(Point(), r))
+ self.assertTrue(Ray.are_same(r, r))
+
+ q = Ray(r.origin(), r.angle())
+ self.assertTrue(Ray.are_same(r, q))
+
+ q.set_origin(r.origin()+Point(0, 1))
+ self.assertFalse(Ray.are_same(r, q))
+ #TODO shouldn't this really be 0?
+ self.assertAlmostEqual(Ray.angle_between(r, q), 2*pi)
+
+ q.set_versor(Point(1, 0))
+ q.set_origin(r.origin())
+ self.assertAlmostEqual(
+ Point(1, 1)/sqrt(2),
+ Ray.make_angle_bisector_ray(q, r).versor())
+
+ q.set_angle(pi/7)
+ self.assertAlmostEqual(q.angle(), pi/7)
+
+ self.assertIsInstance(q.portion(2, 4), Curve)
+ self.assertAlmostEqual(q.portion(2, 4)(0), q.point_at(2))
+
+ self.assertIsInstance(q.segment(1, 5), LineSegment)
+
+ self.assertAlmostEqual(q.segment(1, 5)(1), q.point_at(5))
+
+
+unittest.main()
+