From 1579c544aa3f1da88d751897cda1a64a8ec1a30b Mon Sep 17 00:00:00 2001 From: Andy Port Date: Wed, 22 Aug 2018 00:27:31 -0700 Subject: [PATCH] Revert "Arc line intersect, take 2 (#60)" This reverts commit 2da39e4c02469f133db50136d21d6f401bfb8d6b. --- svgpathtools/path.py | 265 +----------------------------------- test/test_path.py | 316 ------------------------------------------- 2 files changed, 2 insertions(+), 579 deletions(-) diff --git a/svgpathtools/path.py b/svgpathtools/path.py index bcabff9..b39c5cd 100644 --- a/svgpathtools/path.py +++ b/svgpathtools/path.py @@ -4,7 +4,7 @@ Arc.""" # External dependencies from __future__ import division, absolute_import, print_function -from math import sqrt, cos, sin, acos, asin, degrees, radians, log, pi +from math import sqrt, cos, sin, acos, degrees, radians, log, pi from cmath import exp, sqrt as csqrt, phase from collections import MutableSequence from warnings import warn @@ -686,29 +686,6 @@ class Line(object): ymax = max(self.start.imag, self.end.imag) return xmin, xmax, ymin, ymax - def point_to_t(self, point): - """If the point lies on the Line, returns its `t` parameter. - If the point does not lie on the Line, returns None.""" - - # Single-precision floats have only 7 significant figures of - # resolution, so test that we're within 6 sig figs. - if np.isclose(point, self.start, rtol=0, atol=1e-6): - return 0.0 - elif np.isclose(point, self.end, rtol=0, atol=1e-6): - return 1.0 - - # Finding the point "by hand" here is much faster than calling - # radialrange(), see the discussion on PR #40: - # https://github.com/mathandy/svgpathtools/pull/40#issuecomment-358134261 - - p = self.poly() - # p(t) = (p_1 * t) + p_0 = point - # t = (point - p_0) / p_1 - t = (point - p[0]) / p[1] - if np.isclose(t.imag, 0) and (t.real >= 0.0) and (t.real <= 1.0): - return t.real - return None - def cropped(self, t0, t1): """returns a cropped copy of this segment which starts at self.point(t0) and ends at self.point(t1).""" @@ -1471,128 +1448,6 @@ class Arc(object): y = rx*sinphi*cos(angle) + ry*cosphi*sin(angle) + self.center.imag return complex(x, y) - def point_to_t(self, point): - """If the point lies on the Arc, returns its `t` parameter. - If the point does not lie on the Arc, returns None. - This function only works on Arcs with rotation == 0.0""" - - def in_range(min, max, val): - return (min <= val) and (max >= val) - - # Single-precision floats have only 7 significant figures of - # resolution, so test that we're within 6 sig figs. - if np.isclose(point, self.start, rtol=0.0, atol=1e-6): - return 0.0 - elif np.isclose(point, self.end, rtol=0.0, atol=1e-6): - return 1.0 - - if self.rotation != 0.0: - raise ValueError("Arc.point_to_t() only works on non-rotated Arcs.") - - v = point - self.center - distance_from_center = sqrt((v.real * v.real) + (v.imag * v.imag)) - min_radius = min(self.radius.real, self.radius.imag) - max_radius = max(self.radius.real, self.radius.imag) - if (distance_from_center < min_radius) and not np.isclose(distance_from_center, min_radius): - return None - if (distance_from_center > max_radius) and not np.isclose(distance_from_center, max_radius): - return None - - # x = center_x + radius_x cos(radians(theta + t delta)) - # y = center_y + radius_y sin(radians(theta + t delta)) - # - # For x: - # cos(radians(theta + t delta)) = (x - center_x) / radius_x - # radians(theta + t delta) = acos((x - center_x) / radius_x) - # theta + t delta = degrees(acos((x - center_x) / radius_x)) - # t_x = (degrees(acos((x - center_x) / radius_x)) - theta) / delta - # - # Similarly for y: - # t_y = (degrees(asin((y - center_y) / radius_y)) - theta) / delta - - x = point.real - y = point.imag - - # - # +Y points down! - # - # sweep mean clocwise - # sweep && (delta > 0) - # !sweep && (delta < 0) - # - # -180 <= theta_1 <= 180 - # - # large_arc && (-360 <= delta <= 360) - # !large_arc && (-180 < delta < 180) - # - - end_angle = self.theta + self.delta - min_angle = min(self.theta, end_angle) - max_angle = max(self.theta, end_angle) - - acos_arg = (x - self.center.real) / self.radius.real - if acos_arg > 1.0: - acos_arg = 1.0 - elif acos_arg < -1.0: - acos_arg = -1.0 - - x_angle_0 = degrees(acos(acos_arg)) - while x_angle_0 < min_angle: - x_angle_0 += 360.0 - while x_angle_0 > max_angle: - x_angle_0 -= 360.0 - - x_angle_1 = -1.0 * x_angle_0 - while x_angle_1 < min_angle: - x_angle_1 += 360.0 - while x_angle_1 > max_angle: - x_angle_1 -= 360.0 - - t_x_0 = (x_angle_0 - self.theta) / self.delta - t_x_1 = (x_angle_1 - self.theta) / self.delta - - asin_arg = (y - self.center.imag) / self.radius.imag - if asin_arg > 1.0: - asin_arg = 1.0 - elif asin_arg < -1.0: - asin_arg = -1.0 - - y_angle_0 = degrees(asin(asin_arg)) - while y_angle_0 < min_angle: - y_angle_0 += 360.0 - while y_angle_0 > max_angle: - y_angle_0 -= 360.0 - - y_angle_1 = 180 - y_angle_0 - while y_angle_1 < min_angle: - y_angle_1 += 360.0 - while y_angle_1 > max_angle: - y_angle_1 -= 360.0 - - t_y_0 = (y_angle_0 - self.theta) / self.delta - t_y_1 = (y_angle_1 - self.theta) / self.delta - - t = None - if np.isclose(t_x_0, t_y_0): - t = (t_x_0 + t_y_0) / 2.0 - elif np.isclose(t_x_0, t_y_1): - t= (t_x_0 + t_y_1) / 2.0 - elif np.isclose(t_x_1, t_y_0): - t = (t_x_1 + t_y_0) / 2.0 - elif np.isclose(t_x_1, t_y_1): - t = (t_x_1 + t_y_1) / 2.0 - else: - # Comparing None and float yields a result in python2, - # but throws TypeError in python3. This fix (suggested by - # @CatherineH) explicitly handles and avoids the case where - # the None-vs-float comparison would have happened below. - return None - - if (t >= 0.0) and (t <= 1.0): - return t - - return None - def centeriso(self, z): """This is an isometry that translates and rotates self so that it is centered on the origin and has its axes aligned with the xy axes.""" @@ -1764,123 +1619,7 @@ class Arc(object): to let me know if you're interested in such a feature -- or even better please submit an implementation if you want to code one.""" - # This special case can be easily solved algebraically. - if (self.rotation == 0) and isinstance(other_seg, Line): - a = self.radius.real - b = self.radius.imag - - # Ignore the ellipse's center point (to pretend that it's - # centered at the origin), and translate the Line to match. - l = Line(start=(other_seg.start-self.center), end=(other_seg.end-self.center)) - - # This gives us the translated Line as a parametric equation. - # s = p1 t + p0 - p = l.poly() - - if p[1].real == 0.0: - # The `x` value doesn't depend on `t`, the line is vertical. - c = p[0].real - x_values = [c] - - # Substitute the line `x = c` into the equation for the - # (origin-centered) ellipse. - # - # x^2/a^2 + y^2/b^2 = 1 - # c^2/a^2 + y^2/b^2 = 1 - # y^2/b^2 = 1 - c^2/a^2 - # y^2 = b^2(1 - c^2/a^2) - # y = +-b sqrt(1 - c^2/a^2) - - discriminant = 1 - (c * c)/(a * a) - if discriminant < 0: - return [] - elif discriminant == 0: - y_values = [0] - else: - val = b * sqrt(discriminant) - y_values = [val, -val] - - else: - # This is a non-vertical line. - # - # Convert the Line's parametric equation to the "y = mx + c" format. - # x = p1.real t + p0.real - # y = p1.imag t + p0.imag - # - # t = (x - p0.real) / p1.real - # t = (y - p0.imag) / p1.imag - # - # (y - p0.imag) / p1.imag = (x - p0.real) / p1.real - # (y - p0.imag) = ((x - p0.real) * p1.imag) / p1.real - # y = ((x - p0.real) * p1.imag) / p1.real + p0.imag - # y = (x p1.imag - p0.real * p1.imag) / p1.real + p0.imag - # y = x p1.imag/p1.real - p0.real p1.imag / p1.real + p0.imag - # m = p1.imag/p1.real - # c = -m p0.real + p0.imag - m = p[1].imag / p[1].real - c = (-m * p[0].real) + p[0].imag - - # Substitute the line's y(x) equation into the equation for - # the ellipse. We can pretend the ellipse is centered at the - # origin, since we shifted the Line by the ellipse's center. - # - # x^2/a^2 + y^2/b^2 = 1 - # x^2/a^2 + (mx+c)^2/b^2 = 1 - # (b^2 x^2 + a^2 (mx+c)^2)/(a^2 b^2) = 1 - # b^2 x^2 + a^2 (mx+c)^2 = a^2 b^2 - # b^2 x^2 + a^2(m^2 x^2 + 2mcx + c^2) = a^2 b^2 - # b^2 x^2 + a^2 m^2 x^2 + 2a^2 mcx + a^2 c^2 - a^2 b^2 = 0 - # (a^2 m^2 + b^2)x^2 + 2a^2 mcx + a^2(c^2 - b^2) = 0 - # - # The quadratic forumla tells us: x = (-B +- sqrt(B^2 - 4AC)) / 2A - # Where: - # A = a^2 m^2 + b^2 - # B = 2 a^2 mc - # C = a^2(c^2 - b^2) - # - # The determinant is: B^2 - 4AC - # - # The solution simplifies to: - # x = (-a^2 mc +- a b sqrt(a^2 m^2 + b^2 - c^2)) / (a^2 m^2 + b^2) - # - # Solving the line for x(y) and substituting *that* into - # the equation for the ellipse gives this solution for y: - # y = (b^2 c +- abm sqrt(a^2 m^2 + b^2 - c^2)) / (a^2 m^2 + b^2) - - denominator = (a * a * m * m) + (b * b) - - discriminant = denominator - (c * c) - if discriminant < 0: - return [] - - x_sqrt = a * b * sqrt(discriminant) - x1 = (-(a * a * m * c) + x_sqrt) / denominator - x2 = (-(a * a * m * c) - x_sqrt) / denominator - x_values = [x1] - if x1 != x2: - x_values.append(x2) - - y_sqrt = x_sqrt * m - y1 = ((b * b * c) + y_sqrt) / denominator - y2 = ((b * b * c) - y_sqrt) / denominator - y_values = [y1] - if y1 != y2: - y_values.append(y2) - - intersections = [] - for x in x_values: - for y in y_values: - p = complex(x, y) + self.center - my_t = self.point_to_t(p) - if my_t == None: - continue - other_t = other_seg.point_to_t(p) - if other_t == None: - continue - intersections.append([my_t, other_t]) - return intersections - - elif is_bezier_segment(other_seg): + if is_bezier_segment(other_seg): u1poly = self.u1transform(other_seg.poly()) u1poly_mag2 = real(u1poly)**2 + imag(u1poly)**2 t2s = polyroots01(u1poly_mag2 - 1) diff --git a/test/test_path.py b/test/test_path.py index 067d2c9..ce4d86a 100644 --- a/test/test_path.py +++ b/test/test_path.py @@ -4,7 +4,6 @@ import unittest from math import sqrt, pi from operator import itemgetter import numpy as np -import random # Internal dependencies from svgpathtools import * @@ -17,48 +16,6 @@ from svgpathtools.path import _NotImplemented4ArcException # to be correct visually with the disvg() function. -def random_line(): - x = (random.random() - 0.5) * 2000 - y = (random.random() - 0.5) * 2000 - start = complex(x, y) - - x = (random.random() - 0.5) * 2000 - y = (random.random() - 0.5) * 2000 - end = complex(x, y) - - return Line(start, end) - - -def random_arc(): - x = (random.random() - 0.5) * 2000 - y = (random.random() - 0.5) * 2000 - start = complex(x, y) - - x = (random.random() - 0.5) * 2000 - y = (random.random() - 0.5) * 2000 - end = complex(x, y) - - x = (random.random() - 0.5) * 2000 - y = (random.random() - 0.5) * 2000 - radius = complex(x, y) - - large_arc = random.choice([True, False]) - sweep = random.choice([True, False]) - - return Arc(start=start, radius=radius, rotation=0.0, large_arc=large_arc, sweep=sweep, end=end) - - -def assert_intersections(a_seg, b_seg, intersections, count): - if count != None: - assert(len(intersections) == count) - for i in intersections: - assert(i[0] >= 0.0) - assert(i[0] <= 1.0) - assert(i[1] >= 0.0) - assert(i[1] <= 1.0) - assert(np.isclose(a_seg.point(i[0]), b_seg.point(i[1]))) - - class LineTest(unittest.TestCase): def test_lines(self): @@ -99,73 +56,6 @@ class LineTest(unittest.TestCase): self.assertTrue(line != str(line)) self.assertFalse(cubic == line) - def test_point_to_t(self): - l = Line(start=(0+0j), end=(0+10j)) - assert(l.point_to_t(0+0j) == 0.0) - assert(np.isclose(l.point_to_t(0+5j), 0.5)) - assert(l.point_to_t(0+10j) == 1.0) - assert(l.point_to_t(1+0j) == None) - assert(l.point_to_t(0-1j) == None) - assert(l.point_to_t(0+11j) == None) - - l = Line(start=(0+0j), end=(10+10j)) - assert(l.point_to_t(0+0j) == 0.0) - assert(np.isclose(l.point_to_t(5+5j), 0.5)) - assert(l.point_to_t(10+10j) == 1.0) - assert(l.point_to_t(1+0j) == None) - assert(l.point_to_t(0-1j) == None) - assert(l.point_to_t(0+11j) == None) - assert(l.point_to_t(10.001+10.001j) == None) - assert(l.point_to_t(-0.001-0.001j) == None) - - l = Line(start=(0+0j), end=(10+0j)) - assert(l.point_to_t(0+0j) == 0.0) - assert(np.isclose(l.point_to_t(5+0j), 0.5)) - assert(l.point_to_t(10+0j) == 1.0) - assert(l.point_to_t(0+1j) == None) - assert(l.point_to_t(0-1j) == None) - assert(l.point_to_t(0+11j) == None) - assert(l.point_to_t(10.001+0j) == None) - assert(l.point_to_t(-0.001-0j) == None) - - l = Line(start=(-2-1j), end=(11-20j)) - assert(l.point_to_t(-2-1j) == 0.0) - assert(np.isclose(l.point_to_t(4.5-10.5j), 0.5)) - assert(l.point_to_t(11-20j) == 1.0) - assert(l.point_to_t(0+1j) == None) - assert(l.point_to_t(0-1j) == None) - assert(l.point_to_t(0+11j) == None) - assert(l.point_to_t(10.001+0j) == None) - assert(l.point_to_t(-0.001-0j) == None) - - l = Line(start=(40.234-32.613j), end=(12.7-32.613j)) - assert(l.point_to_t(40.234-32.613j) == 0.0) - assert(np.isclose(l.point_to_t(33.3505-32.613j), 0.25)) - assert(np.isclose(l.point_to_t(26.467-32.613j), 0.50)) - assert(np.isclose(l.point_to_t(19.5835-32.613j), 0.75)) - assert(l.point_to_t(12.7-32.613j) == 1.0) - assert(l.point_to_t(40.25-32.613j) == None) - assert(l.point_to_t(12.65-32.613j) == None) - assert(l.point_to_t(11-20j) == None) - assert(l.point_to_t(0+1j) == None) - assert(l.point_to_t(0-1j) == None) - assert(l.point_to_t(0+11j) == None) - assert(l.point_to_t(10.001+0j) == None) - assert(l.point_to_t(-0.001-0j) == None) - - random.seed() - for line_index in range(100): - l = random_line() - print(l) - for t_index in range(100): - orig_t = random.random() - p = l.point(orig_t) - computed_t = l.point_to_t(p) - print("orig_t=%f, p=%s, computed_t=%f" % (orig_t, p, computed_t)) - assert(np.isclose(orig_t, computed_t)) - - - class CubicBezierTest(unittest.TestCase): def test_approx_circle(self): @@ -588,71 +478,6 @@ class ArcTest(unittest.TestCase): self.assertTrue(segment == Arc(0j, 100 + 50j, 0, 0, 0, 100 + 50j)) self.assertTrue(segment != Arc(0j, 100 + 50j, 0, 1, 0, 100 + 50j)) - def test_point_to_t(self): - a = Arc(start=(0+0j), radius=(5+5j), rotation=0.0, large_arc=True, sweep=True, end=(0+10j)) - assert(a.point_to_t(0+0j) == 0.0) - assert(np.isclose(a.point_to_t(5+5j), 0.5)) - assert(a.point_to_t(0+10j) == 1.0) - assert(a.point_to_t(-5+5j) == None) - assert(a.point_to_t(0+5j) == None) - assert(a.point_to_t(1+0j) == None) - assert(a.point_to_t(0-1j) == None) - assert(a.point_to_t(0+11j) == None) - - a = Arc(start=(0+0j), radius=(5+5j), rotation=0.0, large_arc=True, sweep=False, end=(0+10j)) - assert(a.point_to_t(0+0j) == 0.0) - assert(np.isclose(a.point_to_t(-5+5j), 0.5)) - assert(a.point_to_t(0+10j) == 1.0) - assert(a.point_to_t(5+5j) == None) - assert(a.point_to_t(0+5j) == None) - assert(a.point_to_t(1+0j) == None) - assert(a.point_to_t(0-1j) == None) - assert(a.point_to_t(0+11j) == None) - - a = Arc(start=(-10+0j), radius=(10+20j), rotation=0.0, large_arc=True, sweep=True, end=(10+0j)) - assert(a.point_to_t(-10+0j) == 0.0) - assert(np.isclose(a.point_to_t(0-20j), 0.5)) - assert(a.point_to_t(10+0j) == 1.0) - assert(a.point_to_t(0+20j) == None) - assert(a.point_to_t(-5+5j) == None) - assert(a.point_to_t(0+5j) == None) - assert(a.point_to_t(1+0j) == None) - assert(a.point_to_t(0-1j) == None) - assert(a.point_to_t(0+11j) == None) - - a = Arc(start=(100.834+27.987j), radius=(60.6+60.6j), rotation=0.0, large_arc=False, sweep=False, end=(40.234-32.613j)) - assert(a.point_to_t(100.834+27.987j) == 0.0) - assert(np.isclose(a.point_to_t(96.2210993246+4.7963831644j), 0.25)) - assert(np.isclose(a.point_to_t(83.0846703014-14.8636715784j), 0.50)) - assert(np.isclose(a.point_to_t(63.4246151671-28.0001000158j), 0.75)) - assert(a.point_to_t(40.234-32.613j) == 1.00) - assert(a.point_to_t(-10+0j) == None) - assert(a.point_to_t(0+0j) == None) - - a = Arc(start=(423.049961698-41.3779390229j), radius=(904.283878032+597.298520765j), rotation=0.0, large_arc=True, sweep=False, end=(548.984030235-312.385118044j)) - orig_t = 0.854049465076 - p = a.point(orig_t) - computed_t = a.point_to_t(p) - assert(np.isclose(orig_t, computed_t)) - - a = Arc(start=(-1-750j), radius=(750+750j), rotation=0.0, large_arc=True, sweep=False, end=1-750j) - assert(np.isclose(a.point_to_t(730.5212132777968+169.8191111892562j), 0.71373858)) - assert(a.point_to_t(730.5212132777968+169j) == None) - assert(a.point_to_t(730.5212132777968+171j) == None) - - random.seed() - for arc_index in range(100): - a = random_arc() - print(a) - for t_index in range(100): - orig_t = random.random() - p = a.point(orig_t) - computed_t = a.point_to_t(p) - print("t:", orig_t) - print("p:", p) - print("computed t:", computed_t) - assert(np.isclose(orig_t, computed_t)) - class TestPath(unittest.TestCase): @@ -1380,147 +1205,6 @@ class Test_intersect(unittest.TestCase): assert(abs(l0.point(i[0][0])-l1.point(i[0][1])) < 1e-9) - def test_arc_line(self): - l = Line(start=(-20+1j), end=(20+1j)) - a = Arc(start=(-10+0), radius=(10+10j), rotation=0.0, large_arc=True, sweep=False, end=(10+0j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 2) - - l = Line(start=(-20-1j), end=(20-1j)) - a = Arc(start=(-10+0), radius=(10+10j), rotation=0.0, large_arc=True, sweep=False, end=(10+0j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 0) - - l = Line(start=(-20+1j), end=(20+1j)) - a = Arc(start=(-10+0), radius=(10+10j), rotation=0.0, large_arc=True, sweep=True, end=(10+0j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 0) - - l = Line(start=(-20-1j), end=(20-1j)) - a = Arc(start=(-10+0), radius=(10+10j), rotation=0.0, large_arc=True, sweep=True, end=(10+0j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 2) - - l = Line(start=(-20+0j), end=(20+0j)) - a = Arc(start=(-10+0), radius=(10+10j), rotation=0.0, large_arc=True, sweep=True, end=(10+0j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 2) - - l = Line(start=(-20+0j), end=(20+0j)) - a = Arc(start=(-10+0), radius=(10+10j), rotation=0.0, large_arc=True, sweep=False, end=(10+0j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 2) - - l = Line(start=(-20+10j), end=(20+10j)) - a = Arc(start=(-10+0), radius=(10+10j), rotation=0.0, large_arc=True, sweep=False, end=(10+0j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 1) - - l = Line(start=(229.226097475-282.403591377j), end=(751.681212592+188.907748894j)) - a = Arc(start=(-1-750j), radius=(750+750j), rotation=0.0, large_arc=True, sweep=False, end=(1-750j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 1) - - # end of arc touches start of horizontal line - l = Line(start=(40.234-32.613j), end=(12.7-32.613j)) - a = Arc(start=(100.834+27.987j), radius=(60.6+60.6j), rotation=0.0, large_arc=False, sweep=False, end=(40.234-32.613j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 1) - - # vertical line, intersects half-arc once - l = Line(start=(1-100j), end=(1+100j)) - a = Arc(start=(10.0+0j), radius=(10+10j), rotation=0, large_arc=False, sweep=True, end=(-10.0+0j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 1) - - # vertical line, intersects nearly-full arc twice - l = Line(start=(1-100j), end=(1+100j)) - a = Arc(start=(0.1-10j), radius=(10+10j), rotation=0, large_arc=True, sweep=True, end=(-0.1-10j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 2) - - # vertical line, start of line touches end of arc - l = Line(start=(15.4+100j), end=(15.4+90.475j)) - a = Arc(start=(25.4+90j), radius=(10+10j), rotation=0, large_arc=False, sweep=True, end=(15.4+100j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 1) - - l = Line(start=(100-60.913j), end=(40+59j)) - a = Arc(start=(100.834+27.987j), radius=(60.6+60.6j), rotation=0.0, large_arc=False, sweep=False, end=(40.234-32.613j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 1) - - l = Line(start=(128.57143 + 380.93364j), end=(300.00001 + 389.505069j)) - a = Arc(start=(214.28572 + 598.07649j), radius=(85.714287 + 108.57143j), rotation=0.0, large_arc=False, sweep=True, end=(128.57143 + 489.50507j)) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, 0) - - random.seed() - for arc_index in range(50): - a = random_arc() - print(a) - for line_index in range(100): - l = random_line() - print(l) - intersections = a.intersect(l) - assert_intersections(a, l, intersections, None) - - - def test_intersect_arc_line_1(self): - - """Verify the return value of intersects() when an Arc ends at - the starting point of a Line.""" - - a = Arc(start=(0+0j), radius=(10+10j), rotation=0, large_arc=False, - sweep=False, end=(10+10j), autoscale_radius=False) - l = Line(start=(10+10j), end=(20+10j)) - - i = a.intersect(l) - assert(len(i) == 1) - assert(i[0][0] == 1.0) - assert(i[0][1] == 0.0) - - - def test_intersect_arc_line_2(self): - - """Verify the return value of intersects() when an Arc is pierced - once by a Line.""" - - a = Arc(start=(0+0j), radius=(10+10j), rotation=0, large_arc=False, - sweep=False, end=(10+10j), autoscale_radius=False) - l = Line(start=(0+9j), end=(20+9j)) - - i = a.intersect(l) - assert(len(i) == 1) - assert(i[0][0] >= 0.0) - assert(i[0][0] <= 1.0) - assert(i[0][1] >= 0.0) - assert(i[0][1] <= 1.0) - - - def test_intersect_arc_line_3(self): - - """Verify the return value of intersects() when an Arc misses - a Line, but the circle that the Arc is part of hits the Line.""" - - a = Arc(start=(0+0j), radius=(10+10j), rotation=0, large_arc=False, - sweep=False, end=(10+10j), autoscale_radius=False) - l = Line(start=(11+100j), end=(11-100j)) - - i = a.intersect(l) - assert(len(i) == 0) - - - def test_intersect_arc_line_disjoint_bboxes(self): - # The arc is very short, which contributes to the problem here. - l = Line(start=(125.314540561+144.192926144j), end=(125.798713132+144.510685287j)) - a = Arc(start=(128.26640649+146.908463323j), radius=(2+2j), - rotation=0, large_arc=False, sweep=True, - end=(128.26640606+146.90846449j)) - i = l.intersect(a) - assert(i == []) - - class TestPathTools(unittest.TestCase): # moved from test_pathtools.py