二次贝塞尔曲线:计算给定的x

时间:2015-01-06 04:02:57

标签: math point bezier

美好的一天。我正在使用具有以下配置的二次贝塞尔曲线:

起点P1 =(1,2) 锚点P2 =(1,8) 终点P3 =(10,8)

我知道给定t,我知道我可以使用以下等式求解x和y:

t = 0.5; // given example value
x = (1 - t) * (1 - t) * P1.x + 2 * (1 - t) * t * P2.x + t * t * P3.x;
y = (1 - t) * (1 - t) * P1.y + 2 * (1 - t) * t * P2.y + t * t * P3.y;

其中P1.x是P1的x坐标,依此类推。

我现在尝试的是,给定一个x值,我使用wolframalpha计算t,然后我将其插入y方程式,得到我的x和y点。

但是,我想自动查找t然后y。我有一个公式来得到x和y给出一个t。但是,我没有基于x得到t的公式。我的代数有点生疏,扩展第一个方程式以隔离t看起来并不太容易。

有没有人有基于x的公式?截至目前,我的谷歌搜索技能让我失望。

我认为值得注意的是我的Bezier曲线正对。

非常感谢任何帮助。感谢。

3 个答案:

答案 0 :(得分:1)

问题是你要解决的问题一般不是函数

    任何t
  • 只是一个(x,y)
  • 但对于任何x0,1,2,+inf
  • 可以有t个解决方案

我会迭代地执行此操作

你已经可以得到任何一点p(t)=Bezier(t)所以使用t的迭代来最小化距离|p(t).x-x|

  1. for(t=0.0,dt=0.1;t<=1.0;t+=dt)
  2. 查找min

    的所有本地d=|p(t).x-x|

    所以当d再次开始上升时设置dt*=-0.1并停止|dt|<1e-6或任何其他阈值。如果t超出间隔<0,1>,请停止并记住某些列表的解决方案。恢复原始t,dt并重置本地最小搜索变量

  3. 处理所有本地min s

    消除距离较大的所有距离,然后计算y一些阈值/精度,并根据要点做你需要的......

  4. 它比代数方法慢得多,但你可以将它用于任何曲率而不仅仅是二次

    通常使用三次曲线,并用它们代数地做这是一场噩梦。

答案 1 :(得分:0)

看看你的伯恩斯坦多项式B [i];你有......

x = SUM_i ( B[i](t) * P[i].x )

... WHERE ...

B[0](t) = t^2 - 2*t + 1
B[1](t) = -2*t^2 + 2*t
B[2](t) = t^2

...所以你可以重新安排(假设我这样做了)......

0 = (P[0].x - 2*P[1].x + P[2].x) * t^2 + (-2*P[0].x + 2*P[1].x) * t + P[0].x - x

现在你应该能够使用二次公式来确定t的解是否存在(即,是真实的,不是复杂的),以及它们是什么。

答案 2 :(得分:0)

import numpy as np
import matplotlib.pyplot as plt
#Control points
p0=(1000,2500); p1=(2000,-1500); p2=(5000,3000)
#x-coordinates to fit
xcoord = [1750., 2750., 3950.,4760., 4900.]

# t variable with as few points as needed, considering accuracy. I found 30 is good enough 
t = np.linspace(0,1,30)

# calculate coordinates of quadratic Bezier curve
x = (1 - t) * (1 - t) * p0[0] + 2 * (1 - t) * t * p1[0] + t * t * p2[0];
y = (1 - t) * (1 - t) * p0[1] + 2 * (1 - t) * t * p1[1] + t * t * p2[1];

# find the closest points to each x-coordinate. Interpolate y-coordinate
ycoord=[]
for ind in xcoord:
    for jnd in range(len(x[:-1])):
        if ind >= x[jnd] and ind <= x[jnd+1]:
            ytemp = (ind-x[jnd])*(y[jnd+1]-y[jnd])/(x[jnd+1]-x[jnd]) + y[jnd]
            ycoord.append(ytemp)


plt.figure()
plt.xlim(0, 6000)
plt.ylim(-2000, 4000)
plt.plot(p0[0],p0[1],'kx', p1[0],p1[1],'kx', p2[0],p2[1],'kx')
plt.plot((p0[0],p1[0]),(p0[1],p1[1]),'k:', (p1[0],p2[0]),(p1[1],p2[1]),'k:')
plt.plot(x,y,'r', x, y, 'k:')
plt.plot(xcoord, ycoord, 'rs')
plt.show()