2

楕円形のビリヤード テーブルの場合、このテーブルの境界と 1 つのビリヤード ボールとの間の衝突をどのように検出して解決できますか?

1.) ビリヤード ボールの位置 P(x,y) が存在するかどうかを確認したい

  • 中身
  • の上
  • または楕円の境界の外側。[更新: パート 1. 解決済み]

2.)境界または境界にある場合は、新しい速度を計算する必要があります (速度を反転するだけでは十分ではありません)。

3.)外側にある場合は、最初に境界に戻るように移動する必要があります。

            ========
        ====      * ====
    ====                ====
    =                      =
    ====                ====
        ====        ====
            ========

ビリヤード ボールの位置 P(x,y) と速度 V(x,y)、および楕円の中心の位置 C(x_0,y_0) と楕円の両方の半軸 a、b が与えられます。 .

4

3 に答える 3

2

円の方程式を使用したように、楕円の方程式を使用するだけです。

((p.x-x0)/a)^2 + ((p.y-y0)/b)^2 = k

k < 1 -> 楕円の内側の場合

k == 1 の場合 -> 楕円上

k > 1 の場合 -> 楕円の外側

于 2011-12-07T18:57:52.347 に答える
0

楕円形のテーブルを使った面白い実験。Delphi コード (エラー処理なし!)。

//calculates next ball position in ellipse
//ellipse semiaxes A, B, A2 = A * A, B2 = B * B
//center CX, CY
//PX,PY - old position, VX,VY - velocity components
//V - scalar velocity V = Sqrt(VX * Vx + VY * VY)

procedure TForm1.Calc;
var
  t: Double;
  eqA, eqB, eqC, DD: Double;
  EX, EY, DX, DY, FX, FY: Double;
begin
  //new position
  NPX := PX + VX;
  NPY := PY + VY;

  //if new position is outside
  if (B2 * Sqr(NPX) + A2 * Sqr(NPY) >= A2 * B2) then begin

    //find intersection point of the ray in parametric form and ellipse
    eqA := B2 * VX * VX + A2 * VY * VY;
    eqB := 2 * (B2 * PX * VX + A2 * PY * VY);
    eqC := -A2 * B2 + B2 * PX * PX + A2 * PY * PY;
    DD := eqB * eqB - 4 * eqA * eqC;
    DD := Sqrt(DD);

    //we need only one bigger root
    t := 0.5 * (DD - eqB) / eqA;

    //intersection point
    EX := PX + t * VX;
    EY := PY + t * VY;

  //mark intersection position by little circle
    Canvas.Ellipse(Round(EX - 2 + CX), Round(EY - 2 + CY),
                   Round(EX + 3 + CX), Round(EY + 3 + CY));

    //ellipse normal direction
    DX := B2 * EX;
    DY := A2 * EY;
    DD := 1.0 / (DY * DY + DX * DX);

    //helper point, projection onto the normal
    FX := DD * (NPX * DX * DX + EX * DY * DY - DY * DX * EY + DX * DY * NPY);
    FY := DD * (-DX * DY * EX + DX * DX * EY + DX * NPX * DY + DY * DY * NPY);

    //mirrored point
    NPX := NPX + 2 * (EX - FX);
    NPY := NPY + 2 * (EY - FY);

    //new velocity components
    DD := V / Hypot(NPX - EX, NPY - EY);
    VX := (NPX - EX) * DD;
    VY := (NPY - EY) * DD;
  end;

  //new position
  PX := NPX;
  PY := NPY;

  //mark new position
  Canvas.Ellipse(Round(PX - 1 + CX), Round(PY - 1 + CY),
                 Round(PX + 1 + CX), Round(PY + 1 + CY));

end;

A = 125、B = 100 楕円の中心 (左の図) から開始し、右の焦点 (右の図) から、ボールは左の焦点に到達し、次に右の焦点に戻ります

于 2011-12-08T11:40:40.730 に答える
0

あなたは楕円形の(したがって凸状の)ボードを検討しているので、 GJKに基づいたものを使用できると思います。衝突中の接触点とサーフェス法線を取得し、衝突がない場合はオブジェクトと関連する目撃点の間の最小距離を取得します。

GJK を使用した衝突検出は非常に高速で、他の形状に対しても非常に簡単に実装できます (サポート関数を再コーディングするだけで済みます)。楕円の場合、サポート関数は次のようになると思います(確認してみてください):

h=((x^2)/(a^4)+(y^2)/(b^4))^(-1/2)

いくつかのリンク:

于 2011-12-07T17:06:39.943 に答える