I have the following SVG path: M 0, 100 S 27, 2, 200 0
.
I'm trying to use the Bezier equations from here to convert the path into mathematical formulae.
When I try, I notice that the blue line (using the SVG path string) doesn't quite match the red line (which is drawn using the mathematical formulae).
Am I doing something wrong, such as not properly understanding how to extract control points from the SVG path?
let c = document.getElementById('c')
let ctx = c.getContext('2d')
ctx.strokeStyle = 'blue'
ctx.stroke(new Path2D(`M 0, 100 S 27, 2, 200 0`))
// bezier control points, derived from SVG path
let x1 = 0, y1 = 100,
x2 = 27, y2 = 2,
x3 = 200, y3 = 0
ctx.strokeStyle = 'red'
ctx.beginPath()
ctx.moveTo(x1, y1)
for(let t=0; t<=1; t+=0.0001) {
ctx.lineTo(
(1-t)**2 * x1 + 2*(1-t) * t * x2 + t**2 * x3,
(1-t)**2 * y1 + 2*(1-t) * t * y2 + t**2 * y3
)
}
ctx.stroke()
<canvas id="c" width="200" height="100"></canvas>
The 'S' path command will draw a cubic Bézier curve, but your code seems to be drawing a quadratic curve. If I read the SVG specs right (that’s a big "if", it’s not yet 7 in the morning here...), I think you need to repeat the (0, 100) point to get four points, and then generate a cubic curve from those.
Working code:
let c = document.getElementById('c')
let ctx = c.getContext('2d')
ctx.strokeStyle = 'blue'
ctx.stroke(new Path2D(`M 0, 100 S 27, 2, 200 0`))
// bezier control points, derived from SVG path
let x1 = 0, y1 = 100,
x2 = 0, y2 = 100,
x3 = 27, y3 = 2,
x4 = 200, y4 = 0
ctx.strokeStyle = 'red'
ctx.beginPath()
ctx.moveTo(x1, y1)
for(let t=0; t<=1; t+=0.0001) {
ctx.lineTo(
(1-t)**3 * x1 + 3*(1-t)**2 * t * x2 + 3*(1-t) * t**2 * x3 + t**3 * x4,
(1-t)**3 * y1 + 3*(1-t)**2 * t * y2 + 3*(1-t) * t**2 * y3 + t**3 * y4,
)
}
ctx.stroke()
<canvas id="c" width="200" height="100"></canvas>