簡體   English   中英

想要使對象在圓內反彈,最終使對象沿圓的邊緣移動

[英]Wanted to make an object bounce inside a circle, ended up making the object move along the rim of the circle

這是有問題的代碼:

public void calculate() {
        // Center of circle is at (250, 250).
        //THIS ALGORITHM IS NOW PROVEN TO BE WORSE THAN I FEARED...

        /*      What it does:
         *          Moves object around in a circle.
         *          Does not move the object towards the center.
         *          Object always stays on the rim of the circle.
         * 
         *      Algorithm I used. (DOES NOT WORK):
         *          N is normalized vector. 
         *          R = -2*(V dot N)*N + V
         */

        vx += Accelero.X * 0.1;
        vy += Accelero.Y * 0.1;
        double nx = x - 250;
        double ny = y - 250;
        double nd = Math.hypot(nx, ny);
        if (nd == 0)
            nd = 1;
        nx /= nd;
        ny /= nd;
        double dotProduct = vx * nx + vy * ny;
        vx += (float) (-2 * dotProduct * nx);
        vy += (float) (-2 * dotProduct * ny);
        x -= vx * 2;
        y -= vy * 2;
        vx *= 0.99;
        vy *= 0.99;
    }

這就是發生的情況。

圖片。

您看到的黑線是紫色對象(框)移動的位置。 恰好恰好在我用Canvas.drawCircle()繪制的圓線上。

我不明白為什么反射不起作用。 如果物體要撞到圓壁上,它是否不應該反映物體的速度方向,這就是算法的本意? 還是我使用了錯誤的算法?

任何幫助表示贊賞。 提前致謝。

您能從任意角度的直牆彈起嗎? 那應該是第一步。 (您可能會發現,速度矢量的極坐標表示更易於使用。)

一旦完成該工作,它就應該非常簡單:彈起一個圓就像彈起一個在接觸點觸及該圓的切線。

您可以通過觀察切線垂直於接觸點處的半徑向量(即從對象的位置指向圓心的向量)來計算該切線

是否有基於矢量的實現,而無需依賴角度?

是的,請參KineticModel所示的不帶三角函數的二維彈性碰撞 您的實現似乎缺少切向組件。 有關詳細信息,請參見Ensemble#collideAtoms()

這就是我所擁有的,我將與大家分享我的發現。

public void calculate() {
    // Center of circle is at (250, 250). Radius is 40.
    //THIS ALGORITHM IS PROVEN TO BE BETTER THAN I FEARED...

    /*      What it does:
     *          Moves object around in a circle, if object is 
     *              inside of circle.
     *          Does not move the object towards the center, 
     *              nor outwards. This is crucial.
     *          Object always stays on the rim of the circle, 
     *              if the collision detection allows it to.
     * 
     *      Algorithm I used. (DOES WORK, NOT EXPECTING THIS THOUGH.):
     *          N is normalized vector. 
     *          R = -2*(V dot N)*N + V
     */



    double nx = x - 250;
    double ny = y - 250;
    double nd = Math.hypot(nx, ny);
    if (nd < 40){
        vx += Accelero.X * 0.1;
        vy += Accelero.Y * 0.1;
        x -= vx;
        y -= vy;
        vx *= 0.9;
        vy *= 0.9;
        return;
    }

    vx += Accelero.X * 0.1;
    vy += Accelero.Y * 0.1;


    if (nd == 0)
        nd = 1;
    nx /= nd;
    ny /= nd;
    double dotProduct = vx * nx + vy * ny;
    vx += (float) (-2 * dotProduct * nx);
    vy += (float) (-2 * dotProduct * ny);
    x -= vx * 2;
    y -= vy * 2;
    vx *= 0.99;
    vy *= 0.99;
}

我將碰撞檢測嵌入到我的函數中,基本上使該函數效率不高。 忽略它,因為它不是主要焦點。

圓的半徑為40,(x,y)的位置為(250,250)。

僅當物體在圓上或遠離圓心時,才應計算碰撞響應,這由算法R = -2 *(V dot N)* N + V給出,其中法向矢量N已被標准化。

該算法確實是正確的,這是我的碰撞檢測的布爾條件導致對象停留在圓的邊緣並在其上繞一圈。

我沒有說@trashgod提供的另一種算法是錯誤的。 由於某些奇怪的問題,某種程度上導致對象異常移動。 我想這是我正在使用的API的錯誤,它不允許雙打,但我可能不正確。 我只是找不到問題的根源。 我也很高興不再對此進行深入研究。

碰撞檢測布爾條件本身可以更改所有內容,如果對其進行了稍微的更改。 如果不是@nm指向我似乎以某種方式忘記了減號(在這種情況下為NOT符號),那么我可能永遠也不會意識到它是多么微不足道。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM