Не уверен, что начинать с B-сплайна имеет смысл: сформировать кривую ромбовидного романа через точки (с виртуальными «до первого» и «после последнего», наложенными на реальные точки), а затем преобразовать это в кривую Безье, используя относительно тривиальное преобразование ?Например, учитывая ваши точки p0, p1 и p2, первый сегмент будет кривой скручивания {p2, p0, p1, p2} для сегмента p1 - p2, {p0, p1, p2, p0} даст p2--p0, и {p1, p2, p0, p1} приведут к p0 - p1.Затем вы тривиально конвертируете их, и теперь у вас есть SVG-путь.
В качестве демонстратора нажмите https://editor.p5js.org/ и вставьте следующий код:
var points = [{x:150, y:100 },{x:50, y:300 },{x:300, y:300 }];
// add virtual points:
points = points.concat(points);
function setup() {
createCanvas(400, 400);
tension = createSlider(1, 200, 100);
}
function draw() {
background(220);
points.forEach(p => ellipse(p.x, p.y, 4));
for (let n=0; n<3; n++) {
let [c1, c2, c3, c4] = points.slice(n,n+4);
let t = 0.06 * tension.value();
bezier(
// on-curve start point
c2.x, c2.y,
// control point 1
c2.x + (c3.x - c1.x)/t,
c2.y + (c3.y - c1.y)/t,
// control point 2
c3.x - (c4.x - c2.x)/t,
c3.y - (c4.y - c2.y)/t,
// on-curve end point
c3.x, c3.y
);
}
}
Что будет выглядеть следующим образомэто:
![](https://i.stack.imgur.com/ZRHBE.png)
Преобразование этого в код Python должно быть почти легким упражнением: для нас почти нет кода для написания =)
И, конечно,Теперь вы можете создать путь SVG, но это вряд ли проблема: теперь вы знаете все точки Безье, поэтому просто начните строить строку <path d=...>
, пока вы выполняете итерацию.