我正在寻找一个明确的答案,也许是一个函数,因为我很慢,它将确定一条线段和圆是否在 javascript 中发生碰撞(使用画布)
像下面这样的函数,如果发生碰撞,则返回 true,否则返回 false。我什至可以给你捐一个婴儿。
function isCollided(lineP1x, lineP1y, lineP2x, lineP2y, circlex, circley, radius) {
...
}
我找到了很多公式,比如这个,但它们超出了我的想象。
我正在寻找一个明确的答案,也许是一个函数,因为我很慢,它将确定一条线段和圆是否在 javascript 中发生碰撞(使用画布)
像下面这样的函数,如果发生碰撞,则返回 true,否则返回 false。我什至可以给你捐一个婴儿。
function isCollided(lineP1x, lineP1y, lineP2x, lineP2y, circlex, circley, radius) {
...
}
我找到了很多公式,比如这个,但它们超出了我的想象。
在这里你需要一些数学:
如果您一般不知道如何求解方程,这是基本概念。我会把剩下的想法留给你。;) 弄清楚CD
' 的长度并不难。
如果你问如何,那就是如何: 在 JavaScript 中查找冲突有点复杂。
我花了大约一天半的时间使它变得完美。希望这会有所帮助。
function collisionCircleLine(circle,line){ // Both are objects
var side1 = Math.sqrt(Math.pow(circle.x - line.p1.x,2) + Math.pow(circle.y - line.p1.y,2)); // Thats the pythagoras theoram If I can spell it right
var side2 = Math.sqrt(Math.pow(circle.x - line.p2.x,2) + Math.pow(circle.y - line.p2.y,2));
var base = Math.sqrt(Math.pow(line.p2.x - line.p1.x,2) + Math.pow(line.p2.y - line.p1.y,2));
if(circle.radius > side1 || circle.radius > side2)
return true;
var angle1 = Math.atan2( line.p2.x - line.p1.x, line.p2.y - line.p1.y ) - Math.atan2( circle.x - line.p1.x, circle.y - line.p1.y ); // Some complicated Math
var angle2 = Math.atan2( line.p1.x - line.p2.x, line.p1.y - line.p2.y ) - Math.atan2( circle.x - line.p2.x, circle.y - line.p2.y ); // Some complicated Math again
if(angle1 > Math.PI / 2 || angle2 > Math.PI / 2) // Making sure if any angle is an obtuse one and Math.PI / 2 = 90 deg
return false;
// Now if none are true then
var semiperimeter = (side1 + side2 + base) / 2;
var areaOfTriangle = Math.sqrt( semiperimeter * (semiperimeter - side1) * (semiperimeter - side2) * (semiperimeter - base) ); // Heron's formula for the area
var height = 2*areaOfTriangle/base;
if( height < circle.radius )
return true;
else
return false;
}
这就是你的做法..
Matt DesLauriers 在https://www.npmjs.com/package/line-circle-collision上为这个问题发布了一个 Javascript 库。API 很简单:
var circle = [5, 5],
radius = 25,
a = [5, 6],
b = [10, 10]
var hit = collide(a, b, circle, radius)
function pointCircleCollide(point, circle, r) {
if (r===0) return false
var dx = circle[0] - point[0]
var dy = circle[1] - point[1]
return dx * dx + dy * dy <= r * r
}
var tmp = [0, 0]
function lineCircleCollide(a, b, circle, radius, nearest) {
//check to see if start or end points lie within circle
if (pointCircleCollide(a, circle, radius)) {
if (nearest) {
nearest[0] = a[0]
nearest[1] = a[1]
}
return true
} if (pointCircleCollide(b, circle, radius)) {
if (nearest) {
nearest[0] = b[0]
nearest[1] = b[1]
}
return true
}
var x1 = a[0],
y1 = a[1],
x2 = b[0],
y2 = b[1],
cx = circle[0],
cy = circle[1]
//vector d
var dx = x2 - x1
var dy = y2 - y1
//vector lc
var lcx = cx - x1
var lcy = cy - y1
//project lc onto d, resulting in vector p
var dLen2 = dx * dx + dy * dy //len2 of d
var px = dx
var py = dy
if (dLen2 > 0) {
var dp = (lcx * dx + lcy * dy) / dLen2
px *= dp
py *= dp
}
if (!nearest)
nearest = tmp
nearest[0] = x1 + px
nearest[1] = y1 + py
//len2 of p
var pLen2 = px * px + py * py
//check collision
return pointCircleCollide(nearest, circle, radius)
&& pLen2 <= dLen2 && (px * dx + py * dy) >= 0
}
var circle = [5, 5],
radius = 25,
a = [5, 6],
b = [10, 10]
var hit = lineCircleCollide(a, b, circle, radius)