Skip to content

Commit

Permalink
Merge pull request #43 from meerk40t/1.1.2
Browse files Browse the repository at this point in the history
Corrections for near collinear quads
  • Loading branch information
tatarize authored Jun 14, 2020
2 parents 1df672c + 6864a9e commit a3841e5
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 13 deletions.
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = svgelements
version = 1.1.1
version = 1.1.2
description = Svg Elements Parsing
long_description_content_type=text/markdown
long_description = file: README.md
Expand Down
22 changes: 11 additions & 11 deletions svgelements/svgelements.py
Original file line number Diff line number Diff line change
Expand Up @@ -3308,17 +3308,7 @@ def length(self, error=None, min_depth=None):
"""Calculate the length of the path up to a certain position"""
a = self.start - 2 * self.control + self.end
b = 2 * (self.control - self.start)
a_dot_b = a.real * b.real + a.imag * b.imag

if abs(a) < 1e-12:
s = abs(b)
elif abs(a_dot_b + abs(a) * abs(b)) < 1e-12:
k = abs(b) / abs(a)
if k >= 2:
s = abs(b) - abs(a)
else:
s = abs(a) * (k ** 2 / 2 - k + 1)
else:
try:
# For an explanation of this case, see
# http://www.malczak.info/blog/quadratic-bezier-curve-length/
A = 4 * (a.real ** 2 + a.imag ** 2)
Expand All @@ -3333,6 +3323,16 @@ def length(self, error=None, min_depth=None):

s = (A32 * Sabc + A2 * B * (Sabc - C2) + (4 * C * A - B ** 2) *
log((2 * A2 + BA + Sabc) / (BA + C2))) / (4 * A32)
except (ZeroDivisionError, ValueError):
# a_dot_b = a.real * b.real + a.imag * b.imag
if abs(a) < 1e-10:
s = abs(b)
else:
k = abs(b) / abs(a)
if k >= 2:
s = abs(b) - abs(a)
else:
s = abs(a) * (k ** 2 / 2 - k + 1)
return s

def is_smooth_from(self, previous):
Expand Down
3 changes: 2 additions & 1 deletion test/test_angle.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


class TestElementAngle(unittest.TestCase):
"""These tests ensure the basic functions of the Angle element."""

def test_angle_init(self):
self.assertEqual(Angle.degrees(90).as_turns, 0.25)
Expand Down Expand Up @@ -40,4 +41,4 @@ def test_orth(self):
self.assertFalse(Angle.degrees(91).is_orthogonal())
self.assertFalse(Angle.degrees(181).is_orthogonal())
self.assertFalse(Angle.degrees(271).is_orthogonal())
self.assertFalse(Angle.degrees(361).is_orthogonal())
self.assertFalse(Angle.degrees(361).is_orthogonal())
1 change: 1 addition & 0 deletions test/test_color.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


class TestElementColor(unittest.TestCase):
"""These tests test the basic functions of the Color element."""

def test_color_red(self):
r0 = Color('red')
Expand Down
1 change: 1 addition & 0 deletions test/test_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


class TestElementElement(unittest.TestCase):
"""These tests ensure the performance of the SVGElement basecase."""

def test_element_id(self):
values = {'id': 'my_id', 'random': True}
Expand Down
1 change: 1 addition & 0 deletions test/test_length.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


class TestElementLength(unittest.TestCase):
"""Tests the functionality of the Length Element."""

def test_length_parsing(self):
self.assertAlmostEqual(Length('10cm'), (Length('100mm')))
Expand Down
1 change: 1 addition & 0 deletions test/test_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


class TestPathMatrix(unittest.TestCase):
"""Tests the functionality of the Matrix element."""

def test_rotate_css_angles(self):
matrix = Matrix("rotate(90, 100,100)")
Expand Down
1 change: 1 addition & 0 deletions test/test_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


class TestPath(unittest.TestCase):
"""Tests of the SVG Path element."""

def test_subpaths(self):
path = Path("M0,0 50,50 100,100z M0,100 50,50, 100,0")
Expand Down
1 change: 1 addition & 0 deletions test/test_path_dunder.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


class TestPath(unittest.TestCase):
"""Tests of dunder methods of the SVG Path element."""

def test_path_iadd_str(self):
p1 = Path("M0,0")
Expand Down
22 changes: 22 additions & 0 deletions test/test_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
# these points religiously. They might be subtly wrong, unless otherwise
# noted.


class LineTest(unittest.TestCase):

def test_lines(self):
Expand Down Expand Up @@ -291,6 +292,9 @@ def test_equality(self):
CubicBezier(600 + 501j, 600 + 350j, 900 + 650j, 900 + 500j))
self.assertTrue(segment != Line(0, 400))

def test_colinear(self):
p = Path("M0,0C5,0 15,0 15,0")
self.assertAlmostEqual(p.length(), 15)

class QuadraticBezierTest(unittest.TestCase):

Expand Down Expand Up @@ -340,6 +344,24 @@ def test_equality(self):
self.assertFalse(segment == Arc(0j, 100 + 50j, 0, 0, 0, 100 + 50j))
self.assertTrue(Arc(0j, 100 + 50j, 0, 0, 0, 100 + 50j) != segment)

def test_issue_61(self):
p = Path('M 206.5,525 Q 162.5,583 162.5,583')
self.assertAlmostEqual(p.length(), 72.80109889280519)
p = Path('M 425.781 446.289 Q 410.40000000000003 373.047 410.4 373.047')
self.assertAlmostEqual(p.length(), 74.83959997888816)
p = Path('M 639.648 568.115 Q 606.6890000000001 507.568 606.689 507.568')
self.assertAlmostEqual(p.length(), 68.93645544992873)
p = Path('M 288.818 616.699 Q 301.025 547.3629999999999 301.025 547.363')
self.assertAlmostEqual(p.length(), 70.40235610403947)
p = Path('M 339.927 706.25 Q 243.92700000000002 806.25 243.927 806.25')
self.assertAlmostEqual(p.length(), 138.6217876093077)
p = Path('M 539.795 702.637 Q 548.0959999999999 803.4669999999999 548.096 803.467')
self.assertAlmostEqual(p.length(), 101.17111989594662)
p = Path('M 537.815 555.042 Q 570.1680000000001 499.1600000000001 570.168 499.16')
self.assertAlmostEqual(p.length(), 64.57177814649368)
p = Path('M 615.297 470.503 Q 538.797 694.5029999999999 538.797 694.503')
self.assertAlmostEqual(p.length(), 236.70287281737836)


class ArcTest(unittest.TestCase):

Expand Down

0 comments on commit a3841e5

Please sign in to comment.