Skip to content

Commit

Permalink
Merge pull request #216 from meerk40t/issue214
Browse files Browse the repository at this point in the history
Fixes Issue #214
  • Loading branch information
tatarize authored Mar 12, 2023
2 parents 61ac290 + e358531 commit 4e99223
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 7 deletions.
7 changes: 6 additions & 1 deletion svgelements/svgelements.py
Original file line number Diff line number Diff line change
Expand Up @@ -4787,7 +4787,12 @@ def _real_minmax(self, v):
if 0 < r2 < 1:
local_extremizers.append(r2)
else:
local_extremizers.append(0.5)
c = a[1] - a[0]
b = 2 * (a[0] - 2*a[1] + a[2])
if b != 0:
r0 = -c/b
if 0 < r0 < 1:
local_extremizers.append(r0)
local_extrema = [self.point(t)[v] for t in local_extremizers]
return min(local_extrema), max(local_extrema)

Expand Down
36 changes: 30 additions & 6 deletions test/test_cubic_bezier.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import random
import unittest
from random import *

from svgelements import *


def get_random_cubic_bezier():
return CubicBezier((random() * 50, random() * 50), (random() * 50, random() * 50),
(random() * 50, random() * 50), (random() * 50, random() * 50))
return CubicBezier(
(random() * 50, random() * 50),
(random() * 50, random() * 50),
(random() * 50, random() * 50),
(random() * 50, random() * 50),
)


class TestElementCubicBezierLength(unittest.TestCase):

def test_cubic_bezier_length(self):
n = 100
error = 0
Expand All @@ -25,18 +29,20 @@ def test_cubic_bezier_length(self):


class TestElementCubicBezierPoint(unittest.TestCase):

def test_cubic_bezier_point_start_stop(self):
import numpy as np

for _ in range(1000):
b = get_random_cubic_bezier()
self.assertEqual(b.start, b.point(0))
self.assertEqual(b.end, b.point(1))
self.assertTrue(np.all(np.array([list(b.start), list(b.end)])
== b.npoint([0, 1])))
self.assertTrue(
np.all(np.array([list(b.start), list(b.end)]) == b.npoint([0, 1]))
)

def test_cubic_bezier_point_implementations_match(self):
import numpy as np

for _ in range(1000):
b = get_random_cubic_bezier()

Expand All @@ -50,3 +56,21 @@ def test_cubic_bezier_point_implementations_match(self):
for p, p1, p2 in zip(pos, v1, v2):
self.assertEqual(b.point(p), Point(p1))
self.assertEqual(Point(p1), Point(p2))

def test_cubic_bounds_issue_214(self):
cubic = CubicBezier(0, -2 - 3j, -1 - 4j, -3j)
bbox = cubic.bbox()
self.assertLess(bbox[1], -3)

def test_cubic_bounds_issue_214_random(self):
for i in range(100):
a = random() * 5
b = random() * 5
c = random() * 5
d = a - 3 * b + 3 * c
cubic1 = CubicBezier(a, b, c, d)
bbox1 = cubic1.bbox()
cubic2 = CubicBezier(a, b, c, d + 1e-11)
bbox2 = cubic2.bbox()
for a, b in zip(bbox1, bbox2):
self.assertAlmostEqual(a, b, delta=1e-5)

0 comments on commit 4e99223

Please sign in to comment.