Python - 在贝塞尔曲线上均匀分布对象

时间:2013-04-28 13:12:24

标签: python math bezier

我已经阅读了有关此主题的所有内容,但我无法将部分代码翻译成我理解的简单python。

我得到了这个,基于de Casteljau算法的this very good explanation

def divideCurve(p0, cp0, cp1, p1, t):
    # p0 and p1 are the start/end points of the bezier curve,
    # cp0 and cp1 are the control points
    # all points are tuples of their coordinates: p0 = (10, 15)

    Ax = ( (1 - t) * p0[0] ) + (t * cp0[0])
    Ay = ( (1 - t) * p0[1] ) + (t * cp0[1])
    Bx = ( (1 - t) * cp0[0] ) + (t * cp1[0])
    By = ( (1 - t) * cp0[1] ) + (t * cp1[1])
    Cx = ( (1 - t) * cp1[0] ) + (t * p1[0])
    Cy = ( (1 - t) * cp1[1] ) + (t * p1[1])

    Dx = ( (1 - t) * Ax ) + (t * Bx)
    Dy = ( (1 - t) * Ay ) + (t * By)
    Ex = ( (1 - t) * Bx ) + (t * Cx)
    Ey = ( (1 - t) * By ) + (t * Cy)

    Px = ( (1 - t) * Dx ) + (t * Ex)
    Py = ( (1 - t) * Dy ) + (t * Ey)

    print Px, Py

for T in range(0, 11, 1):
    t = T*0.1
    divideCurve(p0, cp0, cp1, p1, t)

但是这会沿着曲线不均匀地分布点。

我认为here是一种可能的解决方案,但我完全不理解弧长函数的反转代码或如何将其转换为python。 我找到了另一种方法here,我认为它采用了一种不同的方法,我再也不了解它在python中实现了。

如果有人愿意将其简化为简单的python,那就太棒了。

1 个答案:

答案 0 :(得分:2)

开始:这是一个没有符号解决方案的问题,即你不能采用“length-for-t”函数(在 t 值...,曲线的长度是X)对于bezier曲线并将其反转,以便得到“t-for-length”(如果我是长度的......总长度的百分比是X, t 值是我的) 。因此,您将找到的所有实现都是主题的变体

  1. 确定完整的曲线长度,
  2. 确定沿曲线的各种 t 值的参考长度,
  3. 对于与参考值不完全匹配的值,找到它附近的两个 t 值并进行插值。
  4. 有些实现会使曲线变平(将贝塞尔曲线转换为直线序列),其他实现将构造一个t-distance-to-t查找表(LUT)。一些实现将在已知参考值之间进行线性插值(有效地模拟平坦曲线),其他实现将使用弧插值,将两个已知值之间的每个段近似为(圆弧)弧的一部分。对于所有这些实现,最重要的是您的里程将根据所做的选择而变化,但是所有这些都接近“实际”结果,您在连续 t 值之间的距离越小。< / p>

    最简单,通常也是最快的是在连续的 t 值之间构造一个“足够小”的LUT,然后甚至不用插值,而是选择 t 最接近实际长度的点。只要步长大小导致1px或更低的段长度,为了显示目的,你不需要比这更好的东西,因为更高的分辨率实际上不会导致“更好”的点,它们甚至会在相同的像素上如果你使你的距离参考点更精确。

    我有一个关于这个的描述,有代码,在http://pomax.github.io/bezierinfo/#tracing,它在Processing,而不是python,但Processing是一个非常简单的语言,并且考虑到算法描述,它应该相对简单直接到根据您已有的代码在Python中编写。