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 基本上是

的直接副本