Skip to content

Commit

Permalink
fix: Remove absolute position effect from optimal bezier interpolatio…
Browse files Browse the repository at this point in the history
…n for consistent result
  • Loading branch information
miyanokomiya committed Nov 18, 2023
1 parent fe5500f commit f71d80c
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## [3.1.1] - 2023-11-18
### Fixed
- Remove absolute position effect from optimal bezier interpolation for consistent result

## [3.1.0] - 2023-11-17
### Added
- Optimal bezier interpolation
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "okageo",
"version": "3.1.0",
"version": "3.1.1",
"description": "parse SVG to polygons",
"main": "./dist/okageo.js",
"module": "./dist/okageo.mjs",
Expand Down
20 changes: 14 additions & 6 deletions src/geo.ts
Expand Up @@ -1631,17 +1631,25 @@ export function getBezierInterpolation(
const len = points.length
if (len < 3) return []

const A = solveBezierInterpolationEquations(points)
// This algorithm appears dependent on the absolute position of the line.
// => Remove the absolute position effect for consistency.
const origin = points[0]
const adjustedPoints = points.map((p) => sub(p, origin))

const A = solveBezierInterpolationEquations(adjustedPoints)
const B: IVec2[] = []
for (let i = 0; i < points.length - 2; i++) {
B[i] = sub(multi(points[i + 1], 2), A[i + 1])
for (let i = 0; i < adjustedPoints.length - 2; i++) {
B[i] = sub(multi(adjustedPoints[i + 1], 2), A[i + 1])
}
B[points.length - 2] = multi(
add(A[points.length - 2], points[points.length - 1]),
B[adjustedPoints.length - 2] = multi(
add(
A[adjustedPoints.length - 2],
adjustedPoints[adjustedPoints.length - 1]
),
1 / 2
)

return A.map((a, i) => [a, B[i]])
return A.map((a, i) => [add(a, origin), add(B[i], origin)])
}

/**
Expand Down
12 changes: 12 additions & 0 deletions test/geo.test.ts
Expand Up @@ -1983,4 +1983,16 @@ describe('getBezierInterpolation', () => {
expect(ret0[1][1].x).toBeCloseTo(10.385, 3)
expect(ret0[1][1].y).toBeCloseTo(5.769, 3)
})

it('should return bezier control points: non-zero origin', () => {
const ret0 = geo.getBezierInterpolation([
{ x: 1, y: 1 },
{ x: 11, y: 1 },
{ x: 11, y: 11 },
])
expect(ret0[0][0].x).toBeCloseTo(5.615, 3)
expect(ret0[0][0].y).toBeCloseTo(1 - 0.769, 3)
expect(ret0[1][1].x).toBeCloseTo(11.385, 3)
expect(ret0[1][1].y).toBeCloseTo(6.769, 3)
})
})

0 comments on commit f71d80c

Please sign in to comment.