Bézier 曲线变成直线 SVG 线。如何转换?
Bézier Curves into straight SVG lines. How to convert?
我正在努力将 SVG 曲线 C
转换为 Python
中的一组直线
语法是C x1 y1, x2 y2, x y
这是我应该得到什么线而不是曲线的例子
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
如何用一组给定的线来近似 svg 曲线?
get_cubic_bezier_point
returns三次贝塞尔曲线上的一个点,其中t
是曲线参数(0到1),p
是4条曲线的列表积分:
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)
这是一个 JS 片段来说明 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>
我认为应该这样做:
function differ(no1, no2, no3,amount) {
return no1 + ((no2 - no1) * no3 / amount);
}
function linePointOnBezier(p1,p2,p3,p4,noOfLines) {
var t = 0;
var points = [];
for(var t = 0; t <= noOfLines; t++) {
var l2 = { //layer 2
p1: {
x: differ(p1.x, p2.x, t, noOfLines),
y: differ(p1.y, p2.y, t, noOfLines),
},
p2: {
x: differ(p2.x, p3.x, t, noOfLines),
y: differ(p2.y, p3.y, t, noOfLines),
},
p3: {
x: differ(p3.x, p4.x, t, noOfLines),
y: differ(p3.y, p4.y, t, noOfLines),
},
};
var l3 = { //layer 3
p1: {
x: differ(l2.p1.x, l2.p2.x, t, noOfLines),
y: differ(l2.p1.y, l2.p2.y, t, noOfLines),
},
p2: {
x: differ(l2.p2.x, l2.p3.x, t, noOfLines),
y: differ(l2.p2.y, l2.p3.y, t, noOfLines),
},
};
var point = [
differ(l3.p1.x, l3.p2.x, t, noOfLines),
differ(l3.p1.y, l3.p2.y, t, noOfLines),
];
points.push(point);
}
return points;
}
我正在努力将 SVG 曲线 C
转换为 Python
语法是C x1 y1, x2 y2, x y
这是我应该得到什么线而不是曲线的例子 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
如何用一组给定的线来近似 svg 曲线?
get_cubic_bezier_point
returns三次贝塞尔曲线上的一个点,其中t
是曲线参数(0到1),p
是4条曲线的列表积分:
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)
这是一个 JS 片段来说明 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>
我认为应该这样做:
function differ(no1, no2, no3,amount) {
return no1 + ((no2 - no1) * no3 / amount);
}
function linePointOnBezier(p1,p2,p3,p4,noOfLines) {
var t = 0;
var points = [];
for(var t = 0; t <= noOfLines; t++) {
var l2 = { //layer 2
p1: {
x: differ(p1.x, p2.x, t, noOfLines),
y: differ(p1.y, p2.y, t, noOfLines),
},
p2: {
x: differ(p2.x, p3.x, t, noOfLines),
y: differ(p2.y, p3.y, t, noOfLines),
},
p3: {
x: differ(p3.x, p4.x, t, noOfLines),
y: differ(p3.y, p4.y, t, noOfLines),
},
};
var l3 = { //layer 3
p1: {
x: differ(l2.p1.x, l2.p2.x, t, noOfLines),
y: differ(l2.p1.y, l2.p2.y, t, noOfLines),
},
p2: {
x: differ(l2.p2.x, l2.p3.x, t, noOfLines),
y: differ(l2.p2.y, l2.p3.y, t, noOfLines),
},
};
var point = [
differ(l3.p1.x, l3.p2.x, t, noOfLines),
differ(l3.p1.y, l3.p2.y, t, noOfLines),
];
points.push(point);
}
return points;
}