I am struggling to convert an SVG curve, C
into a set of straight lines in Python
Syntax is C x1 y1, x2 y2, x y
Here is an example of what line should I get instead of the curve https://svg-path-visualizer.netlify.app/#M%2010%2010%20C%2020%2020%2C%2040%2020%2C%2050%2010%20M%2010%2010%20L%2020%2017%20L%2040%2017%20L%2050%2010
How to approximate the svg curve with a given set of lines?
get_cubic_bezier_point
returns a point on a Cubic Bezier curve, where t
is a curve parameter (0 to 1) and p
is a list of 4 curve points:
import numpy as np
def get_cubic_bezier_point(t, p):
multipliers = [
t * t * t,
3 * t * t * (1 - t),
3 * t * (1 - t) * (1 - t),
(1 - t) * (1 - t) * (1 - t)
]
x = 0
y = 0
for index in range(4):
x += p[index][0] * multipliers[index]
y += p[index][1] * multipliers[index]
return [x,y]
points = [
[10, 10],
[100, 250],
[150, -100],
[220, 140],
]
for t in np.arange(0, 1, 0.1):
point = get_cubic_bezier_point(t, points)
print(point)
Here is a JS snippet to illustrate a CB:
const points = [
{x: 10, y: 10},
{x: 100, y: 250},
{x: 150, y: -100},
{x: 220, y: 140}
];
const fp = i => `${points[i].x},${points[i].y}`;
d3.select('path').attr('d', `M ${fp(0)} C ${fp(1)} ${fp(2)} ${fp(3)}`);
const findCBPoint = t => {
const multipliers = [
t * t * t,
3 * t * t * (1 - t),
3 * t * (1 - t) * (1 - t),
(1 - t) * (1 - t) * (1 - t)
]
return multipliers.reduce((s, m, i) => ({
x: s.x + points[i].x * m,
y: s.y + points[i].y * m
}), {x: 0, y: 0});
}
for (let t = 0; t <= 1; t += 0.1) {
const p = findCBPoint(t);
console.log(p);
d3.select('svg').append('circle')
.attr('cx', p.x).attr('cy', p.y).attr('r', 3);
}
path {
stroke: red;
fill: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
<path/>
</svg>