Skip to content

Commit 70b38d1

Browse files
authored
Merge pull request #85 from hfutrell/public-bernstein
Public bernstein
2 parents 00b7870 + ddb6ef5 commit 70b38d1

12 files changed

+367
-241
lines changed

BezierKit/BezierKit.xcodeproj/project.pbxproj

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@
4949
FD84360622B0091500AA90EF /* PathComponent+WindingCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD84360422B0091500AA90EF /* PathComponent+WindingCount.swift */; };
5050
FDA727591ED5035300011871 /* CubicCurveTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDA727581ED5035300011871 /* CubicCurveTests.swift */; };
5151
FDA7275A1ED5035300011871 /* CubicCurveTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDA727581ED5035300011871 /* CubicCurveTests.swift */; };
52+
FDB6011B25BB9B3700BAB067 /* BezierCurve+Polynomial.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB6011A25BB9B3700BAB067 /* BezierCurve+Polynomial.swift */; };
53+
FDB6011C25BB9B3700BAB067 /* BezierCurve+Polynomial.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB6011A25BB9B3700BAB067 /* BezierCurve+Polynomial.swift */; };
54+
FDB6012225BBA06600BAB067 /* BezierCurve+PolynomialTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB6012125BBA06600BAB067 /* BezierCurve+PolynomialTests.swift */; };
55+
FDB6012325BBA06600BAB067 /* BezierCurve+PolynomialTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB6012125BBA06600BAB067 /* BezierCurve+PolynomialTests.swift */; };
5256
FDB6B4021EAFD6DF00001C61 /* BezierCurve.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB6B3F71EAFD6DF00001C61 /* BezierCurve.swift */; };
5357
FDB6B4031EAFD6DF00001C61 /* BezierCurve.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB6B3F71EAFD6DF00001C61 /* BezierCurve.swift */; };
5458
FDB6B4041EAFD6DF00001C61 /* CubicCurve.swift in Sources */ = {isa = PBXBuildFile; fileRef = FDB6B3F81EAFD6DF00001C61 /* CubicCurve.swift */; };
@@ -170,6 +174,8 @@
170174
FD80FF8922B1CEE00018C592 /* LockTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LockTests.swift; sourceTree = "<group>"; };
171175
FD84360422B0091500AA90EF /* PathComponent+WindingCount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PathComponent+WindingCount.swift"; sourceTree = "<group>"; };
172176
FDA727581ED5035300011871 /* CubicCurveTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CubicCurveTests.swift; sourceTree = "<group>"; };
177+
FDB6011A25BB9B3700BAB067 /* BezierCurve+Polynomial.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BezierCurve+Polynomial.swift"; sourceTree = "<group>"; };
178+
FDB6012125BBA06600BAB067 /* BezierCurve+PolynomialTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BezierCurve+PolynomialTests.swift"; sourceTree = "<group>"; };
173179
FDB6B3F71EAFD6DF00001C61 /* BezierCurve.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BezierCurve.swift; sourceTree = "<group>"; };
174180
FDB6B3F81EAFD6DF00001C61 /* CubicCurve.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CubicCurve.swift; sourceTree = "<group>"; };
175181
FDB6B3F91EAFD6DF00001C61 /* Draw.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Draw.swift; sourceTree = "<group>"; };
@@ -279,6 +285,7 @@
279285
FD0F550A1DC43FFB0084CDCD /* Info.plist */,
280286
FD0F55081DC43FFB0084CDCD /* BezierKitTestHelpers.swift */,
281287
FDF0664D1FFA0C9900123308 /* BezierCurveTests.swift */,
288+
FDB6012125BBA06600BAB067 /* BezierCurve+PolynomialTests.swift */,
282289
FDE6CD8E1EC8F9BD00FAB479 /* LineSegmentTests.swift */,
283290
FDA727581ED5035300011871 /* CubicCurveTests.swift */,
284291
FD40244F2110CF5100FA723C /* QuadraticCurveTests.swift */,
@@ -326,6 +333,7 @@
326333
FD149EB92135CBFF009E791D /* AugmentedGraph.swift */,
327334
FDC859622119274A00AF7642 /* BoundingBoxHierarchy.swift */,
328335
FDB6B3F71EAFD6DF00001C61 /* BezierCurve.swift */,
336+
FDB6011A25BB9B3700BAB067 /* BezierCurve+Polynomial.swift */,
329337
FD5CF14B22400FCA00FE15A6 /* BezierCurve+Intersection.swift */,
330338
FDB6B3F81EAFD6DF00001C61 /* CubicCurve.swift */,
331339
FDB6B3FC1EAFD6DF00001C61 /* CGPoint+Overloads.swift */,
@@ -657,6 +665,7 @@
657665
FDB6B40F1EAFD6DF00001C61 /* PathComponent.swift in Sources */,
658666
FDB6B4151EAFD6DF00001C61 /* Utils.swift in Sources */,
659667
FDCE99A6223C404E00597989 /* Path+Data.swift in Sources */,
668+
FDB6011C25BB9B3700BAB067 /* BezierCurve+Polynomial.swift in Sources */,
660669
FDC2EB4B2298735C007768FC /* Lock.swift in Sources */,
661670
FDB6B4071EAFD6DF00001C61 /* Draw.swift in Sources */,
662671
FDB6B4131EAFD6DF00001C61 /* Types.swift in Sources */,
@@ -683,6 +692,7 @@
683692
FDB6B40E1EAFD6DF00001C61 /* PathComponent.swift in Sources */,
684693
FDB6B4141EAFD6DF00001C61 /* Utils.swift in Sources */,
685694
FDCE99A5223C404E00597989 /* Path+Data.swift in Sources */,
695+
FDB6011B25BB9B3700BAB067 /* BezierCurve+Polynomial.swift in Sources */,
686696
FDC2EB4A2298735C007768FC /* Lock.swift in Sources */,
687697
FDB6B4061EAFD6DF00001C61 /* Draw.swift in Sources */,
688698
FDB6B4121EAFD6DF00001C61 /* Types.swift in Sources */,
@@ -708,6 +718,7 @@
708718
FD12F1E22288CF6900404CE1 /* UtilsTests.swift in Sources */,
709719
FDA727591ED5035300011871 /* CubicCurveTests.swift in Sources */,
710720
FDB9D7331EB28CEB00413F0E /* BezierKit_iOSTests.swift in Sources */,
721+
FDB6012225BBA06600BAB067 /* BezierCurve+PolynomialTests.swift in Sources */,
711722
FD80FF8A22B1CEE00018C592 /* LockTests.swift in Sources */,
712723
FDE6CD8F1EC8F9BD00FAB479 /* LineSegmentTests.swift in Sources */,
713724
FD4024502110CF5100FA723C /* QuadraticCurveTests.swift in Sources */,
@@ -737,6 +748,7 @@
737748
FD12F1E32288CF6900404CE1 /* UtilsTests.swift in Sources */,
738749
FDA7275A1ED5035300011871 /* CubicCurveTests.swift in Sources */,
739750
FDB9D7421EB28D1900413F0E /* BezierKit_MacTests.swift in Sources */,
751+
FDB6012325BBA06600BAB067 /* BezierCurve+PolynomialTests.swift in Sources */,
740752
FD80FF8B22B1CEE00018C592 /* LockTests.swift in Sources */,
741753
FDE6CD901EC8F9BD00FAB479 /* LineSegmentTests.swift in Sources */,
742754
FD4024512110CF5100FA723C /* QuadraticCurveTests.swift in Sources */,
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//
2+
// BezierCurve+PolynomialTests.swift
3+
// BezierKit
4+
//
5+
// Created by Holmes Futrell on 1/22/21.
6+
// Copyright © 2021 Holmes Futrell. All rights reserved.
7+
//
8+
9+
import BezierKit
10+
import XCTest
11+
12+
class BezierCurve_PolynomialTests: XCTestCase {
13+
14+
func testPolynomialLineSegment() {
15+
let lineSegment = LineSegment(p0: CGPoint(x: 3, y: 4), p1: CGPoint(x: 5, y: 6))
16+
XCTAssertEqual(lineSegment.xPolynomial, BernsteinPolynomial1(b0: 3, b1: 5))
17+
XCTAssertEqual(lineSegment.yPolynomial, BernsteinPolynomial1(b0: 4, b1: 6))
18+
}
19+
20+
func testPolynomialQuadratic() {
21+
let quadratic = QuadraticCurve(p0: CGPoint(x: 1, y: 0),
22+
p1: CGPoint(x: 2, y: -2),
23+
p2: CGPoint(x: 3, y: -1))
24+
XCTAssertEqual(quadratic.xPolynomial, BernsteinPolynomial2(b0: 1, b1: 2, b2: 3))
25+
XCTAssertEqual(quadratic.yPolynomial, BernsteinPolynomial2(b0: 0, b1: -2, b2: -1))
26+
}
27+
28+
func testPolynomialCubic() {
29+
let cubic = CubicCurve(p0: CGPoint(x: 1, y: 0),
30+
p1: CGPoint(x: 2, y: 2),
31+
p2: CGPoint(x: 3, y: 1),
32+
p3: CGPoint(x: 4, y: -1))
33+
XCTAssertEqual(cubic.xPolynomial, BernsteinPolynomial3(b0: 1, b1: 2, b2: 3, b3: 4))
34+
XCTAssertEqual(cubic.yPolynomial, BernsteinPolynomial3(b0: 0, b1: 2, b2: 1, b3: -1))
35+
}
36+
37+
func testExtremaLine() {
38+
let l1 = LineSegment(p0: CGPoint(x: 1.0, y: 2.0), p1: CGPoint(x: 4.0, y: 6.0))
39+
let (x1, y1, all1) = l1.extrema()
40+
XCTAssertTrue(x1.isEmpty)
41+
XCTAssertTrue(y1.isEmpty)
42+
XCTAssertTrue(all1.isEmpty)
43+
44+
let l2 = LineSegment(p0: CGPoint(x: 1.0, y: 2.0), p1: CGPoint(x: 4.0, y: 2.0))
45+
let (x2, y2, all2) = l2.extrema()
46+
XCTAssertTrue(x2.isEmpty)
47+
XCTAssertTrue(y2.isEmpty)
48+
XCTAssertTrue(all2.isEmpty)
49+
}
50+
51+
func testExtremaQuadratic() {
52+
let f: [CGFloat] = [4, -2, 1] // f(t) = 4t^2 - 2t + 1, which has a local minimum at t = 0.25
53+
let g: [CGFloat] = [1, -4, 4] // g(t) = t^2 -4t + 4, which has a local minimum at t = 2 (outside parameter range)
54+
let q = BezierKitTestHelpers.quadraticCurveFromPolynomials(f, g)
55+
let (x, y, all) = q.extrema()
56+
XCTAssertEqual(all.count, 1)
57+
XCTAssertEqual(all[0], 0.25)
58+
XCTAssertEqual(x.count, 1)
59+
XCTAssertEqual(x[0], 0.25)
60+
XCTAssertTrue(y.isEmpty)
61+
}
62+
63+
func testExtremaCubic() {
64+
let f: [CGFloat] = [1, -1, 0, 0] // f(t) = t^3 - t^2, which has two local minimum at t=0, t=2/3 and an inflection point t=1/3
65+
let g: [CGFloat] = [0, 3, -2, 0] // g(t) = 3t^2 - 2t, which has a local minimum at t=1/3
66+
let c = BezierKitTestHelpers.cubicCurveFromPolynomials(f, g)
67+
let (x, y, all) = c.extrema()
68+
XCTAssertEqual(all.count, 3)
69+
XCTAssertEqual(all[0], 0.0)
70+
XCTAssertEqual(all[1], 1.0 / 3.0)
71+
XCTAssertEqual(all[2], 2.0 / 3.0)
72+
XCTAssertEqual(x[0], 0.0)
73+
XCTAssertEqual(x[1], 1.0 / 3.0)
74+
XCTAssertEqual(x[2], 2.0 / 3.0)
75+
XCTAssertEqual(y.count, 1)
76+
XCTAssertEqual(y[0], 1.0 / 3.0)
77+
}
78+
}

