0

フォーラムの質問を見つけました...

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

線とベジエ曲線の交点を何らかの形で出力することを期待しています。私はコーヒースクリプトに翻訳しました

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

そして時々(いくつかの入力で)何かを出力しますが、ほとんどはNaNand undefined. 正確に何を出力すべきかわかりませんt。最初のベジエ曲線の値ですか?

また、明らかに正しく機能していません。私の翻訳や最初のコードに何か問題があると思いますか?

javascript/coffeescript で、ベジエ曲線と線を数学的に交差させたいと思っています。

4

2 に答える 2

2

あなたの最大の間違いは、vbscriptSqrでは「平方根」ではなく「平方根」であるということです

編集:(ここにあった以前のコメントを気にしないでください)

編集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のベジェ曲線が(0,0)、(1,1)で定義された線の隣にある、tの値として直感的に理解できるものに近いですが、このバグを無料と呼ぶことに近いわけではありません。 、それは単に「機能しているようです」。

于 2012-12-22T19:12:49.160 に答える
0

Obj-C を知っている場合は、ベジェ曲線の作成に関する質問を投稿しました。物事を修正するための答えがあれば、それは機能します。

Objective-C のベジエ曲線アルゴリズムには微調整が必​​要です

于 2012-12-22T21:45:22.457 に答える