【问题标题】:Bézier Curves into straight SVG lines. How to convert?贝塞尔曲线成直线 SVG 线。如何转换?
【发布时间】:2021-06-10 10:05:27
【问题描述】:

我正在努力将 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 曲线?

【问题讨论】:

标签: python svg line bezier curve


【解决方案1】:

get_cubic_bezier_point 返回三次贝塞尔曲线上的一个点,其中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 sn-p 来说明一个 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>

【讨论】:

  • 请记住,如果您想从第一个点而不是最后一个点开始,您的函数需要从 (1-t)³ 到 t³,而不是相反。
【解决方案2】:

我认为应该这样做:

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-10
    • 1970-01-01
    • 2017-11-18
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    相关资源
    最近更新 更多