繁体   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