2015-01-06 155 views
2

美好的一天。我使用的是二次貝塞爾曲線具有以下配置:二次貝塞爾曲線:計算t給定x

開始點P1 =(1,2) 錨點P2 =(1,8) 終點P3 =(10,8)

我知道在給定的,我知道可以解決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,然後將該t插入到y方程中,並得到我的x和y點。

但是,我想自動找到t然後y。我有一個公式可以讓x和y給出t。但是,我沒有一個基於x的公式。我的代數有點生疏,擴展第一個方程來隔離t並不容易。

有沒有人有一個公式得到t基於x?截至目前,我的谷歌搜索技能已經失敗。

我認爲值得注意的是我的貝塞爾曲線正確。

任何幫助將非常感激。謝謝。

+0

作爲貝塞爾曲線是不是一個功能,你可以有一個'y'多個'x'和幾個'y'一個'x'協調。 – karatedog

+0

二次貝塞爾曲線是一個(參數)函數,除非它是一條直線,否則它最多與另一條線相交2點。我在下面給出了垂直線(x =常數)的交點的直接解決方案;它不工作? – dwn

回答

0

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

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

...其中...

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的解是否存在(即,是真實的,而不是複雜的),以及它們是什麼。

0

的問題是,你要解決什麼是不一般

  • 任何t功能只是一個(x,y)
  • 但對於任何x有可能的t
0,1,2,+inf解決方案

我會這樣做迭代

  • 你已經可以得到任何一點P(T)=貝塞爾(T)
  • 所以使用的t迭代,以儘量減少距離|p(t).x-x|

    1. for(t=0.0,dt=0.1;t<=1.0;t+=dt)
    2. 找到d=|p(t).x-x|

      所有本地分鐘
      • 因此當d開始再次上升
      • 設置dt*=-0.1
      • 停止,如果|dt|<1e-6或任何其他treshold
      • 停止,如果t超出區間<0,1>
      • 記得解決一些列表
      • 恢復原來的T,dt和重置本地分鐘搜索變量
    3. 過程中的所有本地分鐘

      • 消除所有具有更大的距離,然後一些treshold /精度
      • 計算y
      • 你需要用點什麼...

它會非常慢,然後代數的方法,但你可以使用這個任何曲率不只是二次方

  • 通常使用三次曲線,並做這個代數y隨他們來說是一個噩夢
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() 
+0

某種解釋會很有幫助。 – Huey