diff options
Diffstat (limited to 'src/cython/test-primitives.py')
-rw-r--r-- | src/cython/test-primitives.py | 288 |
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() + |