Skip to content

Commit

Permalink
fix: Fix invalid calculation of getPeriodicBezierInterpolation
Browse files Browse the repository at this point in the history
- `u` had extra value and it ruined the equations
  • Loading branch information
miyanokomiya committed Feb 28, 2024
1 parent 6ff2d33 commit c5c66ad
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 15 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## [3.1.6] - 2024-02-28
### Fixed
- Fix invalid calculation of `getPeriodicBezierInterpolation`

## [3.1.5] - 2024-02-27
### Fixed
- Fix invalid calculation of `getBezierInterpolation`
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "okageo",
"version": "3.1.5",
"version": "3.1.6",
"description": "parse SVG to polygons",
"main": "./dist/okageo.js",
"module": "./dist/okageo.mjs",
Expand Down
23 changes: 14 additions & 9 deletions src/geo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1702,7 +1702,7 @@ export function getPeriodicBezierInterpolation(
for (let i = 0; i < points.length - 2; i++) {
B[i] = sub(multi(points[i + 1], 2), A[i + 1])
}
B[points.length - 2] = sub(multi(points[0], 2), A[0])
B[points.length - 2] = sub(multi(points[points.length - 1], 2), A[0])

return A.map((a, i) => [a, B[i]])
}
Expand All @@ -1713,23 +1713,28 @@ export function getPeriodicBezierInterpolationA(points: IVec2[]): IVec2[] {

const values: IVec2[] = []
for (let i = 0; i < points.length - 1; i++) {
values.push(multi(add(multi(points[i], 2), points[i + 1]), 2))
values.push({
x: 4 * points[i].x + 2 * points[i + 1].x,
y: 4 * points[i].y + 2 * points[i + 1].y,
})
}
const y = solvePeriodicBezierInterpolationEquations(values, gamma)

const u = points.map(() => ({ x: 0, y: 0 }))
const u: IVec2[] = []
u[0] = { x: gamma, y: gamma }
u[paramSize - 1] = { x: 1, y: 1 }
for (let i = 1; i < points.length - 2; i++) {
u.push({ x: 0, y: 0 })
}
u.push({ x: 1, y: 1 })
const q = solvePeriodicBezierInterpolationEquations(u, gamma)

const v = u
const vy = {
x: v[0].x * y[0].x + v[paramSize - 1].x * y[paramSize - 1].x,
y: v[0].y * y[0].y + v[paramSize - 1].y * y[paramSize - 1].y,
x: y[0].x + (1 / gamma) * y[paramSize - 1].x,
y: y[0].y + (1 / gamma) * y[paramSize - 1].y,
}
const vq = {
x: v[0].x * q[0].x + v[paramSize - 1].x * q[paramSize - 1].x,
y: v[0].y * q[0].y + v[paramSize - 1].y * q[paramSize - 1].y,
x: q[0].x + (1 / gamma) * q[paramSize - 1].x,
y: q[0].y + (1 / gamma) * q[paramSize - 1].y,
}

const A: IVec2[] = []
Expand Down
31 changes: 26 additions & 5 deletions test/geo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2045,15 +2045,36 @@ describe('getPeriodicBezierInterpolation', () => {
const ret0 = geo.getPeriodicBezierInterpolation(points)
expect(ret0).toHaveLength(4)
expect(ret0[0][0].x).toBeCloseTo(2.5)
expect(ret0[0][0].y).toBeCloseTo(-2.583)
expect(ret0[0][0].y).toBeCloseTo(-2.5)
expect(ret0[0][1].x).toBeCloseTo(7.5)
expect(ret0[0][1].y).toBeCloseTo(-2.541)
expect(ret0[0][1].y).toBeCloseTo(-2.5)
expect(ret0[1][0].x).toBeCloseTo(12.5)
expect(ret0[1][0].y).toBeCloseTo(2.542)
expect(ret0[1][0].y).toBeCloseTo(2.5)
expect(ret0[1][1].x).toBeCloseTo(12.5)
expect(ret0[1][1].y).toBeCloseTo(7.583)
expect(ret0[1][1].y).toBeCloseTo(7.5)
expect(ret0[3][1].x).toBeCloseTo(-2.5)
expect(ret0[3][1].y).toBeCloseTo(2.583)
expect(ret0[3][1].y).toBeCloseTo(2.5)
})

it('should return bezier control points: non-zero origin', () => {
const points = [
{ x: 0, y: 0 },
{ x: 10, y: 0 },
{ x: 10, y: 10 },
{ x: 0, y: 10 },
{ x: 0, y: 0 },
]
const ret0 = geo.getPeriodicBezierInterpolation(points)
const origin = { x: 100, y: 200 }
const shift = geo.getPeriodicBezierInterpolation(
points.map((p) => geo.add(p, origin))
)
ret0.forEach(([c1, c2], i) => {
expect(c1.x).toBeCloseTo(shift[i][0].x - origin.x)
expect(c1.y).toBeCloseTo(shift[i][0].y - origin.y)
expect(c2.x).toBeCloseTo(shift[i][1].x - origin.x)
expect(c2.y).toBeCloseTo(shift[i][1].y - origin.y)
})
})
})

Expand Down

0 comments on commit c5c66ad

Please sign in to comment.