对于我的应用程序,我有一个SVG绘制的矩形,我正在使用它作为一个命中框,我正在寻找一个JavaScript函数,只要hitbox触及另一个旋转的矩形,它返回一个true的布尔值它的中心是使用CSS转换的某种角度。我从http://www.inkfood.com/collision-detection-with-svg/发现了这段代码:
function intersectRect(r1, r2) {
var r1 = r1.getBoundingClientRect(); //BOUNDING BOX OF THE FIRST OBJECT
var r2 = r2.getBoundingClientRect(); //BOUNDING BOX OF THE SECOND OBJECT
//CHECK IF THE TWO BOUNDING BOXES OVERLAP
return !(r2.left > r1.right ||
r2.right < r1.left ||
r2.top > r1.bottom ||
r2.bottom < r1.top);
}
这适用于常规矩形,但我不确定如何在此基础上使用我的旋转矩形。当我在Web浏览器中使用开发人员工具检查旋转的矩形时,我可以看到它正确地突出显示了矩形。话虽这么说,当我尝试使用JavaScript提取边界客户端矩形时,它以未旋转的形式返回矩形的尺寸。我的问题是如何为旋转的矩形接收正确的尺寸,以便我能够检测到它与我的hitbox矩形何时发生碰撞?还有另一种方法让我检测我的hitbox何时触及旋转的矩形?任何帮助将非常感激。
答案 0 :(得分:1)
好的,所以在你的用例实用之前需要进行大量的优化,但它确实可以作为isPointInPath
适用于轮换的概念证明,只要您可以通过点绘制矩形(也可以使用fillRect
和rotate
绘制它,然后使用lineTo
但不使用stroke
跟踪轮廓以创建您的边界框检查)。
要测试isPointInPath
,请修改checkX
和checkY
var ctx = document.querySelector('canvas').getContext('2d')
function rotate(x, y, a, b, degrees){
let angle = degrees * (Math.PI / 180),
sinA = Math.sin(angle),
cosA = Math.cos(angle)
return [
cosA * (a - x) - sinA * (b - y) + x,
sinA * (a - x) + cosA * (b - y) + y
]
}
function drawRect(x, y, w, h, rotation){
var manipFn = rotation ? rotate : function(a,b){ return [a,b]; }
var coords = {
bottomLeft: manipFn(x,y,x,y,rotation),
bottomRight: manipFn(x,y,x+w,y,rotation),
topRight: manipFn(x,y,x+w,y+h,rotation),
topLeft: manipFn(x,y,x,y+h,rotation)
}
var checkX = 106,
checkY = 18
ctx.moveTo(...coords.bottomLeft)
ctx.strokeStyle = "#3a1"
ctx.lineWidth = 1
ctx.lineTo(...coords.bottomRight)
ctx.lineTo(...coords.topRight)
ctx.lineTo(...coords.topLeft)
ctx.lineTo(...coords.bottomLeft)
console.log(ctx.isPointInPath(checkX,checkY))
ctx.stroke()
ctx.closePath()
ctx.fillStyle = "#000"
ctx.fillRect(checkX, checkY, 2, 2)
}
//drawRect(10, 10, 20, 30)
drawRect(100, 10, 20, 30, 45)
&#13;
canvas {
width: 500px;
height: 500px;
border: 1px solid black;
}
&#13;
<canvas></canvas>
&#13;
答案 1 :(得分:1)
SVG规范中有很多ick,但这里有一个你要求的工作示例。请注意,这是中心!!
https://codepen.io/josephscottstevens/pen/XEgbrP
window.onmousemove = function(e) {
var c = document.getElementById("circle");
var l = document.getElementById("line");
var displayDiv = document.getElementById("isColiding");
var circle = { radius : c.r, center : { x:c.cx, y:c.cy } };
var line = { p1 : { x:l.x1, y:l.y1 }, p2 : { x:l.x2, y:l.y2 } };
displayDiv.textContent = circle.radius; //(distance == 0) ? "coliding" : "not coliding";
moveSection("circle", e.clientX - 20, e.clientY - 20);
var distance = circleDistFromLineSeg(circle, line);
}