【问题标题】:Java 2d polygon collision responseJava 2d 多边形碰撞响应
【发布时间】:2012-07-22 23:02:48
【问题描述】:

我制作了一个使用凸多边形的游戏。我的计划是让这些多边形根据它们的质量和速度碰撞和反弹。但首先我需要确保它们没有重叠。此代码检查多边形 A 的每条边,以查看多边形 B 的任何顶点是否在垂直于边的轴上重叠。整个方法返回修复多边形 A 所需的结果向量:

    /**Calculates adjustment vector for EntityPolygon A*/
public Vector calculateCollision(EntityPolygon A, EntityPolygon B) {

    //this is a large number so the first comparison of overlap is true
    double overlap = 10000;

            //this is the angle of the axis to apply the overlap vector
    double angle = 0;

            //I ran a for loop for every edge of the polygon
    for(int x = 0; x <= A.numPoint - 1; x++) {

                    //create variables
        Vector edge;
        Vector axis;
        double centerA;
        double centerB;
        double maxA;
        double maxB;
        double minA;
        double minB;

                    //this if statement finds this point and the next point
                    //to make a Vector of the edge
        if(x != A.numPoint - 1) {
            edge = new Vector(A.point[x], A.point[x + 1]);
        } else {
            edge = new Vector(A.point[x], A.point[0]);
        }

                    //this finds the axis perpendicular axis of the edge
        axis = edge.getRightNormal();

        //finds the location of both polygon's centers when projected onto
                    //the velocity(projectionOnVelocity() projects the point on the                                                           
                    //new axis)
        centerA = A.getLocation().getProjectionOnVelocity(axis);
        centerB = B.getLocation().getProjectionOnVelocity(axis);

                    //finds the location of polygons A and B on the axis by
                    //setting the min and max of their highest and lowest points
        maxA = findMax(A, axis);
        maxB = findMax(B, axis);
        minA = findMin(A, axis);
        minB = findMin(B,axis);

        //final comparison to find overlapping vector.
        if(centerA > centerB) {//if A is above B on the axis
            if(maxB > minA) {//if the max point on B is above min on A
                double m = maxB - minA;
                if(m < overlap) {
                    overlap = m;
                    angle = axis.angle;
                }
            } else {
                                    //(0,0) vector
                return Vector.getDefault();
            }
        } else if(centerB > centerA) {//if B is above A on axis
            if(maxA > minB) {//if the max point on A is above min on B
                double m = maxA - minB;
                if(m < overlap) {
                    overlap = m;
                    angle = axis.angle + Math.PI;
                }
            } else {
                                    //(0,0) vector
                return Vector.getDefault();
            }
        }
    }
            //if the overlap value has been set by the edges of Polygon A
    if(overlap != 10000) {
                    //returns the adjustment vector along overlap edge axis
        return new Vector(angle, overlap, true);
    } else {
                    (0,0) vector
        return Vector.getDefault();
    }
}

此代码有一个错误,该错误会在非常平坦的部分高于方形部分的情况下导致问题,平坦的部分认为它比实际下降得更远。结果,扁平件和方形件发生碰撞,将它们推到下图中的当前位置

这是预赛阶段的实际比赛图片。右边的蓝色方块在他们接触之前就已经被顶部的障碍物移动了。这发生在程序开始时,正方形位于屏幕的最左侧。

【问题讨论】:

  • 看起来你的算法是错误的。如果您为您的示例案例提供一些数字,会更容易解释。
  • 您提到了游戏中的图片,但我没有看到它们。

标签: java 2d physics collision


【解决方案1】:

我同意 Beta,您的算法看起来不正确(主要是因为我很确定多边形相交不会那么容易。只是为了检查 2 个形状的相交(没有任何智能),您必须检查是否任何边缘都与其他形状的任何边缘相交,但即使是适度简单的形状也会很慢。

矩形相交很容易做到,三角形相交应该不会太难,如果你可以将你的形状分成其中一个(或者任何一组具有相当简单公式的形状),它会让事情变得更容易.

您也可以查看this question

多边形相交是一个经过充分研究的问题,只要谷歌一下,你应该会得到很多选择。

【讨论】:

    猜你喜欢
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多