diff options
Diffstat (limited to 'src/cython/test-conicsection.py')
-rw-r--r-- | src/cython/test-conicsection.py | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/cython/test-conicsection.py b/src/cython/test-conicsection.py new file mode 100644 index 0000000..9fc1c20 --- /dev/null +++ b/src/cython/test-conicsection.py @@ -0,0 +1,137 @@ +import unittest +import math +from random import randint, uniform + +import cy2geom + +from cy2geom import Point, IntPoint +from cy2geom import Interval, IntInterval, OptInterval, OptIntInterval + +from cy2geom import Affine +from cy2geom import Translate, Scale, Rotate, VShear, HShear, Zoom +from cy2geom import Eigen + +from cy2geom import Curve +from cy2geom import Linear +from cy2geom import SBasis, SBasisCurve +from cy2geom import Bezier, BezierCurve + +from cy2geom import LineSegment, QuadraticBezier, CubicBezier +from cy2geom import HLineSegment, VLineSegment + +from cy2geom import EllipticalArc + +from cy2geom import Path + +from cy2geom import Circle, Ellipse + + +class TestPrimitives(unittest.TestCase): + 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_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)) + +unittest.main() |