def test_eigen(self): #TODO looks like bug in eigen - (1, 0) should be eigenvector too #~ S = Scale(1, 2) #~ E_S = Eigen(S) #~ print E_S.vectors, E_S.values #~ print Affine(S) #~ for i in E_S.vectors: #~ print i, i*S, Point(1, 0) * S B = Affine(-2, 2, 2, 1, 0, 0) G1 = Eigen(B) G2 = Eigen([[-2, 2], [2, 1]]) self.assertAlmostEqual(min(G1.values), min(G2.values)) self.assertAlmostEqual(max(G1.values), max(G2.values)) if Point.are_near(G1.vectors[0] * G1.values[0], G1.vectors[0] * B): self.assertTrue( Point.are_near(G1.vectors[1] * G1.values[1], G1.vectors[1] * B)) else: self.assertTrue( Point.are_near(G1.vectors[1] * G1.values[0], G1.vectors[1] * B)) self.assertTrue( Point.are_near(G1.vectors[0] * G1.values[1], G1.vectors[0] * B))
def Nagon(N): """Return N-agon with side of length 1.""" side = cy2geom.LineSegment(Point(-0.5, 0), Point(0.5, 0)) angle = 2 * math.pi / N distance_to_center = 0.5 / math.tan(math.pi / N) return Path.fromList([ side.transformed( cy2geom.Translate(Point(0, -distance_to_center)) * cy2geom.Rotate(angle * i)) for i in range(N) ], stitching=Path.STITCH_DISCONTINUOUS, closed=True)
def test_quadraticBezier(self): Q = QuadraticBezier(Point(2, 8), Point(1, 9), Point(-2, 3)) R = QuadraticBezier.from_beziers(Bezier(2, 8, 4), Bezier(-1, 9, 9)) self.curve(Q) self.curve(R) self.curve(Q.reverse()) self.curve(Q.portion(interval=Interval(0.1, 0.9))) self.curve(Q.subdivide(0.8)[0]) self.curve(Q.subdivide(0.8)[1]) self.curve(Q.derivative()) self.curve(Q.transformed(Scale(-3)*Translate(4, 8))) self.curve(QuadraticBezier())
def ntest_lineSegment(self): L = LineSegment(Point(2, 8), Point(1, 9)) K = LineSegment.from_beziers(Bezier(2, 8), Bezier(-1, 9)) self.curve(L) self.curve(K) self.curve(L.reverse()) self.curve(L.portion(Interval(0.2, 0.4))) self.curve(L.subdivide(0.3)[0]) self.curve(L.subdivide(0.3)[1]) self.curve(L.derivative()) self.curve(L.transformed(Scale(30)*Translate(3, 9))) self.curve(LineSegment())
def test_cubicBezier(self): C = CubicBezier(Point(2, 0), Point(-1, 2.9), Point(-2, 3), Point(3, 1)) D = CubicBezier.from_beziers(Bezier(2, 8, 4, 7), Bezier(-1, 9, 9, 8)) print 343 self.curve(C) self.curve(D) self.curve(C.reverse()) #Some kind of numerical instability imo #~ self.curve(C.portion(Interval(0.1, 0.9))) self.curve(C.subdivide(0.8)[0]) self.curve(C.subdivide(0.8)[1]) self.curve(C.derivative()) self.curve(C.transformed(Scale(-3)*Translate(4, 8))) self.curve(CubicBezier())
def test_angle(self): self.assertAlmostEqual(Angle.deg_to_rad(45), pi / 4) self.assertAlmostEqual(Angle.rad_to_deg(pi / 6), 30) self.assertAlmostEqual( Angle.map_circular_arc_on_unit_interval(pi / 6, 0, pi / 2), 1 / 3.) self.assertAlmostEqual( Angle.map_unit_interval_on_circular_arc(0.4, 0, pi), 2 * pi / 5) self.assertTrue(Angle.arc_contains(pi / 3, pi / 4, pi / 2, pi)) self.assertFalse(Angle.arc_contains(pi / 6, pi / 4, pi / 2, pi)) 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_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_rotate(self): R = Rotate() S = Rotate(pi / 3) T = Rotate(Point(1, 1)) U = Rotate(-1, 1) self.assertTrue(S.vector(), Point(cos(pi / 3), sin(pi / 3))) self.assertEqual(Point(T[0], T[1]), T.vector()) self.assertTrue(Affine.are_near(Rotate.from_degrees(60), S)) self.assertEqual(R, Rotate.identity()) self.assertTrue( Point.are_near((S * T).vector(), Point(cos(pi / 3 + pi / 4), sin(pi / 3 + pi / 4)))) self.affine(Affine(R), Affine(S)) self.affine(Affine(S), Affine(T)) self.affine(Affine(T), Affine(U)) self.affine(Affine(U), Affine(R))
def test_translate(self): T = Translate() U = Translate(Point(2, 4)) V = Translate(1, -9) self.assertTrue(Affine(T).is_translation()) self.assertTrue(Affine(U).is_nonzero_translation()) self.assertEqual((U * V).vector(), U.vector() + V.vector()) self.assertEqual(U.inverse().vector(), -U.vector()) self.assertEqual(T, Translate.identity()) self.assertEqual(U.vector(), Point(U[0], U[1])) self.affine(Affine(V), Affine(U)) self.affine(Affine(U), Affine(V)) r = Rect.from_points(Point(0, 2), Point(4, 8)) self.assertEqual((r * (U * V)).min(), r.min() + U.vector() + V.vector())
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_eigen(self): #TODO looks like bug in eigen - (1, 0) should be eigenvector too #~ S = Scale(1, 2) #~ E_S = Eigen(S) #~ print E_S.vectors, E_S.values #~ print Affine(S) #~ for i in E_S.vectors: #~ print i, i*S, Point(1, 0) * S B = Affine(-2, 2, 2, 1, 0, 0) G1 = Eigen(B) G2 = Eigen( [[-2, 2], [2, 1]] ) self.assertAlmostEqual(min(G1.values), min(G2.values)) self.assertAlmostEqual(max(G1.values), max(G2.values)) if Point.are_near( G1.vectors[0]*G1.values[0], G1.vectors[0]*B ): self.assertTrue( Point.are_near( G1.vectors[1]*G1.values[1], G1.vectors[1]*B ) ) else: self.assertTrue( Point.are_near( G1.vectors[1]*G1.values[0], G1.vectors[1]*B ) ) self.assertTrue( Point.are_near( G1.vectors[0]*G1.values[1], G1.vectors[0]*B ) )
def test_scale(self): S = Scale() T = Scale(Point(3, 8)) U = Scale(-3, 1) V = Scale(sqrt(2)) self.assertTrue(Affine(T).is_scale()) self.assertTrue(Affine(T).is_nonzero_scale()) self.assertTrue(Affine(V).is_nonzero_uniform_scale()) self.assertEqual((T * V).vector(), T.vector() * sqrt(2)) self.assertEqual((T * U)[0], T[0] * U[0]) self.assertAlmostEqual(1 / U.inverse()[1], U[1]) r = Rect.from_points(Point(0, 2), Point(4, 8)) self.assertAlmostEqual((r * V).area(), 2 * r.area()) self.assertFalse(Affine(U).preserves_area()) self.assertTrue(Affine(V).preserves_angles()) self.affine(Affine(T), Affine(U)) self.affine(Affine(U), Affine(V)) self.affine(Affine(V), Affine(T))
def test_affine(self): al = [] for i in range(10): al.append( Affine(uniform(-10, 10), uniform(-10, 10), uniform(-10, 10), uniform(-10, 10), uniform(-10, 10), uniform(-10, 10))) for A in al: for B in al: self.affine(A, B) o = Point(2, 4) v = Point(-1, 1) / sqrt(2) l = Line.from_origin_and_versor(o, v) R = Affine.reflection(v, o) for i in range(100): p = Point(randint(0, 100), randint(0, 100)) self.assertAlmostEqual(Line.distance(p, l), Line.distance(p * R, l)) self.assertTrue(Affine.are_near(R, R.inverse())) self.affine(R, R.inverse())
def test_optRect(self): P = OptRect(0.298, 2, 4, 5) self.interval_basic(P.Rect[0], P.Rect[1]) G = Rect(sqrt(2), sqrt(2), sqrt(3), sqrt(3)) H = OptRect.from_rect(G) self.rect_basic(P.Rect, G) lst = [Point(randint(-100, 100), randint(-100, 100)) for i in range(10)] R = OptRect.from_list(lst) for p in lst: self.assertTrue(R.Rect.contains(p)) self.assertAlmostEqual(min(lst).y, R.Rect.min().y) self.assertAlmostEqual(max(lst).y, R.Rect.max().y) Q = OptRect() self.assertFalse(Q) self.assertTrue(P) self.assertTrue(Q.is_empty()) self.assertFalse(P.is_empty()) self.assertTrue(P.contains_rect( P )) self.assertTrue(P.contains_rect(Q)) self.assertFalse(Q.contains_rect(P)) self.assertFalse(P.intersects(Q)) self.assertTrue(P.contains_rect(P.Rect)) self.assertTrue(P.contains(P.Rect.midpoint())) self.assertEqual(P, OptRect.from_rect(P)) P.union_with(G) P.union_with(H) self.assertTrue(P.contains_rect(H)) P.intersect_with(G) self.assertEqual(P, G) self.assertEqual( P|H, G ) self.assertEqual( (P|R).Rect.min().x , min( P.Rect.min().x, R.Rect.min().x )) self.assertFalse(P & Q) self.assertEqual(P, P&P) self.assertEqual( P & (R | H), (P & R) | (P & H) )
def test_bezierCurve(self): B = BezierCurve.create( [ Point(0, 5), Point(3, 65), Point(-3, 2), Point(1, 9) ] ) C = BezierCurve.create( [ Point(0,1), Point(1, 0) ] ) self.curve(B) self.curve(C) self.curve(C.reverse()) self.curve(B.portion(0, 2)) self.curve(B.transformed(Zoom(9, Translate(3, 6)))) self.curve(B.derivative())
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_rotate(self): R = Rotate() S = Rotate(pi/3) T = Rotate(Point( 1, 1 )) U = Rotate( -1, 1 ) self.assertTrue(S.vector(), Point(cos(pi/3), sin(pi/3)) ) self.assertEqual( Point(T[0], T[1]), T.vector() ) self.assertTrue( Affine.are_near( Rotate.from_degrees(60), S ) ) self.assertEqual(R, Rotate.identity()) self.assertTrue( Point.are_near( ( S * T ).vector(), Point( cos( pi/3 + pi/4 ), sin( pi/3 + pi/4 ) ) ) ) self.affine( Affine(R), Affine(S)) self.affine( Affine(S), Affine(T)) self.affine( Affine(T), Affine(U)) self.affine( Affine(U), Affine(R))
def test_zoom(self): Z = Zoom(3) Y = Zoom(translate=Translate(3, 2)) X = Zoom(sqrt(3), Translate(-1, 3)) self.assertEqual(Zoom(Z.scale(), Translate(Y.translation())), Y * Z) Z.set_translation(Y.translation()) Y.set_scale(Z.scale()) self.assertEqual(Z, Y) self.assertEqual(Y.inverse().scale(), 1 / Y.scale()) r = Rect.from_xywh(1, 1, 3, 6) q = Rect.from_xywh(0, -1, 1, 2) W = Zoom.map_rect(r, q) self.assertAlmostEqual(W.scale() * r.width(), q.width()) self.assertTrue(Point.are_near(r.min() + W.translation(), q.min()))
def test_rect(self): P = Rect(0.298, 2, 4, 5) self.interval_basic(P[0], P[1]) G = Rect(sqrt(2), sqrt(2), sqrt(3), sqrt(3)) H = Rect.from_xywh(3.43232, 9.23214, 21.523, -0.31232) self.rect_basic(P, G) self.rect_basic(G, H) lst = [Point(randint(-100, 100), randint(-100, 100)) for i in range(10)] R = Rect.from_list(lst) for p in lst: self.assertTrue(R.contains(p)) self.assertAlmostEqual(min(lst).y, R.min().y) self.assertAlmostEqual(max(lst).y, R.max().y)
def test_sVGEllipticalArc(self): F1 = EllipticalArc(Point(), 1, 2, math.pi/6, True, True, Point(1, 1)) F2 = SVGEllipticalArc(Point(), 1, 2, math.pi/6, True, True, Point(1, 1)) for i in range(11): t = i/10.0 self.assertAlmostEqual(F1(t), F2(t)) #degenerate ellipse D = SVGEllipticalArc(Point(0, 0), 0.5, 0, 0, False, False, Point(1, 0)) self.assertTrue(D.is_degenerate()) for i in range(11): t = i/10.0 self.assertAlmostEqual(D(t), D.chord()(t)) self.assertAlmostEqual(D.value_at(t, 0), t) self.assertAlmostEqual(D.roots(t, 0)[0], t) self.assertIsInstance(D.derivative(), LineSegment)
def test_hLineSegment(self): H = HLineSegment(Point(3, 9), Point(9, 9)) I = HLineSegment(Point(1, 3), Point(92, 3)) J = HLineSegment.from_point_length( Point(2, 4), 1) self.curve( H ) self.curve( I ) self.curve( J ) self.curve( H.portion(0, .25) ) self.curve( H.derivative() ) self.curve( H.transformed(Rotate(20)) ) self.curve( HLineSegment() ) self.curve( I.reverse() ) map(self.curve, I.subdivide(0.8)) self.assertAlmostEqual(I.get_Y(), 3) J.set_Y(2) J.set_initial_X(0) J.set_final_X(1) self.assertAlmostEqual( J(0), Point(0, 2) ) self.assertAlmostEqual( J(1), Point(1, 2) )
def test_zoom(self): Z = Zoom(3) Y = Zoom(translate=Translate(3,2)) X = Zoom(sqrt(3), Translate(-1, 3)) self.assertEqual( Zoom(Z.scale(), Translate(Y.translation())), Y*Z ) Z.set_translation(Y.translation()) Y.set_scale(Z.scale()) self.assertEqual(Z, Y) self.assertEqual(Y.inverse().scale(), 1/Y.scale()) r = Rect.from_xywh( 1, 1, 3, 6) q = Rect.from_xywh( 0, -1, 1, 2) W = Zoom.map_rect(r, q) self.assertAlmostEqual(W.scale()*r.width(), q.width()) self.assertTrue(Point.are_near( r.min()+W.translation(), q.min()))
def path(self, P): for curve in P: self.assertIsInstance(curve, Curve) self.assertAlmostEqual(P(0), P.front()(0)) self.curves_equal(P.front(), P[0]) self.curves_equal(P.back_default(), P[P.size_default() - 1]) self.curves_equal(P.back_open(), P.back()) self.assertEqual(P.size_open(), P.size()) self.assertFalse(P.empty() ^ (P.size() == 0)) exact = P.bounds_exact().Rect exact.expand_by(1e-5) fast = P.bounds_fast().Rect fast.expand_by(1e-5) A1 = Affine(3, 1, 8, 3, 9, 9) A2 = Rotate(0.231) for i in range(100 * P.size_open() + 1): t = i / 100.0 self.assertTrue(exact.contains(P(t))) self.assertTrue(fast.contains(P(t))) self.assertAlmostEqual((P * A1)(t), P(t) * A1) self.assertAlmostEqual((P * A2)(t), P(t) * A2) self.assertAlmostEqual(P(t), P.point_at(t)) self.assertAlmostEqual(P(t).x, P.value_at(t, 0)) self.assertAlmostEqual(P(t).y, P.value_at(t, 1)) if P.closed(): self.curves_equal(P.back_default(), P.back_closed()) self.assertEqual(P.size_default(), P.size_closed()) else: self.curves_equal(P.back_default(), P.back_open()) self.assertEqual(P.size_default(), P.size_open()) for i in range(10): for root in P.roots(i, 0): if root < P.size_default(): self.assertAlmostEqual(P.value_at(root, 0), i) for root in P.roots(i, 1): if root < P.size_default(): self.assertAlmostEqual(P.value_at(root, 1), i) for t in P.all_nearest_times(P(0)): self.assertAlmostEqual(P(t), P(0)) self.assertAlmostEqual(min(P.all_nearest_times(P(0))), 0) self.assertAlmostEqual(P.nearest_time(P(0), 0, 0.2), 0) self.assertEqual(len(P.nearest_time_per_curve(Point())), P.size_default()) t, distSq = P.nearest_time_and_dist_sq(Point(-1, -1), 0, P.size()) self.assertAlmostEqual(distSq**0.5, abs(P(t) - Point(-1, -1))) self.assertAlmostEqual(P.portion(0.3, 0.4)(0), P(0.3)) self.assertAlmostEqual( P.portion(interval=Interval(P.size(), P.size() * 2) / 3)(0), P(P.size() / 3.0)) self.assertAlmostEqual(P(0.23), P.reverse()(P.size() - 0.23)) self.assertAlmostEqual(P.initial_point(), P(0)) self.assertAlmostEqual(P.final_point(), P(P.size()))
def test_path(self): a = Path() a.append_curve( CubicBezier(Point(-7, -3), Point(2, 8), Point(2, 1), Point(-2, 0))) self.assertEqual(a.size(), 1) self.assertFalse(a.closed()) self.path(a) a.close(True) self.assertTrue(a.closed()) self.path(a) a.close(False) a.append_curve(LineSegment(a.final_point(), Point(3, 5))) self.assertEqual(a.size(), 2) self.path(a) a.append_SBasis(SBasis(3, 6) * SBasis(1, 0), SBasis(5, 2)) self.path(a) a.append_curve( EllipticalArc(Point(), 1, 2, math.pi / 6, True, True, Point(1, 1)), Path.STITCH_DISCONTINUOUS) #Stitching adds new segment self.assertEqual(a.size(), 5) b = Path() for c in a: b.append_curve(c) #TODO: This fails with STITCH_DISCONTINUOUS, but also does so in C++, so #it's either correct behaviour or bug in 2geom #~ self.path(b) b.insert(2, LineSegment(b[2 - 1](1), b[2](0))) #, Path.STITCH_DISCONTINUOUS) self.curves_equal(LineSegment(b[2 - 1](1), b[2](0)), b[2]) #TODO! fails on root finding #self.path(b) b.set_initial(a[2](1)) b.set_final(a[3](0)) a.insert_slice(3, b, 0, b.size()) self.assertEqual(a.size(), b.size() * 2 - 1) for i in range(b.size()): self.curves_equal(a[3 + i], b[i]) #Looks like bug: # A = Path() # A.append_curve( CubicBezier( Point(-7, -3), Point(2, 8), Point(2, 1), Point(-2, 0) ) ) # A.append_curve(EllipticalArc(Point(), 1, 2, math.pi/6, True, True, Point(1, 1)), Path.STITCH_DISCONTINUOUS) # print A.roots(0, 1) #Roots are [1.0, 2.768305708350847, 3.25], Point at second root is #Point (2.32, -0.48) #and third root is > 3 - it corresponds to root on closing segment, but A is open, #and computing A(3.25) results in RangeError - this might be bug or feature. self.path(a.portion(0.232, 3.12)) self.path(a.portion(interval=Interval(0.1, 4.7))) self.path(a.portion(0.232, 3.12).reverse()) b.clear() self.assertTrue(b.empty()) aa = Path() for c in a: aa.append_curve(c) a.erase(0) self.assertEqual(a.size(), aa.size() - 1) self.assertAlmostEqual(a(0), aa(1)) a.erase_last() self.assertEqual(a.size(), aa.size() - 2) self.assertAlmostEqual(a.final_point(), aa[aa.size() - 2](1)) a.replace(3, QuadraticBezier(a(3), Point(), a(4))) self.assertEqual(a.size(), aa.size() - 2) cs = [ LineSegment(Point(-0.5, 0), Point(0.5, 0)).transformed( Rotate(-math.pi / 3 * i) * Translate( Point(0, math.sqrt(3) / 2) * Rotate(-math.pi / 3 * i))) for i in range(6) ] hexagon = Path.fromList(cs, stitching=Path.STITCH_DISCONTINUOUS, closed=True) if draw: utils.draw(hexagon, scale=100) #to = 5 because each corner contains one stitching segment half_hexagon = Path.fromPath(hexagon, fr=0, to=5) if draw: utils.draw(half_hexagon, scale=100) half_hexagon.replace_slice( 1, 5, LineSegment(half_hexagon(1), half_hexagon(5))) self.assertEqual(half_hexagon.size(), 2) self.assertAlmostEqual(half_hexagon(1.5), Point(0.5, 0)) half_hexagon.stitch_to(half_hexagon(0)) self.assertAlmostEqual(half_hexagon(2.5), Point()) a.start(Point(2, 2)) a.append_SBasis(SBasis(2, 6), SBasis(1, 5) * SBasis(2, 9)) self.assertAlmostEqual(a(1), Point(6, 5 * 9)) l = Path.fromList( [QuadraticBezier(Point(6, 5 * 9), Point(1, 2), Point(-2, .21))]) a.append_path(l) self.assertAlmostEqual(a.final_point(), l.final_point()) k = Path.fromList( [QuadraticBezier(Point(), Point(2, 1), Point(-2, .21)).reverse()]) k.append_portion_to(l, 0, 0.3) self.assertAlmostEqual(l.final_point(), k(0.3))
def curve(self, C): self.assertAlmostEqual(C.initial_point(), C(0)) self.assertAlmostEqual(C.final_point(), C.point_at(1)) #Doesn't have to be true #~ if C.length() > 0.01: #~ self.assertFalse(C.is_degenerate()) if C.is_degenerate(): #trivial special case return for i in range(11): t = i/10.0 self.assertAlmostEqual(C(t).x, C.point_at(t).x) self.assertAlmostEqual(C(t).y, C.value_at(t, 1)) self.assertEqual( C(t), C.point_and_derivatives(t, 1)[0] ) self.assertTrue( C.bounds_exact().contains(C(t)) ) self.assertTrue( C.bounds_fast().contains(C(t)) ) #TODO why this works only with degree = 0? if C.bounds_local(OptInterval(t-0.05, t+0.05), 0 ) and ( C.bounds_local(OptInterval(t-0.05, t+0.05), 0).Rect.area() > 1e-10): #ruling out too small rectangles, they have problems with precision self.assertTrue( C.bounds_local( OptInterval(t-0.05, t+0.05), 0 ).Rect.contains(C(t))) D = C.duplicate() D.set_initial(Point()) self.assertAlmostEqual(D.initial_point(), Point()) D.set_final(Point(1, 1)) self.assertAlmostEqual(D.final_point(), Point(1, 1)) A = Affine( uniform(-10, 10), uniform(-10, 10), uniform(-10, 10), uniform(-10, 10), uniform(-10, 10), uniform(-10, 10)) E = C.transformed(A) for i in range(11): t = i/10.0 # self.assertAlmostEqual( E(t), C(t)*A ) G1 = C.portion(0.2, 0.8) G2 = C.portion( interval=Interval(2, 8)/10 ) self.assertAlmostEqual( G1(0), C(0.2) ) self.assertAlmostEqual( G2(0.5), C( lerp(0.5, 0.2, 0.8) )) self.assertAlmostEqual( G1(1), G2(1) ) for i in range(11): t = i/10.0 self.assertAlmostEqual( C.reverse()(t), C(1-t) ) self.assertAlmostEqual( C.point_and_derivatives(0.3, 1)[1], C.derivative()(0.3) ) self.assertAlmostEqual( C.nearest_time(C(0)), 0 ) self.assertAlmostEqual( C( C.nearest_time(C(0.5), interval=Interval(0.2, 0.5)) ), C(0.5) ) self.assertAlmostEqual( C( C.nearest_time(C(0.5), 0.2, 0.5) ), C(0.5) ) for p in C.all_nearest_times( C(0), 0, 1): self.assertEqual(C(p), C(0)) for p in C.all_nearest_times( C(1), interval=Interval(0, 1)): self.assertEqual(C(p), C(1)) for r in C.roots(0, 0): self.assertAlmostEqual(C.value_at(r, 0), 0) self.assertGreaterEqual(C.length(), abs(C(1) - C(0))) self.assertEqual(C.winding(Point()), int(C.winding(Point())) ) self.assertAlmostEqual( C.unit_tangent_at(0.5), Point.unit_vector(C.derivative()(0.5)) ) self.assertTrue(isinstance(C.to_SBasis()[0], SBasis))
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)
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))
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_point(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 get_curve(ellipse): p = Point(ellipse.ray(0), 0) * Rotate(ellipse.rot_angle()) return ellipse.arc(ellipse.center() + p, ellipse.center() - p, ellipse.center() + p * (1 - 1e-7))
def test_ellipse(self): #TODO: maybe a bug in arc? get_curve(F) returns different ellipse than F def get_curve(ellipse): p = Point(ellipse.ray(0), 0) * Rotate(ellipse.rot_angle()) return ellipse.arc(ellipse.center() + p, ellipse.center() - p, ellipse.center() + p * (1 - 1e-7)) E = Ellipse() self.assertAlmostEqual(E.center(), Point()) self.assertAlmostEqual(E.ray(0), 0) self.assertAlmostEqual(E.ray(1), 0) F = Ellipse(Point(), 3, 2, 0) self.assertAlmostEqual(F.center(), Point()) self.assertAlmostEqual(F.ray(0), 3) self.assertAlmostEqual(F.ray(1), 2) self.assertAlmostEqual(F.rot_angle(), 0) # x**2/9 + y**2/4 = 1 self.assertAlmostEqual(F.implicit_form_coefficients()[0], 1 / 9.0) self.assertAlmostEqual(F.implicit_form_coefficients()[2], 1 / 4.0) self.assertAlmostEqual(F.implicit_form_coefficients()[5], -1) coeffs = (1 / 3.0, 0, 1 / 16.0, 1, 0, -1 / 4.0) G = Ellipse.from_coefficients(*coeffs) self.assertAlmostEqual(G.center(), Point(-3 / 2.0, 0)) self.assertAlmostEqual(G.ray(0), math.sqrt(3)) self.assertAlmostEqual(G.ray(1), 4) self.assertAlmostEqual(G.rot_angle(), 0) points = [ Point(1, 2), Point(2, 9), Point(0, 3), Point(-3, 8), Point(5, 8) ] G.set_points(points) coeffs_G = tuple(G.implicit_form_coefficients()) def paramG(x, y): A, B, C, D, E, F = coeffs_G return A * x**2 + B * x * y + C * y**2 + D * x + E * y + F for p in points: self.assertAlmostEqual(paramG(p.x, p.y), 0) G2 = Ellipse.from_points(points) coeffs_G2 = tuple(G.implicit_form_coefficients()) def paramG2(x, y): A, B, C, D, E, F = coeffs_G2 return A * x**2 + B * x * y + C * y**2 + D * x + E * y + F for p in points: self.assertAlmostEqual(paramG2(p.x, p.y), 0) E.set_coefficients(*coeffs_G2) for a1, a2 in zip(E.implicit_form_coefficients(), G2.implicit_form_coefficients()): self.assertAlmostEqual(a1, a2) H = Ellipse.from_circle(Circle(Point(2, 8), 5)) self.assertAlmostEqual(H.center(), Point(2, 8)) self.assertAlmostEqual(H.ray(0), 5) self.assertAlmostEqual(H.ray(1), 5) Ft = F.transformed(Rotate(math.pi / 2)) self.assertAlmostEqual(F.ray(0), Ft.ray(1)) self.assertAlmostEqual(F.ray(1), Ft.ray(0))
def test_circle(self): C = Circle() self.assertEqual(C.center(), Point()) D = Circle(Point(2, 4), 2) Dp = D.getPath() self.assertEqual(D.center(), Point(2, 4)) self.assertEqual(D.ray(), 2) for i in range(11): t = i / 10.0 #Circle approximated by SBasis is not perfect self.assertAlmostEqual(abs(D.center() - Dp(t)), D.ray(), delta=0.1) half_circle = D.arc(Dp(0), Dp(0.3), Dp(0.5)) self.assertTrue(half_circle.is_SVG_compliant()) self.assertAlmostEqual(Dp(0.25), half_circle(0.5), delta=0.1) points = [Point(2, 5), Point(1, 4), Point(9, 0)] D.set_points(points) for p in points: self.assertAlmostEqual(abs(p - D.center()), D.ray()) Dc = Circle.from_points(points) self.assertAlmostEqual(Dc.center(), D.center()) self.assertAlmostEqual(Dc.ray(), D.ray()) coeffs = (2, 4, 1, -4) E = Circle.from_coefficients(*coeffs) def param(x, y): A, B, C, D = coeffs return A * x**2 + A * y**2 + B * x + C * y + D Ec = E.arc(E.center() + Point(E.ray(), 0), E.center() - Point(E.ray(), 0), E.center() + Point(E.ray(), 0)) for i in range(11): t = i / 10.0 self.assertAlmostEqual(param(Ec.value_at(t, 0), Ec.value_at(t, 1)), 0) E.set(3, 5, 9) self.assertAlmostEqual(E.center(), Point(3, 5)) self.assertAlmostEqual(E.ray(), 9) E.set_coefficients(*coeffs) #radius and center from parametric equation ca = float(coeffs[1]) / coeffs[0] cb = float(coeffs[2]) / coeffs[0] cc = float(coeffs[3]) / coeffs[0] self.assertAlmostEqual(4 * E.ray()**2, ca**2 + cb**2 - 4 * cc) self.assertAlmostEqual(E.center(), -Point(ca, cb) / 2)
def test_vLineSegment(self): V = VLineSegment(Point(2, 9), Point(2, 6)) W = VLineSegment(Point(1, 2), Point(1, 8)) X = VLineSegment.from_point_length( Point(2, 4), 1)
def test_ellipticalArc(self): E = EllipticalArc() self.curve(E) F = EllipticalArc(Point(), 1, 2, math.pi/6, True, True, Point(1, 1)) self.assertTrue(F.sweep()) self.assertTrue(F.large_arc()) self.assertAlmostEqual(F.chord()(0), Point()) self.assertAlmostEqual(F.chord()(1), Point(1, 1)) F.set_extremes(Point(1, 1), Point(-1, 1)) self.assertAlmostEqual(F.initial_point(), Point(1, 1)) self.assertAlmostEqual(F.final_point(), Point(-1, 1)) self.assertEqual(F.initial_angle(), F.angle_at(0)) self.assertEqual(F.final_angle(), F.angle_at(1)) self.assertTrue(F.contains(F.angle_at(0.5))) G = EllipticalArc(Point(), 1, 1, 0, True, True, Point(2, 0)) for i in range(11): t = i/10.0 print G(t) self.assertAlmostEqual(G.extent(), math.pi) self.assertAlmostEqual(G.extent(), G.sweep_angle()) self.assertAlmostEqual(float(G.angle_at(0.5)), -math.pi/2) self.assertAlmostEqual(Point(1, 1), G.rays()) self.assertAlmostEqual(1, G.ray(1)) self.assertAlmostEqual(0, float(G.rotation_angle())) self.assertAlmostEqual(G.extent(), G.angle_interval().extent()) self.assertAlmostEqual(G.center(), Point(1, 0)) #unit half-circle U = EllipticalArc(Point(1, 0), 1, 1, 0, True, True, Point(-1, 0)) G.set(Point(), 1, 1, 0, True, False, Point(1, 0)) A = G.unit_circle_transform() self.assertAlmostEqual( G(0.5), U.transformed(A)(0.5) ) self.assertAlmostEqual( G.value_at_angle(G.angle_at(0.32), 0), G.value_at(0.32, 0) ) self.assertTrue(G.contains_angle(Angle(math.pi/4))) self.assertFalse(G.is_SVG_compliant())
def rect_basic(self, P, Q): pmin = P.min() pmax = P.max() #for simplicity self.assertTrue(pmin.x > 0) self.assertTrue(pmin.y > 0) self.assertAlmostEqual(pmin.x, P[0].min()) self.assertAlmostEqual(pmax.y, P[1].max()) self.assertEqual(pmin, P.corner(0)) self.assertEqual(pmin, Point(P.left(), P.top())) self.assertEqual(pmax, Point(P.right(), P.bottom())) self.assertAlmostEqual( P.width(), P[0].extent() ) self.assertAlmostEqual( P.height(), P[1].extent() ) self.assertAlmostEqual( P.aspect_ratio(), P.width()/P.height() ) self.assertEqual( P.dimensions(), Point( P.width(), P.height() ) ) self.assertEqual( P.midpoint(), (P.min() + P.max())/2 ) self.assertAlmostEqual(P.area(), P.width()*P.height()) #TODO export EPSILON from 2geom if P.area() > 1e-7: self.assertFalse(P.has_zero_area()) self.assertTrue(P.has_zero_area(P.area())) else: self.assertTrue(P.has_zero_area()) self.assertAlmostEqual(P.max_extent(), max(P.width(), P.height())) self.assertGreaterEqual(P.max_extent(), P.min_extent()) qmin = Q.min() qmax = Q.max() pdiag = (pmax-pmin).length() Q.set_min(P.midpoint()) Q.set_max(P.midpoint()) self.assertTrue(Q.has_zero_area()) #print P,Q Q.expand_by(P.min_extent()/3.0) #print P, Q self.assertTrue(P.contains_rect(Q)) self.assertTrue(P.intersects(Q)) self.assertTrue(Q.intersects(P)) self.assertFalse(Q.contains_rect(P)) self.assertTrue(P.interior_contains_rect(Q)) self.assertFalse(P.interior_contains_rect(P)) self.assertTrue(P.interior_intersects(Q)) self.assertTrue(P.interior_intersects(P)) self.assertTrue(P.contains(P.midpoint())) self.assertFalse(P.contains(P.midpoint()*3)) P.union_with(Q) self.assertEqual( P.min(), pmin ) Q.set_left(qmin.x) Q.set_top(qmin.y) Q.set_right(qmax.x) Q.set_bottom(qmax.y) self.assertEqual(Q.min(), qmin) self.assertEqual(Q.max(), qmax) Q.expand_to( Point() ) self.assertEqual(Point(), Q.min()) Q.expand_by(qmax) self.assertEqual(qmax, -Q.min()) Q.expand_by(-qmax.x, -qmax.y) self.assertEqual(Q.max(), qmax) self.assertEqual( (P+Q.min()).max(), P.max() + Q.min() ) self.assertEqual( (P-Q.max()).min(), P.min() - Q.max() ) self.assertEqual( P|P, P ) self.assertFalse( P != P ) Q.set_left(qmin.x) Q.set_top(qmin.y) Q.set_right(qmax.x) Q.set_bottom(qmax.y) self.assertAlmostEqual(Rect.distance(Point(), P), P.min().length()) self.assertAlmostEqual(Rect.distanceSq(Q.min(), P), Rect.distance(Q.min(), P)**2 ) self.assertEqual(P.round_outwards()[0], P[0].round_outwards()) if P.round_inwards(): self.assertEqual(P.round_inwards().Rect[1], P[1].round_inwards().Interval)
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_point(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_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)