2009-10-15 1 views
3

Мне нужен алгоритм для обнаружения, если круг ударил квадрат, и я видел этот пост: Circle-Rectangle collision detection (intersection)обнаружение столкновения Круг-Прямоугольник закончил exampe

Похоже, я должен идти на ответ ShreevatsaR, но я математический дурак, и я понятия не имею, как закончить алгоритм. Может ли кто-нибудь найти время, чтобы сделать полный пример для меня, пожалуйста, я искал сеть для этого и еще не нашел рабочего примера.

Большое спасибо
Soeren

EDIT:

Ok вот моя попытка. Он не работает, он никогда не обнаруживает никаких столкновений.

typedef struct { 
    double x; 
    double y; 
} point; 

typedef struct { 
    point one; 
    point two; 
} segment; 

typedef struct { 
    point center; 
    double radius; 
} circle; 

typedef struct { 
    point p; 
    int width; 
    int height; 
    point a; 
    point b; 
    point c; 
    point d; 
} rectangle; 

double slope(point one, point two) { 
    return (double)(one.y-two.y)/(one.x-two.x); 
} 

double distance(point p, segment s) { 
    // Line one is the original line that was specified, and line two is 
    // the line we're constructing that runs through the specified point, 
    // at a right angle to line one. 
    // 

    // if it's a vertical line return the horizontal distance 
    if (s.one.x == s.two.x)  
     return fabs(s.one.x - p.x); 

    // if it's a horizontal line return the vertical distance 
    if (s.one.y == s.two.y) 
     return fabs(s.one.y - p.y); 

    // otherwise, find the slope of the line 
    double m_one = slope(s.one, s.two); 

    // the other slope is at a right angle. 
    double m_two = -1.0/m_one; 

    // find the y-intercepts. 
    double b_one = s.one.y - s.one.x * m_one; 
    double b_two = p.y - p.x * m_two; 

    // find the point of intersection 
    double x = (b_two - b_one)/(m_one - m_two); 
    double y = m_one * x + b_one; 

    // find the x and y distances 
    double x_dist = x - p.x; 
    double y_dist = y - p.y; 

    // and return the total distance. 
    return sqrt(x_dist * x_dist + y_dist * y_dist); 
} 

bool intersectsCircle(segment s, circle c) { 
    return distance(c.center, s) <= c.radius; 
} 

bool pointInRectangle(point p, rectangle r) 
{ 
    float right = r.p.x + r.width; 
    float left = r.p.x - r.width; 
    float top = r.p.y + r.height; 
    float bottom = r.p.y - r.height; 
    return ((left <= p.x && p.x <= right) && (top <= p.y && p.y <= bottom)); 
} 

bool intersect(circle c, rectangle r) { 
    segment ab; 
    ab.one = r.a; 
    ab.two = r.b; 
    segment bc; 
    ab.one = r.b; 
    ab.two = r.c; 
    segment cd; 
    ab.one = r.c; 
    ab.two = r.d; 
    segment da; 
    ab.one = r.d; 
    ab.two = r.a; 
    return pointInRectangle(c.center, r) || 
          intersectsCircle(ab, c) || 
          intersectsCircle(bc, c) || 
          intersectsCircle(cd, c) || 
          intersectsCircle(da, c); 
} 
+0

Существует полная реализация обнаружения столкновений по кругу/прямоугольнику в вопросе, с которым вы связались. Кроме того, я сомневаюсь, что кто-то захочет помочь, если вы не приложите серьезных усилий и не покажете свои попытки. – patros

ответ

1

Основная часть, которую он, кажется, оставил, - это InteresectsCircle (линия, круг).

#include <math.h> 

typedef struct { 
    double x; 
    double y; 
} point; 

typedef struct { 
    point one; 
    point two; 
} segment; 

typedef struct { 
    point center; 
    double radius; 
} circle; 

double slope(point &one, point &two) { 
    return (double)(one.y-two.y)/(one.x-two.x); 
} 

double distance(point &p, segment &s) { 
// Line one is the original line that was specified, and line two is 
// the line we're constructing that runs through the specified point, 
// at a right angle to line one. 
// 

    // if it's a vertical line return the horizontal distance 
    if (s.one.x == s.two.x)  
     return fabs(s.one.x - p.x); 

    // if it's a horizontal line return the vertical distance 
    if (s.one.y == s.two.y) 
     return fabs(s.one.y - p.y); 

    // otherwise, find the slope of the line 
    double m_one = slope(s.one, s.two); 

    // the other slope is at a right angle. 
    double m_two = -1.0/m_one; 

    // find the y-intercepts. 
    double b_one = s.one.y - s.one.x * m_one; 
    double b_two = p.y - p.x * m_two; 

    // find the point of intersection 
    double x = (b_two - b_one)/(m_one - m_two); 
    double y = m_one * x + b_one; 

    // find the x and y distances 
    double x_dist = x - p.x; 
    double y_dist = y - p.y; 

    // and return the total distance. 
    return sqrt(x_dist * x_dist + y_dist * y_dist); 
} 

bool IntersectsCircle(segment s, circle c) { 
    return distance(circle.center, s) <= circle.radius; 
} 
+0

Большое спасибо :) Я пытаюсь поместить это в свой код, а также реализовать отсутствующую функцию «pointInRectangle», но я не понимаю описание «pointInRectangle»: 0 ≤ AP · AB ≤ AB · AB и 0 ≤ AP · AD ≤ AD · AD Я думаю, что «AP» - это строка «rectangle.a to p» справа? Но как я могу умножить точку, состоящую из двух переменных на что угодно? Спасибо – Neigaard

+0

Привет, Джерри, у вас есть время посмотреть мою попытку и помочь мне? – Neigaard

1

some code in C++ У меня есть (слегка шаблонный), которые должны сделать эти тесты пересечения, но у меня не было времени, чтобы проверить их еще. В частности, у меня есть тест пересечения сегментного круга, а также пересечение параллелограммных кругов, которое должно вычислять площадь пересечения и точки пересечения. Опять же, это совершенно непроверено по поводу написания этого комментария, поэтому вам нужно будет протестировать/адаптировать их к вашим потребностям.