1
Graphics / Re: Collision Detection between circle and triangle?
« on: March 01, 2020, 02:49:50 am »
Never mind, I figured it out. One problem was that I was using getOrigin instead of getPosition. Also, after I changed that I was still getting false positives because it would still sometimes cross one of the lines when just the corners of the bounding rectangles intersected. I fixed that by making sure it only crossed the right line segment when the spaceship was on the left of the circle, and vice-versa. Also, I did have to use the point-radius collision for the top point of the triangle because of this. Here's my changed code for anyone who's interested:
#include "Spaceship.h"
#include <iostream>
Spaceship::Spaceship() {
_texture.loadFromFile("images\\spaceship.png");
_texture.setSmooth(true);
setTexture(_texture);
setPosition(720 / 2 + getGlobalBounds().width / 2, 680 - getGlobalBounds().height);
}
bool Spaceship::pointRadius(sf::CircleShape &circle, float x1, float y1) {
float x2 = circle.getPosition().x;
float y2 = circle.getPosition().y;
float distance = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
return distance < circle.getRadius();
}
float Spaceship::getDistanceToCircleOrigin(sf::CircleShape &circle, float x1, float y1, float x2, float y2) {
float distance = abs((y2 - y1) * (circle.getPosition().x) - (x2 - x1) * (circle.getPosition().y) + x2 * y1 - y2 * x1) / sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
return distance;
}
bool Spaceship::intersectsCircle(sf::CircleShape &circle) {
if (getGlobalBounds().intersects(circle.getGlobalBounds())) {
if (pointRadius(circle, getPosition().x + getGlobalBounds().width / 2, getPosition().y)) {
return true;
}
float distance = getDistanceToCircleOrigin(
circle,
getPosition().x + getGlobalBounds().width / 2,
getPosition().y,
getPosition().x + getGlobalBounds().width,
getPosition().y + getGlobalBounds().height
);
float distance2 = getDistanceToCircleOrigin(
circle, getPosition().x + getGlobalBounds().width / 2,
getPosition().y,
getPosition().x,
getPosition().y + getGlobalBounds().height);
float radius = circle.getRadius();
if (distance <= radius && distance2 > radius && getPosition().x < circle.getPosition().x - circle.getGlobalBounds().width / 2) {
return true;
}
if (distance2 <= radius && distance > radius && getPosition().x + getGlobalBounds().width > circle.getPosition().x + circle.getGlobalBounds().width / 2) {
return true;
}
}
return false;
}
#include <iostream>
Spaceship::Spaceship() {
_texture.loadFromFile("images\\spaceship.png");
_texture.setSmooth(true);
setTexture(_texture);
setPosition(720 / 2 + getGlobalBounds().width / 2, 680 - getGlobalBounds().height);
}
bool Spaceship::pointRadius(sf::CircleShape &circle, float x1, float y1) {
float x2 = circle.getPosition().x;
float y2 = circle.getPosition().y;
float distance = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
return distance < circle.getRadius();
}
float Spaceship::getDistanceToCircleOrigin(sf::CircleShape &circle, float x1, float y1, float x2, float y2) {
float distance = abs((y2 - y1) * (circle.getPosition().x) - (x2 - x1) * (circle.getPosition().y) + x2 * y1 - y2 * x1) / sqrt((y2 - y1) * (y2 - y1) + (x2 - x1) * (x2 - x1));
return distance;
}
bool Spaceship::intersectsCircle(sf::CircleShape &circle) {
if (getGlobalBounds().intersects(circle.getGlobalBounds())) {
if (pointRadius(circle, getPosition().x + getGlobalBounds().width / 2, getPosition().y)) {
return true;
}
float distance = getDistanceToCircleOrigin(
circle,
getPosition().x + getGlobalBounds().width / 2,
getPosition().y,
getPosition().x + getGlobalBounds().width,
getPosition().y + getGlobalBounds().height
);
float distance2 = getDistanceToCircleOrigin(
circle, getPosition().x + getGlobalBounds().width / 2,
getPosition().y,
getPosition().x,
getPosition().y + getGlobalBounds().height);
float radius = circle.getRadius();
if (distance <= radius && distance2 > radius && getPosition().x < circle.getPosition().x - circle.getGlobalBounds().width / 2) {
return true;
}
if (distance2 <= radius && distance > radius && getPosition().x + getGlobalBounds().width > circle.getPosition().x + circle.getGlobalBounds().width / 2) {
return true;
}
}
return false;
}