p5.js 中旋转线上圆圈之间的碰撞检测
collision detection between circles on a rotating line in p5.js
我有一个带有圆圈和旋转臂的简单草图,从圆心顺时针旋转。在草图中,中心左侧有两个较小的椭圆。
我正在寻找一种方法来检测旋转臂何时与较小的椭圆发生碰撞,因为它旋转臂的方式是首先击中靠近中心的椭圆。我在完全实现这个想法时遇到了一些麻烦,我想知道以前是否有人遇到过这个问题?
这里有一些代码可以更好地说明我的观点
希望这是有道理的!
let angle;
function setup() {
createCanvas(400, 400);
angleMode(RADIANS);
angle = 0.00;
}
function draw() {
background(220);
translate(width / 2, height / 2);
noFill();
ellipse(0, 0, 400);
fill(255, 0, 0, 40);
ellipse(60, 0, 30);
ellipse(160, 0, 30);
stroke(0, 200);
strokeWeight(3);
rotate(angle);
line(0, 0, 0, -200);
angle += 0.015;
}
function doSomthing() {
// when arm collides with smaller circles
// do somthing.
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
这个问题基本上是重复的,但我只是想确保解决方案有效:
const lineLength = 200;
const radius = 15;
let angle;
let lineStart;
let circleOne;
let circleTwo;
function setup() {
createCanvas(400, 400);
angleMode(RADIANS);
ellipseMode(RADIUS);
angle = -PI / 2;
lineStart = createVector(0, 0);
circleOne = createVector(60, 0);
circleTwo = createVector(160, 0);
}
function draw() {
background(220);
translate(width / 2, height / 2);
noFill();
ellipse(0, 0, 400);
let lineEnd = createVector(lineLength * cos(angle), lineLength * sin(angle));
fill(255, 0, 0, 40);
push();
if (getLineCircleIntersections(lineStart, lineEnd, circleOne, radius).length > 0) {
fill('red');
}
ellipse(circleOne.x, circleOne.y, radius);
pop();
push();
if (getLineCircleIntersections(lineStart, lineEnd, circleTwo, radius).length > 0) {
fill('red');
}
ellipse(circleTwo.x, circleTwo.y, radius);
pop();
stroke(0, 200);
push();
strokeWeight(2);
rotate(angle);
line(lineStart.x, lineStart.y, 200, 0);
pop();
push();
strokeWeight(6);
stroke('blue');
point(lineEnd.x, lineEnd.y);
pop();
angle += 0.015;
}
function getLineCircleIntersections(p1, p2, cpt, r) {
let x1 = p1.copy().sub(cpt);
let x2 = p2.copy().sub(cpt);
let dv = x2.copy().sub(x1)
let dr = dv.mag();
let D = x1.x * x2.y - x2.x * x1.y;
// evaluate if there is an intersection
let di = r * r * dr * dr - D * D;
if (di < 0.0) {
return [];
}
let t = sqrt(di);
let ip = [];
ip.push(new p5.Vector(D * dv.y + Math.sign(dv.y) * dv.x * t, -D * dv.x + abs(dv.y) * t).div(dr * dr).add(cpt));
if (di > 0.0) {
ip.push(new p5.Vector(D * dv.y - Math.sign(dv.y) * dv.x * t, -D * dv.x - abs(dv.y) * t).div(dr * dr).add(cpt));
}
push();
for (let p of ip) {
stroke('lime');
strokeWeight(8);
point(p.x, p.y);
}
pop();
return ip.filter(p => p.x >= p1.x && p.x <= p2.x);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
需要进行一些调整才能使用此示例,但 getLineCircleIntersections
基本上是
的直接副本
我有一个带有圆圈和旋转臂的简单草图,从圆心顺时针旋转。在草图中,中心左侧有两个较小的椭圆。
我正在寻找一种方法来检测旋转臂何时与较小的椭圆发生碰撞,因为它旋转臂的方式是首先击中靠近中心的椭圆。我在完全实现这个想法时遇到了一些麻烦,我想知道以前是否有人遇到过这个问题?
这里有一些代码可以更好地说明我的观点
希望这是有道理的!
let angle;
function setup() {
createCanvas(400, 400);
angleMode(RADIANS);
angle = 0.00;
}
function draw() {
background(220);
translate(width / 2, height / 2);
noFill();
ellipse(0, 0, 400);
fill(255, 0, 0, 40);
ellipse(60, 0, 30);
ellipse(160, 0, 30);
stroke(0, 200);
strokeWeight(3);
rotate(angle);
line(0, 0, 0, -200);
angle += 0.015;
}
function doSomthing() {
// when arm collides with smaller circles
// do somthing.
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
这个问题基本上是重复的,但我只是想确保解决方案有效:
const lineLength = 200;
const radius = 15;
let angle;
let lineStart;
let circleOne;
let circleTwo;
function setup() {
createCanvas(400, 400);
angleMode(RADIANS);
ellipseMode(RADIUS);
angle = -PI / 2;
lineStart = createVector(0, 0);
circleOne = createVector(60, 0);
circleTwo = createVector(160, 0);
}
function draw() {
background(220);
translate(width / 2, height / 2);
noFill();
ellipse(0, 0, 400);
let lineEnd = createVector(lineLength * cos(angle), lineLength * sin(angle));
fill(255, 0, 0, 40);
push();
if (getLineCircleIntersections(lineStart, lineEnd, circleOne, radius).length > 0) {
fill('red');
}
ellipse(circleOne.x, circleOne.y, radius);
pop();
push();
if (getLineCircleIntersections(lineStart, lineEnd, circleTwo, radius).length > 0) {
fill('red');
}
ellipse(circleTwo.x, circleTwo.y, radius);
pop();
stroke(0, 200);
push();
strokeWeight(2);
rotate(angle);
line(lineStart.x, lineStart.y, 200, 0);
pop();
push();
strokeWeight(6);
stroke('blue');
point(lineEnd.x, lineEnd.y);
pop();
angle += 0.015;
}
function getLineCircleIntersections(p1, p2, cpt, r) {
let x1 = p1.copy().sub(cpt);
let x2 = p2.copy().sub(cpt);
let dv = x2.copy().sub(x1)
let dr = dv.mag();
let D = x1.x * x2.y - x2.x * x1.y;
// evaluate if there is an intersection
let di = r * r * dr * dr - D * D;
if (di < 0.0) {
return [];
}
let t = sqrt(di);
let ip = [];
ip.push(new p5.Vector(D * dv.y + Math.sign(dv.y) * dv.x * t, -D * dv.x + abs(dv.y) * t).div(dr * dr).add(cpt));
if (di > 0.0) {
ip.push(new p5.Vector(D * dv.y - Math.sign(dv.y) * dv.x * t, -D * dv.x - abs(dv.y) * t).div(dr * dr).add(cpt));
}
push();
for (let p of ip) {
stroke('lime');
strokeWeight(8);
point(p.x, p.y);
}
pop();
return ip.filter(p => p.x >= p1.x && p.x <= p2.x);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
需要进行一些调整才能使用此示例,但 getLineCircleIntersections
基本上是