BezierKit/BezierKitTests/BezierKitTestHelpers.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ class BezierKitTestHelpers {
7676
return sum
7777
}
7878

79+
static func quadraticCurveFromPolynomials(_ f: [CGFloat], _ g: [CGFloat]) -> QuadraticCurve {
80+
precondition(f.count == 3 && g.count == 3)
81+
let curve = QuadraticCurve(p0: CGPoint(x: f[2], y: g[2]),
82+
p1: CGPoint(x: 0.5 * f[1] + f[2], y: 0.5 * g[1] + g[2]),
83+
p2: CGPoint(x: f[0] + f[1] + f[2], y: g[0] + g[1] + g[2]))
84+
return curve
85+
}
86+
7987
static func cubicCurveFromPolynomials(_ f: [CGFloat], _ g: [CGFloat]) -> CubicCurve {
8088
precondition(f.count == 4 && g.count == 4)
8189
// create a cubic bezier curve from two polynomials
@@ -89,12 +97,7 @@ class BezierKitTestHelpers {
8997
let b = r / 3.0 + a
9098
let c = q / 3.0 + 2.0 * b - a
9199
let d = p + a - 3.0 * b + 3.0 * c
92-
// check that it worked
93-
let curve = CubicCurve(p0: a, p1: b, p2: c, p3: d)
94-
for t: CGFloat in stride(from: 0, through: 1, by: 0.1) {
95-
assert(distance(curve.point(at: t), CGPoint(x: evaluatePolynomial(f, at: t), y: evaluatePolynomial(g, at: t))) < 0.001, "internal error! failed to fit polynomial!")
96-
}
97-
return curve
100+
return CubicCurve(p0: a, p1: b, p2: c, p3: d)
98101
}
99102

100103
static func isSatisfactoryReduceResult<A>(_ result: [Subcurve<A>], for curve: A) -> Bool {

BezierKit/BezierKitTests/CubicCurveTests.swift

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -250,22 +250,6 @@ class CubicCurveTests: XCTestCase {
250250
XCTAssertEqual(c1.length(), 5.0, accuracy: epsilon)
251251
}
252252

253-
func testExtrema() {
254-
let f: [CGFloat] = [1, -1, 0, 0] // f(t) = t^3 - t^2, which has two local minimum at t=0, t=2/3 and an inflection point t=1/3
255-
let g: [CGFloat] = [0, 3, -2, 0] // g(t) = 3t^2 - 2t, which has a local minimum at t=1/3
256-
let c = BezierKitTestHelpers.cubicCurveFromPolynomials(f, g)
257-
let (x, y, all) = c.extrema()
258-
XCTAssertEqual(all.count, 3)
259-
XCTAssertEqual(all[0], 0.0)
260-
XCTAssertEqual(all[1], 1.0 / 3.0)
261-
XCTAssertEqual(all[2], 2.0 / 3.0)
262-
XCTAssertEqual(x[0], 0.0)
263-
XCTAssertEqual(x[1], 1.0 / 3.0)
264-
XCTAssertEqual(x[2], 2.0 / 3.0)
265-
XCTAssertEqual(y.count, 1)
266-
XCTAssertEqual(y[0], 1.0 / 3.0)
267-
}
268-
269253
func testProject() {
270254
let epsilon: CGFloat = 1.0e-5
271255
// test a cubic

BezierKit/BezierKitTests/LineSegmentTests.swift

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,6 @@ class LineSegmentTests: XCTestCase {
100100
XCTAssertEqual(l.length(), 5.0)
101101
}
102102

103-
func testExtrema() {
104-
let l = LineSegment(p0: CGPoint(x: 1.0, y: 2.0), p1: CGPoint(x: 4.0, y: 6.0))
105-
let (x, y, all) = l.extrema()
106-
XCTAssertTrue(x.isEmpty)
107-
XCTAssertTrue(y.isEmpty)
108-
XCTAssertTrue(all.isEmpty)
109-
}
110-
111103
func testProject() {
112104
let l = LineSegment(p0: CGPoint(x: 1.0, y: 2.0), p1: CGPoint(x: 5.0, y: 6.0))
113105
let p1 = l.project(CGPoint(x: 0.0, y: 0.0)) // should project to p0

BezierKit/BezierKitTests/PolynomialTests.swift

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,73 +11,83 @@ import XCTest
1111

1212
class PolynomialTests: XCTestCase {
1313

14-
let accuracy = 1.0e-5
14+
let accuracy: CGFloat = 1.0e-5
1515

1616
func testEvaluation() {
1717
let point = BernsteinPolynomial0(b0: 3.0)
1818
XCTAssertEqual(point.reduce(a1: 1, a2: 2), 0)
19-
XCTAssertEqual(point.f(0), 3)
20-
XCTAssertEqual(point.f(0.5), 3)
21-
XCTAssertEqual(point.f(1), 3)
19+
XCTAssertEqual(point.value(at: 0), 3)
20+
XCTAssertEqual(point.value(at: 0.5), 3)
21+
XCTAssertEqual(point.value(at: 1), 3)
2222
XCTAssertEqual(point.derivative, BernsteinPolynomial0(b0: 0.0))
23-
XCTAssertEqual(point.analyticalRoots(between: 0, and: 1), [])
23+
XCTAssertEqual(point.distinctAnalyticalRoots(between: 0, and: 1), [])
2424
XCTAssertEqual(point.coefficients, [3.0])
2525

2626
let line = BernsteinPolynomial1(b0: 2.0, b1: 4.0)
27-
XCTAssertEqual(line.f(0), 2)
28-
XCTAssertEqual(line.f(0.5), 3)
29-
XCTAssertEqual(line.f(1), 4)
27+
XCTAssertEqual(line.value(at: 0), 2)
28+
XCTAssertEqual(line.value(at: 0.5), 3)
29+
XCTAssertEqual(line.value(at: 1), 4)
3030
XCTAssertEqual(line.derivative, BernsteinPolynomial0(b0: 2))
31-
XCTAssertEqual(line.analyticalRoots(between: -2, and: 1), [-1])
32-
XCTAssertEqual(line.analyticalRoots(between: 0, and: 1), [])
31+
XCTAssertEqual(line.distinctAnalyticalRoots(between: -2, and: 1), [-1])
32+
XCTAssertEqual(line.distinctAnalyticalRoots(between: 0, and: 1), [])
3333
XCTAssertEqual(line.coefficients, [2, 4])
3434

3535
let quad = BernsteinPolynomial2(b0: -1, b1: 1.0, b2: 0.0)
36-
XCTAssertEqual(quad.f(0), -1)
37-
XCTAssertEqual(quad.f(0.5), 0.25)
38-
XCTAssertEqual(quad.f(1), 0)
36+
XCTAssertEqual(quad.value(at: 0), -1)
37+
XCTAssertEqual(quad.value(at: 0.5), 0.25)
38+
XCTAssertEqual(quad.value(at: 1), 0)
3939
XCTAssertEqual(quad.derivative, BernsteinPolynomial1(b0: 4, b1: -2))
4040
XCTAssertEqual(quad.coefficients, [-1, 1, 0])
4141
}
4242

4343
func testDegree1() {
4444
let polynomial = BernsteinPolynomial1(b0: -3, b1: 2)
45-
let roots = findRoots(of: polynomial, between: -1, and: 1)
45+
let roots = findDistinctRoots(of: polynomial, between: -1, and: 1)
4646
XCTAssertEqual(roots.count, 1)
47-
XCTAssertEqual(roots[0], 0.6, accuracy: accuracy)
47+
XCTAssertEqual(roots[0], CGFloat(0.6), accuracy: accuracy)
4848
}
4949

5050
func testDegree2() {
5151
let polynomial = BernsteinPolynomial2(b0: -5, b1: -6, b2: -4)
52-
let roots = findRoots(of: polynomial, between: -10, and: 10)
52+
let roots = findDistinctRoots(of: polynomial, between: -10, and: 10)
5353
XCTAssertEqual(roots[0], -1, accuracy: accuracy)
5454
XCTAssertEqual(roots[1], 1.0 + 2.0 / 3.0, accuracy: accuracy)
5555
}
5656

5757
func testDegree3() {
5858
// x^3 - 6x^2 + 11x - 6
5959
let polynomial = BernsteinPolynomial3(b0: -6, b1: -7.0 / 3.0, b2: -2.0 / 3.0, b3: 0)
60-
XCTAssertEqual(polynomial.coefficients, [-6, -7.0 / 3.0, -2.0 / 3.0, 0.0])
61-
let roots = findRoots(of: polynomial, between: 0, and: 4)
60+
XCTAssertEqual(polynomial.coefficients, [-6, CGFloat(-7.0 / 3.0), CGFloat(-2.0 / 3.0), 0.0])
61+
let roots = findDistinctRoots(of: polynomial, between: 0, and: 4)
6262
XCTAssertEqual(roots[0], 1, accuracy: accuracy)
6363
XCTAssertEqual(roots[1], 2, accuracy: accuracy)
6464
XCTAssertEqual(roots[2], 3, accuracy: accuracy)
6565
}
6666

67-
func testDegree3RepeatedRoot() {
67+
func testDegree3RepeatedRoot1() {
6868
// x^3 - 4x^2 + 5x - 2
6969
// repeated root at x = 1
7070
let polynomial = BernsteinPolynomial3(b0: -2, b1: -1.0 / 3.0, b2: 0, b3: 0)
71-
let roots = findRoots(of: polynomial, between: -1, and: 3)
71+
let roots = findDistinctRoots(of: polynomial, between: -1, and: 3)
7272
XCTAssertEqual(roots[0], 1, accuracy: accuracy)
7373
XCTAssertEqual(roots[1], 2, accuracy: accuracy)
7474
}
7575

76+
// func testDegree3RootExactlyZero() {
77+
// // root is exactly t = 0 (at the start of unit interval),
78+
// // so may be accidentally discarded due to numerical precision
79+
// let polynomial = BernsteinPolynomial3(b0: 0, b1: 96, b2: -24, b3: -36)
80+
// let roots = findRoots(of: polynomial, between: 0, and: 1)
81+
// XCTAssertEqual(roots.count, 2)
82+
// XCTAssertEqual(roots[0], 0.0)
83+
// XCTAssertEqual(roots[1], 2.0 / 3.0, accuracy: accuracy)
84+
// }
85+
7686
func testDegree4() {
7787
// x^4 - 2.44x^2 + 1.44
78-
let polynomial = BernsteinPolynomial4(b0: 1.44, b1: 1.44, b2: 1.44 - 1.22 / 3, b3: 0.22, b4: 0)
79-
XCTAssertEqual(polynomial.coefficients, [1.44, 1.44, 1.44 - 1.22 / 3, 0.22, 0])
80-
let roots = findRoots(of: polynomial, between: -2, and: 2)
88+
let polynomial = BernsteinPolynomial4(b0: 1.44, b1: 1.44, b2: CGFloat(1.44 - 1.22 / 3), b3: 0.22, b4: 0)
89+
XCTAssertEqual(polynomial.coefficients, [1.44, 1.44, CGFloat(1.44 - 1.22 / 3), 0.22, 0])
90+
let roots = findDistinctRoots(of: polynomial, between: -2, and: 2)
8191
XCTAssertEqual(roots[0], -1.2, accuracy: accuracy)
8292
XCTAssertEqual(roots[1], -1, accuracy: accuracy)
8393
XCTAssertEqual(roots[2], 1, accuracy: accuracy)
@@ -87,7 +97,7 @@ class PolynomialTests: XCTestCase {
8797
func testDegree4RepeatedRoots() {
8898
// x^4 - 2x^2 + 1
8999
let polynomial = BernsteinPolynomial4(b0: 1, b1: 1, b2: 2.0 / 3.0, b3: 0, b4: 0)
90-
let roots = findRoots(of: polynomial, between: -2, and: 2)
100+
let roots = findDistinctRoots(of: polynomial, between: -2, and: 2)
91101
XCTAssertEqual(roots.count, 2)
92102
XCTAssertEqual(roots[0], -1, accuracy: accuracy)
93103
XCTAssertEqual(roots[1], 1, accuracy: accuracy)
@@ -97,16 +107,15 @@ class PolynomialTests: XCTestCase {
97107
// 0.2x^5 - 0.813333x^3 - 8.56x
98108
let polynomial = BernsteinPolynomial5(b0: 0, b1: -1.712, b2: -3.424, b3: -5.2173333, b4: -7.1733332, b5: -9.173333)
99109
XCTAssertEqual(polynomial.coefficients, [0, -1.712, -3.424, -5.2173333, -7.1733332, -9.173333])
100-
let roots = findRoots(of: polynomial, between: -4, and: 4)
101-
XCTAssertEqual(polynomial.analyticalRoots(between: -5, and: 5), nil, "shouldn't be possible to solve analytically")
110+
let roots = findDistinctRoots(of: polynomial, between: -4, and: 4)
102111
XCTAssertEqual(roots[0], -2.9806382, accuracy: accuracy)
103112
XCTAssertEqual(roots[1], 0, accuracy: accuracy)
104113
XCTAssertEqual(roots[2], 2.9806382, accuracy: accuracy)
105114
}
106115

107116
func testDegree4RealWorldIssue() {
108117
let polynomial = BernsteinPolynomial4(b0: 1819945.4373168945, b1: -3353335.8194732666, b2: 3712712.6330566406, b3: -2836657.1703338623, b4: 2483314.5947265625)
109-
let roots = findRoots(of: polynomial, between: 0, and: 1)
118+
let roots = findDistinctRootsInUnitInterval(of: polynomial)
110119
XCTAssertEqual(roots.count, 2)
111120
XCTAssertEqual(roots[0], 0.15977874432923783, accuracy: 1.0e-5)
112121
XCTAssertEqual(roots[1], 0.407811682610126, accuracy: 1.0e-5)

BezierKit/BezierKitTests/QuadraticCurveTests.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@ class QuadraticCurveTests: XCTestCase {
100100
// func testLength() {
101101
// }
102102
//
103-
// func testExtrema() {
104-
// }
105103

106104
func testProject() {
107105
let epsilon: CGFloat = 1.0e-5

0 commit comments

Comments
 (0)