2

2 つの異なる幾何学的形状のオブジェクトが衝突するかどうかを「チェック」しようとしています。1つは円で、2つ目は正方形です。簡単な例を見つけてそれから学ぶためにグーグルを検索しました。その方法がわからないからです。この例を見つけて試してみましたが、何も起こりませんでした。ほとんどの場合、コードにバグがあります。CまたはC++言語で修正するのを手伝ってください。

bool Collision(int circleX, int circleY, int radius, int squareX, int squareY, int width, int height)
{
    int distance = 0;

    if(circleX < squareX) 
        distance += pow(circleX - boxX,2); //x-axis
    else if (circleX > squareX + width)
        distance += pow(circleX - squareX - width, 2);

    if(circleY < squareY) 
        distance += pow(circleY - squareY,2); //y-axis
    else if (circleY > squareY + height) 
        distance += pow(circleY - squareY - height, 2);

    if( distance <= pow(radius, 2))
        return true; 
    else    
        return false;
}
4

2 に答える 2

3

まず、円と正方形の表し方を明確にしましょう。

慣例ではsquare、 は次のように表されます。

  squarexX, squareY + height  ------------ squareX+ width, squareY +height
  |                                               |
  |                                               |
   squareX, squareY          ------------- squareX + width, squareY

Whileは、円 と値circleの座標で表されます。これを念頭に置いて、独自の関数をコーディングすることさえできるはずです。円には幅も高さもありません。(circleX, circleY)radius

だから彼らのコードで:

 if(circleX < squareX) distance += pow(circleX - boxX,2); //x-axis

する必要があります

 if(circleX < squareX) distance += pow(circleX - squareX,2); //x-axis

正方形が円と重なっている/衝突しているかどうかを判断するための考え方は次のとおりです。

  1. 正方形が 2D 平面の原点にあると仮定します。そうでない場合は、原点を正方形の中心に移動できます。
  2. 次に、円と正方形の最も近いエッジの交点の間の距離を見つけます。この距離が半径より大きい場合は重なりません。それ以外の場合は重なります。特殊なケースとして、円が正方形の内側にある場合、いわゆる交点は円自体の中心になります。この場合、testForCollision は true を返します。

完全な関数は次のようになります。

//this function computes the distance between center of circle
//to closest point on one of the edges of square, that edge is on the
//same side as the circle
#include <algorithm>
bool testForCollision(int circleX, int circleY, int width, int height, int radius)
{   

    int dx = std::min(circleX, (int)(width  * 0.5));
    int dx1 = std::max(dx, (int)(-width *0.5));

    int dy = std::min(circleY, (int)(height * 0.5));
    int dy1 = std::max(dy, (int)(-height * 0.5));

    return (dx1 - circleX) * (dx1 - circleX) 
           + (dy1 - circleY) * (dy1 - circleY) <= radius * radius;
}


bool Collision(int circleX, int circleY, int radius, 
               int squareX, int squareY, int width, int height)
{

    //get center of square
    int center_of_square_x = squareX + width/2;
    int center_of_square_y = squareY + height/2;

    //if square is already at origin, test directly
    if ( center_of_square_x == 0 && center_of_square_y ==0)
    {
        return testForCollision(circleX, circleY, width, height, radius);
    }
    else
    {
        //shift center of square to origin and update coordinates of circle
        //only consider part of the situation, more to add about shifting
        circleX = circleX - center_of_square_x;
        circleY = circleY - center_of_square_y;
        return testForCollision(circleX, circleY, width, height, radius);
    }
}

このようにして、円と正方形が互いに衝突するかどうかを識別できるはずです。

編集: 1 つのテスト ケースを見てみましょう:

circleX = 60 circleY = 172 radius = 39
squareX = 120 squareY = 180 width = 72 height = 72 

正方形の座標は次のとおりです(中心を含む)

120, 252  -------- 192, 252
 |                   |
 |--------156,216----|
 |                   |
120,180   ---------192,180

(60,172) がエッジ (120,252) の左側にあることがわかります-->(120,180)、(120,180) と (60,72) の間の距離は 39 よりも大きいです。 (120,252) と (60,72) の間の距離も 39 より大きく、重複はありません。理解を深めるために、円の中心 (60,172) と半径 39 を考えると、円の中心から到達できる x と y の範囲は (60-39,60 +39) = (21,99) および ( 172-39, 172+39) = (133,211). 視覚化すると、これは正方形と重なってはいけません。

最初に原点を (156,216) に変換すると、新しい座標系の円の中心は (-96,-44) になります。それは第 3 象限にあります。testForCollision 関数を実行すると、重複がないことがわかります。

dx = min(-96,36) = -96
dx1 = max(dx, -36) = -36
dy = min(-44, 36) = -44
dy1 = max(dy,-36) = -36

distance = (-36 - (-96))^2 + (-36 - (-44))^2 = 60^2 + 8^2 > 39^2, so no overlap
于 2013-04-14T02:15:39.380 に答える
2

3 つのケースがあります。

  • 形状が重なるため、一方の形状の端が他方の形状の端と交差します。
  • 円が正方形の中に完全に入っている (例えば、どこかに小さな円が入った巨大な長方形を想像してください)
  • 四角形が円の中に完全に入っている (たとえば、小さな四角形が入った巨大な円を想像してください)

まず、円の中心と長方形の中心の間の距離を決定します。この距離を D としましょう。

次に、四角形の内側に収まる大きさの円を見つけます。これは、長方形の高さまたは長方形の幅 (どちらか小さい方) に等しい直径を持ちます。新しい円の半径に元の円の半径を加えたものが距離 D より小さい場合は、間違いなく衝突が発生します。

次に、長方形全体を含むのに十分な大きさの最小の円を見つけます。この円の半径は、ピタゴラス (長方形の中心から長方形の任意の角までの距離) で求めることができます。この新しい円の半径に元の円の半径を加えたものが距離 D より大きい場合、衝突は発生しません。

これらのテストの両方で答えが得られない場合。その場合、どちらの形状も他方の形状の完全な内側にはありませんが、それらが重なっている場合と重なっていない場合があります。したがって、ある形状のエッジが他の形状のエッジと交差するかどうかを判断する必要があります。これを行うには、長方形のすべての辺を無限の長さに延長します (線分を使用して線を記述します)。そして、x または y を円の式に「差し込む」ことによって、これらの無限の長さの線が円の円周と交差する場所を計算してみてください (注: 交点がないか、1 つの交点または 2 つの交点が見つかります)。交差が 2 つある場合は、どちらかがエッジかどうかをテストする必要があります。

たとえば、長方形の上端が にある場合、円の形式にy = 2接続します。y = 2この線x = 3が x = 6` と x = 6` で交差していることがわかった場合、3 と 6 の両方が長方形の左端と長方形の右端の間にあるかどうかをテストします。長方形の上端と衝突があります。

衝突を検出せずに四角形の 4 つのエッジすべてに対して「エッジ交差」テストを実行すると、検出する衝突はありません。

于 2013-04-14T03:34:09.067 に答える