0

凸多角形を使ったゲームを作りました。私の計画は、これらのポリゴンが衝突し、その質量と速度に応じて跳ね返ることです。しかし、最初にそれらが重なっていないことを確認する必要があります。このコードは、ポリゴン A のすべてのエッジをチェックして、ポリゴン B の頂点のいずれかがエッジに垂直な軸上でオーバーラップしているかどうかを確認します。メソッド全体が、Polygon A を修正するために必要な結果の Vector を返します。

    /**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();
    }
}

このコードには、非常に平らなピースが正方形のピースの上にある状況で問題を引き起こすバグがあり、平らなピースは実際よりもはるかに下にあると信じています。その結果、平らなピースと四角いピースが衝突し、下の写真の現在の位置に押し出されます。

これは準備段階での実際のゲームの写真です。右側の青い四角は、接触する前に上部のブロック バリアによって移動されています。これは、正方形が画面の一番左側にあるプログラムの開始時に発生します。

4

1 に答える 1

0

ベータ版に同意します。アルゴリズムが正しくないように見えます (主に、ポリゴンの交差がそれほど簡単ではないことを確信しているためです。2 つの形状の交差を確認するためだけに (知性なしで)、エッジが交差するかどうかを確認する必要があります)。他の形状の任意のエッジを使用できますが、これは適度に単純な形状であっても低速です。

長方形の交差は非常に簡単ですが、三角形の交差はそれほど難しくないはずです。形状をそれらの 1 つ (または実際には合理的に単純な式を持つ形状のセット) に分割できれば、作業がはるかに簡単になります。

この質問も確認できます。

ポリゴンの交差はよく研究されている問題です。Google で検索するだけで、かなりの数のオプションが得られるはずです。

于 2012-11-23T18:32:14.843 に答える