Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can you guys add some functionality? #53

Open
Faeest opened this issue Jan 1, 2024 · 2 comments
Open

Can you guys add some functionality? #53

Faeest opened this issue Jan 1, 2024 · 2 comments

Comments

@Faeest
Copy link

Faeest commented Jan 1, 2024

don't be wrong, it's a pretty helpful plugin for my games. but, it's only detect the collision which only a bool, I have to smuggle some code so I know which direction the collision came in a rect to rect and circle to circle. so then I can use it on my platformer game. Can you guys add that?

@poisa
Copy link

poisa commented Jan 25, 2024

You can definitely do this. Here's an example GPT4 provided for circle2rect collision. Circle2circle should be easier.
In this example collideRectCircle() is the exact same version as provided by the p5.collide2D library.

function setup() {
  createCanvas(400, 400);
  noCursor()
}

function draw() {
  background(220);

  if (collideRectCircle(mouseX, mouseY, 50, 50, 100, 100, 100)) {
    fill("red");
  } else {
    fill("white");
  }

  rect(mouseX, mouseY, 50, 50);
  circle(100, 100, 100);

  let pts = collisionPointsRectCircle(mouseX, mouseY, 50, 50, 100, 100, 100);

  if (pts) {
    for (let pt of pts) {
      fill('yellow')
      circle(pt.x, pt.y, 5);
    }
  }
}

function collideRectCircle(rx, ry, rw, rh, cx, cy, diameter) {
  //2d
  // temporary variables to set edges for testing
  var testX = cx;
  var testY = cy;

  // which edge is closest?
  if (cx < rx) {
    testX = rx; // left edge
  } else if (cx > rx + rw) {
    testX = rx + rw;
  } // right edge

  if (cy < ry) {
    testY = ry; // top edge
  } else if (cy > ry + rh) {
    testY = ry + rh;
  } // bottom edge

  // // get distance from closest edges
  var distance = this.dist(cx, cy, testX, testY);

  // if the distance is less than the radius, collision!
  if (distance <= diameter / 2) {
    return true;
  }
  return false;
}

function collisionPointsRectCircle(rx, ry, rw, rh, cx, cy, diameter) {
  let points = [];
  let radius = diameter / 2;
  let rectPoints = [
    { x: rx, y: ry },
    { x: rx + rw, y: ry },
    { x: rx, y: ry + rh },
    { x: rx + rw, y: ry + rh },
  ];

  // Check each corner of the rectangle
  for (let p of rectPoints) {
    if (dist(p.x, p.y, cx, cy) <= radius) {
      points.push(p);
    }
  }

  // Check middle points of each rectangle side
  let midPoints = [
    { x: rx + rw / 2, y: ry },
    { x: rx, y: ry + rh / 2 },
    { x: rx + rw / 2, y: ry + rh },
    { x: rx + rw, y: ry + rh / 2 },
  ];

  for (let p of midPoints) {
    let angle = Math.atan2(p.y - cy, p.x - cx);
    let circlePoint = {
      x: cx + radius * Math.cos(angle),
      y: cy + radius * Math.sin(angle),
    };

    if (
      circlePoint.x >= rx &&
      circlePoint.x <= rx + rw &&
      circlePoint.y >= ry &&
      circlePoint.y <= ry + rh
    ) {
      points.push(circlePoint);
    }
  }

  // Removing duplicate points
  points = points.filter(
    (point, index, self) =>
      index === self.findIndex((t) => t.x === point.x && t.y === point.y)
  );

  return points;
}

@poisa
Copy link

poisa commented Jan 25, 2024

Here's circle2circle as provided by GPT4:

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(240);
  let circle1 = { x: mouseX, y: mouseY, r: 40 };
  let circle2 = { x: 200, y: 200, r: 30 };

  let points = circleIntersection(circle1, circle2);
  fill("white");
  drawCircle(circle1);
  drawCircle(circle2);
  if (points) {
    drawPoints(points);
  }
}

function drawCircle(circle) {
  ellipse(circle.x, circle.y, circle.r * 2);
}

function drawPoints(points) {
  for (let p of points) {
    fill(255, 0, 0);
    ellipse(p.x, p.y, 10, 10);
  }
}

function circleIntersection(c1, c2) {
  let d = dist(c1.x, c1.y, c2.x, c2.y);

  if (d > c1.r + c2.r || d < abs(c1.r - c2.r) || (d === 0 && c1.r === c2.r)) {
    return null; // No intersection
  }

  let a = (c1.r * c1.r - c2.r * c2.r + d * d) / (2 * d);
  let h = sqrt(c1.r * c1.r - a * a);
  let p2 = {
    x: c1.x + (a * (c2.x - c1.x)) / d,
    y: c1.y + (a * (c2.y - c1.y)) / d,
  };

  return [
    {
      x: p2.x + (h * (c2.y - c1.y)) / d,
      y: p2.y - (h * (c2.x - c1.x)) / d,
    },
    {
      x: p2.x - (h * (c2.y - c1.y)) / d,
      y: p2.y + (h * (c2.x - c1.x)) / d,
    },
  ];
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants