JavaScript-确定两个圆是否会沿其路径相交

时间:2018-09-12 02:35:23

标签: javascript math collision-detection linear-algebra

var circleA = {
	x: 100, 
  y: 40,
  radius: 20,
  color: '63, 81, 181',
  pathx: 220,
  pathy: 150
}

var circleB = {
	x: 250, 
  y: 50,
  radius: 30,
  color: '76, 175, 80',
  pathx: 120,
  pathy: 140
}

var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = 500;
var centerY = 500;


//draw circle A
context.beginPath();
context.arc(circleA.x, circleA.y, circleA.radius, 0, 2 * Math.PI, false);
context.fillStyle = "rgba(" + circleA.color + ", 1)";
context.fill();

//draw circle A path destination
context.beginPath();
context.arc(circleA.pathx, circleA.pathy, circleA.radius, 0, 2 * Math.PI, false);
context.fillStyle = "rgba(" + circleA.color + ", 0.5)";
context.fill();

//draw line in circle A path
context.beginPath();
context.moveTo(circleA.x,circleA.y);
context.lineTo(circleA.pathx,circleA.pathy);
context.strokeStyle = "rgba(" + circleA.color + ", 1)";
context.stroke();

//draw circle B
context.beginPath();
context.arc(circleB.x, circleB.y, circleB.radius, 0, 2 * Math.PI, false);
context.fillStyle = "rgba(" + circleB.color + ", 1)";
context.fill();

//draw circle B path destination
context.beginPath();
context.arc(circleB.pathx, circleB.pathy, circleA.radius, 0, 2 * Math.PI, false);
context.fillStyle = "rgba(" + circleB.color + ", 0.5)";
context.fill();

//draw line in circle A path
context.beginPath();
context.moveTo(circleB.x,circleB.y);
context.lineTo(circleB.pathx,circleB.pathy);
context.strokeStyle = "rgba(" + circleB.color + ", 1)";
context.stroke();



//I NEED HELP HERE - i have no idea how to calculate this
function willCollide(ca_start, ca_end, cb_start, cb_end)
{
	var RSum = circleA.radius + circleB.radius;
  var t = 10;
  
  var a = getPos(circleA, t);
  var b = getPos(circleB, t);
  
  var distance = (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
  var sum = RSum*=2;
  
	context.font = "20px Arial";

 	context.fillText('distance: ' + distance + "  sum: " + sum,10,200);
}

function getPos(circle, t)
{
  //position changes
  var dax = (circle.pathx - circle.x);
  var day = (circle.pathy - circle.y);
  //normalize components
  var lenA = Math.sqrt(dax * dax + day * day);
  dax = dax / lenA;
  day = day / lenA;
  //position vs time
  var ax = circleA.x + dax * t;
  var ay = circleA.y + day * t;
  
  return {
  	x: ax,
    y: ay
  }
}

willCollide(
	{ x: circleA.x, y: circleA.y },
  { x: circleA.pathx, y: circleA.pathy },
  circleA.radius,
  { x: circleB.x, y: circleB.y },
  { x: circleB.pathx, y: circleB.pathy },
  circleB.radius
);
body {
        margin: 0px;
        padding: 0px;
      }
<!DOCTYPE HTML>
<html>
  <head>
  </head>
  <body>
    <canvas id="myCanvas" width="578" height="200"></canvas>
  </body>
</html>

我在每个帧上都有给定路径的空间中到处乱跑。

所以我可以说圆A将转到xy(10,8),圆B将转到xy(5,-3)。

,并且我需要确保每个圆圈的前进路径是明确的,并且该路径上没有其他圆圈可以,因此,我想给它一个新的路径。

我已附上一张图片,解释了每种情况的情况和所需的结果。

非常感谢您的帮助。谢谢! enter image description here

1 个答案:

答案 0 :(得分:2)

第一个圆的位置描述为

x1 = x1_0 + vx1 * t 
y1 = y1_0 + vy1 * t 

其中x10是初始x坐标,vx1是速度矢量的x分量,t是时间。

使第二个圆心具有相似的表达式,构建平方距离的表达式,并在平方距离等于4R^2(对于相等的半径)时找到时间-如果解在所需的时间间隔存在,则为圈子的碰撞。

在您的指定中(似乎您具有相同的速度):

RSum = circleA.radius + circleB.radius
//position changes
dax = (circleA.pathx - circleA.x) 
day = (circleA.pathy - circleA.y) 
//normalize components
lenA = Sqrt(dax * dax + day * day)
dax = dax / lenA
day = day / lenA
//position vs time
ax = circleA.x + dax * t
ay = circleA.y + day * t

和类似的B

现在制作距离方程,用ax, bx, ay, by表达式代替,并求解未知的t(二次方程,可能有0,1,2根)

(ax - bx) * (ax - bx) + (ay - by) * (ay - by) = RSum * RSum
or
(circleA.x + dax * t - circleB.x - dbx * t) * ....