我有2 ellipses,我需要检测它们之间的任何重叠。
以下是检测两个圆圈之间重叠的示例,我正在寻找类似椭圆的东西:
var circle1 = {radius: 20, x: 5, y: 5};
var circle2 = {radius: 12, x: 10, y: 5};
var dx = circle1.x - circle2.x;
var dy = circle1.y - circle2.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < circle1.radius + circle2.radius) {
// collision !
}
对于省略号,我有相同的变量,因为垂直轴上的半径是水平轴上半径的2倍:
var oval1 = {radius: 20, x: 5, y: 5};
var oval2 = {radius: 12, x: 10, y: 5};
// what comes here?
if ( /* condition ? */ ) {
// collision !
}
var result = document.getElementById("result");
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
// First eclipse
var eclipse1 = { radius: 20,
x: 100,
y: 40 };
// Second eclipse
var eclipse2 = { radius: 20,
x: 120,
y: 65 };
function have_collision( element1, element2 )
{
var dx = element1.x - element2.x;
var dy = element1.y - element2.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= element1.radius + element2.radius) {
return true;
}
else {
return false;
}
}
function draw( element ) {
// http://scienceprimer.com/draw-oval-html5-canvas
context.beginPath();
for (var i = 0 * Math.PI; i < 2 * Math.PI; i += 0.01 ) {
xPos = element.x - (element.radius/2 * Math.sin(i)) * Math.sin(0 * Math.PI) + (element.radius * Math.cos(i)) * Math.cos(0 * Math.PI);
yPos = element.y + (element.radius * Math.cos(i)) * Math.sin(0 * Math.PI) + (element.radius/2 * Math.sin(i)) * Math.cos(0 * Math.PI);
if (i == 0) {
context.moveTo(xPos, yPos);
} else {
context.lineTo(xPos, yPos);
}
}
context.fillStyle = "#C4C4C4";
context.fill();
context.lineWidth = 2;
context.strokeStyle = "#FF0000";
context.stroke();
context.closePath();
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
canvas.addEventListener('mousemove', function(e) {
var mousePos = getMousePos(canvas, e);
eclipse2.x = mousePos.x;
eclipse2.y = mousePos.y;
result.innerHTML = 'Collision ? ' + have_collision( eclipse1, eclipse2 );
context.clearRect(0, 0, canvas.width, canvas.height);
draw( eclipse1 );
draw( eclipse2 );
}, false);
draw( eclipse1 );
draw( eclipse2 );
result.innerHTML = 'Collision ? ' + have_collision( eclipse1, eclipse2 );
&#13;
#canvas {
border: solid 1px rgba(0,0,0,0.5);
}
&#13;
<canvas id="canvas"></canvas>
<p id="result"></p>
<code>distance = Math.sqrt(dx * dx + dy * dy);</code>
&#13;
答案 0 :(得分:7)
由于你的椭圆是非常具体的,因为它们只是沿着Y轴收缩的圆圈,你可以想象如果你沿着Y轴以2因子拉伸平面会发生什么。你会同意那些重叠的椭圆将成为重叠的圆,而那些不重叠的椭圆也会在拉伸后不重叠。您可以想象它就像椭圆是在弹性材料上绘制的,而您只是在垂直方向上拉伸材料:这当然不会改变任何重叠条件。
所以,你可以这样写:
var stretchedDistance = Math.sqrt(dx * dx + 2 * dy * 2 * dy);
...并继续处理现状,因为它基于X方向的半径,在拉伸之后,也是Y方向的半径。当然,我以不同的方式命名变量,因此您应该使用该变量进行测试。因此,为了完成代码,我们得到:
var stretchedDistance = Math.sqrt(dx * dx + 4 * dy * dy);
if (stretchedDistance < circle1.radius + circle2.radius) {
// collision !
}
请注意,通过将dy
乘以2来考虑拉伸。在距离公式中,它与写4 * dy * dy
相同且更短。
以下是您创建的精彩互动fiddle,并对其进行了更新。