我找到了一个forum question ...
Function intersectBezier3Line(x1#,y1#,vx1#,vy1#,x2#,y2#,vx2#,vy2#,L1x#,L1y#,L2x#,L2y#)
Local A#,B#,C#,E#,F#,G#,La#,Lb#,Lc#,Solution#
A=3*vx1+x2-(3*vx2)-x1
B=3*x1-(6*vx1)+(3*vx2)
C=3*vx1-(3*x1)
E=3*vy1+y2-(3*vy2)-y1
F=3*y1-(6*vy1)+(3*vy2)
G=3*vy1-(3*y1)
La=L2y-L1y
Lb=L1x-L2x
Lc=L1y*(L2x-L1x) + L1x*(L1y-L2y)
ax(4)=La*x1 + Lb*y1 + Lc
ax(3)=La*C + Lb*G
ax(2)=La*B + Lb*F
ax(1)=La*A + Lb*E
FindRootsPoly3(ax(4),ax(3),ax(2),ax(1))
End Function
Function FindRootsPoly3(A3#,A2#,A1#,A0#)
Local fc2#,gc2#,hc2#,Rc2#,Sc2#,Tc2#,Uc2#,ic2#,jc2#,kc2#,Lc2#,Mc2#,Nc2#,Pc2#
fc2 =( (3*A1/A3) - ((A2^2)/(A3^2) ))/ 3
gc2=(( (2*A2^3)/(A3^3)) - (9*A2*A1/(A3^2)) + (27*A0/A3)) / 27
hc2 = ((gc2^2)/4) + ((fc2^3)/27)
If hc2>0 Then
Rc2 = -(gc2/2) + (Sqr(hc2))
If Rc2<0 Then
Sc2 = -(Abs(Rc2)^0.333333)
Else
Sc2 = ((Rc2))^0.333333
EndIf
Tc2 = -(gc2/2) -( Sqr(hc2))
If Tc2<0 Then
Uc2 = -(Abs(Tc2)^0.333333)
Else
Uc2 = (Tc2)^0.333333
EndIf
Rx(0) = (Sc2 + Uc2) - (A2/(3*A3))
Else
If hc2=0 And gc2=0 And fc2=0 Then
Rx(0) =-((A0/A3)^0.3333333 )
Else
If hc2<0 Or hc2=0 Then
ic2= Sqr(((gc2^2)/4) - hc2)
jc2 = (ic2)^0.333333
kc2 = ACos (- (gc2 / (2*ic2)))
Lc2 = -jc2
Mc2 = Cos (kc2/3)
Nc2 = Sqr( 3) * Sin (kc2/3)
Pc2 = -(A2/(3*A3))
Rx(0) = 2*jc2 * Cos(kc2/3) -(A2/(3*A3))
Rx(1) = Lc2 * (Mc2 + Nc2) + Pc2
Rx(2) = Lc2 * (Mc2 - Nc2) + Pc2
EndIf
EndIf
EndIf
End Function
我希望以某种方式输出直线和贝塞尔曲线之间的交点。我翻译成coffeescript
intersectBezier3Line = (x1,y1,vx1,vy1,x2,y2,vx2,vy2,L1x,L1y,L2x,L2y)->
A=3*vx1+x2-(3*vx2)-x1
B=3*x1-(6*vx1)+(3*vx2)
C=3*vx1-(3*x1)
E=3*vy1+y2-(3*vy2)-y1
F=3*y1-(6*vy1)+(3*vy2)
G=3*vy1-(3*y1)
La=L2y-L1y
Lb=L1x-L2x
Lc=L1y*(L2x-L1x) + L1x*(L1y-L2y)
ax = [
La*x1 + Lb*y1 + Lc
La*C + Lb*G
La*B + Lb*F
La*A + Lb*E
]
FindRootsPoly3 ax[3],ax[2],ax[1],ax[0]
pow = (x,y)-> Math.pow x,y
sqr = (x)-> x*x
FindRootsPoly3 = (A3,A2,A1,A0)->
fc2 = ((3*A1 / A3) - ( pow(A2,2) / pow(A3,2) ))/ 3
gc2 = (( (2*pow(A2,3)) / pow(A3,3)) - (9*A2*A1 / pow(A3,2)) + (27*A0 / A3)) / 27
hc2 = (pow(gc2,2)/4) + (pow(fc2,3)/27)
Rx = []
if hc2>0
Rc2 = -(gc2/2) + (sqr(hc2))
if Rc2<0
Sc2 = -(pow(Math.abs(Rc2),0.333333))
else
Sc2 = pow(((Rc2)),0.333333)
Tc2 = -(gc2/2) - ( sqr(hc2))
if Tc2<0
Uc2 = -pow(Math.abs(Tc2),0.333333)
else
Uc2 = pow((Tc2),0.333333)
Rx[0] = (Sc2 + Uc2) - (A2/(3*A3))
else
if hc2==0 and gc2==0 and fc2==0
Rx[0] = -pow((A0/A3),0.3333333 )
else
if hc2<0 or hc2==0
ic2 = sqr((pow(gc2,2)/4) - hc2)
jc2 = pow((ic2),0.333333)
kc2 = Math.acos( -(gc2 / (2*ic2)))
Lc2 = -jc2
Mc2 = Math.cos(kc2/3)
Nc2 = sqr( 3) * Math.sin(kc2/3)
Pc2 = -(A2/(3*A3))
Rx[0] = 2*jc2 * Math.cos(kc2 / 3) - (A2/(3*A3))
Rx[1] = Lc2 * (Mc2 + Nc2) + Pc2
Rx[2] = Lc2 * (Mc2 - Nc2) + Pc2
Rx
有时(带一些输入)它会输出一些东西,但大多数只是NaN
和undefined
。我不知道它应该输出到底是什么,它是t
在初始贝塞尔曲线上的值?
此外,它显然无法正常工作。任何人都可以看到我的翻译或初始代码有任何错误吗?
我真的希望能够在数学上将bezier曲线与javascript / coffeescript中的一行相交!
答案 0 :(得分:2)
你最大的错误是在vbscript中Sqr
不是“正方形”,它是“平方根”
编辑:(没关注此处的先前评论)
编辑II:你的翻译没有问题,但似乎原始代码在定义要解决的多项式时有一些错误:
bezier4poly = (A,B,C,D) ->
[
-A + 3*B + -3*C + D
3*A - 6*B + 3*C
-3*A + 3*B
A
]
intersectBezier3Line2 = (Px0,Py0,Px1,Py1,Px2,Py2,Px3,Py3,Lx0,Ly0,Lx1,Ly1)->
### (x_2 - x_1)(y - y_1)=(y_2 - y_1)(x - x_1) => ###
###(y_1 - y_2)x + (x_2 - x_1)y + (x_1(y_2 - y_1) + - y_1(x_2 - x_1)) => Ax + By + C = 0 ###
A=Ly0-Ly1
B=Lx1-Lx0
C=Lx0*(Ly1-Ly0) + -Ly0*(Lx1-Lx0)
ax = bezier4poly(Px0,Px1,Px2,Px3)
ay = bezier4poly(Py0,Py1,Py2,Py3)
p = [
A*ax[0] + B*ay[0]
A*ax[1] + B*ay[1]
A*ax[2] + B*ay[2]
A*ax[3] + B*ay[3] + C
]
findRootsPoly3 p[0],p[1],p[2],p[3]
使用此,获取结果并排序
intersectBezier3Line2(0,0,1,0,0,1,1,1,0,0,1,1)
给出
[-6.212270483585414e-7, 0.49999999999999994, 1.0000006212270485]
这与t的值相近,t的bezier曲线紧挨着由(0,0),(1,1)定义的直线,但是我并不接近于调用这个错误免费,它只是“似乎工作”。
答案 1 :(得分:0)
如果你知道Obj-C我发布了一个关于创建贝塞尔曲线的问题。答案是纠正它的工作功能。