2

これに従って、回転した長方形と円の間の衝突検出を実装しようとしています http://www.migapro.com/circle-and-rotated-rectangle-collision-detection/

ここで jsfiddle にコードを追加しましたhttp://jsfiddle.net/Z6KSX/2/

ここで何が欠けていますか?

function check_coll ( circle_x,circle_y, rect_x, rect_y, rect_width, rect_height, rect_angle) 
   {

    // Rotate circle's center point back
    var rect_centerX = rect_x /2 ;
    var rect_centerY = rect_y /2 ;

    var cx = (Math.cos(rect_angle) * (circle_x - rect_centerX)) - (Math.sin(rect_angle) * (circle_y - rect_centerY)) + rect_centerX;
    var cy = (Math.sin(rect_angle) * (circle_x - rect_centerX)) + (Math.cos(rect_angle) * (circle_y - rect_centerY)) + rect_centerY;

    // Closest point
    var x, y;

    // Find the unrotated closest x point from center of unrotated circle
    if (cx < rect_x) {
        x = rect_x;
    }
    else if (cx > rect_x + rect_width){
        x = rect_x + rect_width;
    }
    else{
        x = cx;
     }

    // Find the unrotated closest y point from center of unrotated circle
    if (cy < rect_y){
        y = rect_y;
    }
    else if (cy > rect_y + rect_height) {
        y = rect_y + rect_height;
    }
    else {
        y = cy;
     }
    // Determine collision
    var collision = false;

    var c_radius = 5;
    var distance = findDistance(cx, cy, x, y);

    if (distance < c_radius) {
        collision = true; // Collision
    }
    else {
        collision = false;
    }
     return collision;
}


function findDistance (x1, y1, x2, y2) {
       var a = Math.abs(x1 - x2);
       var b = Math.abs(y1 - y2);

       var c = Math.sqrt((a * a) + (b * b));
       return c;
}

4

3 に答える 3

2

ヘヘ、間違った道をたどるのに多くの時間を費やした後、最近自分でこれを解決したので、これは面白いと思います。

最終的に私は方法を考え出した:

1.) 円の中心点を、長方形が回転した負の量だけ回転させるだけです。これで、点が長方形に「整列」されます (長方形の相対座標空間内)。

2.) 円対 AABB を求めます。私がそれを解決した方法は、円の中心に最も近い長方形上の点を私に与えました。

3.) 結果のポイントを、四角形が回転した正の量だけ回転します。通常どおり解決を続けます (その点と円の中心の間の距離が円の半径内にあるかどうかを確認します)。

あなたのコードを一目見ただけで、おそらく同じことをしているように見えますが、最後のステップを見逃していませんか? デバッグに役立つ正確な場所を確認するために、ステップ 2 の長方形にポイントを描画することをお勧めします。

于 2012-11-27T09:19:30.423 に答える
0

私はこれを理解することができました。コードの問題は、間違った半径を使用していて、rect_x と rect_y の中心を逃していたことです。

   var rect_centerX = rect_x + (rect_width / 2);
   var rect_centerY = rect_y + (rect_height /2);

キャンバス上で回転を処理する場合、createrect で使用される対応する x 値と y 値に変換値を追加する必要があります。

于 2012-11-29T06:30:36.770 に答える
0

私は自分のプロジェクトにもこのコードを使用していますが、機能しています。angleの代わりに -angle を使用するだけです

ここに私のコードリンクがあります

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const rectX = 100;
const rectY = 100;
const rectWidth = 200;
const rectHeight = 100;
const circleRadius = 2;
const rectMidPointX = rectX + rectWidth / 2;
const rectMidPointY = rectY + rectHeight / 2;
const angle = Math.PI / 4;
let circleX;
let circleY;


canvas.addEventListener('mousemove', (e) => {
  circleX = e.clientX;
  circleY = e.clientY;

  ctx.save();
  ctx.beginPath();
  ctx.fillStyle = '#fff';
  ctx.arc(circleX, circleY, circleRadius, 0, 2 * Math.PI);
  ctx.fill();
  ctx.stroke();
  ctx.restore();
    calculateIntersection();
})

ctx.save();

//ctx.fillRect(100, 100, 100, 100);
ctx.strokeStyle = 'black';
ctx.translate(rectMidPointX, rectMidPointY);
ctx.rotate(angle);
ctx.translate(-rectMidPointX, -rectMidPointY);
ctx.strokeRect(rectX, rectY, rectWidth, rectHeight);
ctx.restore();

// Determine collision
let collision = false;

const findDistance = (fromX, fromY, toX, toY) => {
  const a = Math.abs(fromX - toX);
  const b = Math.abs(fromY - toY);

  return Math.sqrt((a * a) + (b * b));
};


function calculateIntersection() {
  // Rotate circle's center point back
  const unrotatedCircleX = Math.cos(-angle) * (circleX - rectMidPointX) -
    Math.sin(-angle) * (circleY - rectMidPointY) + rectMidPointX;
  const unrotatedCircleY = Math.sin(-angle) * (circleX - rectMidPointX) +
    Math.cos(-angle) * (circleY - rectMidPointY) + rectMidPointY;

  // Closest point in the rectangle to the center of circle rotated backwards(unrotated)
  let closestX, closestY;

  // Find the unrotated closest x point from center of unrotated circle
  if (unrotatedCircleX < rectX)
    closestX = rectX;
  else if (unrotatedCircleX > rectX + rectWidth)
    closestX = rectX + rectWidth;
  else
    closestX = unrotatedCircleX;

  // Find the unrotated closest y point from center of unrotated circle
  if (unrotatedCircleY < rectY)
    closestY = rectY;
  else if (unrotatedCircleY > rectY + rectHeight)
    closestY = rectY + rectHeight;
  else
    closestY = unrotatedCircleY;

  const distance = findDistance(unrotatedCircleX, unrotatedCircleY, closestX, closestY);
  if (distance < circleRadius)
    collision = true; // Collision
  else
    collision = false;

  console.log('collision', collision);
}
<canvas id="canvas" width="400px" height="400px" />

于 2022-01-15T16:33:53.860 に答える