2009-10-15 8 views
3

je besoin d'un algorithme pour détecter si un cercle a frappé un carré, et j'ai vu ce post: Circle-Rectangle collision detection (intersection)détection de collision Cercle-rectangle terminé exampe

On dirait que je devrais aller pour la réponse de ShreevatsaR, mais je suis un maths imbécile, et je n'ai aucune idée de comment finir l'algorithme. Quelqu'un pourrait-il trouver le temps de faire un exemple complet pour moi s'il vous plaît, j'ai cherché sur le net pour cela, et je n'ai encore trouvé aucun exemple de travail.

Merci beaucoup
Soeren

EDIT:

Ok voici ma tentative. Ça ne marche pas, ça ne détecte jamais les collisions.

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

Il existe une implémentation complète de la détection de collision de cercle/rectangle dans la question à laquelle vous avez lié. Au-delà de cela, je doute que quiconque sera prêt à aider à moins que vous ne fassiez un effort sérieux et que vous ne montriez vos tentatives. – patros

Répondre

1

La partie principale qu'il semble avoir quitté est InteresectsCircle (ligne, cercle).

#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

Merci beaucoup :) J'essaie de mettre cela dans mon code, et aussi implémenter la fonction "pointInRectangle" manquant, mais je ne comprends pas la description du "pointInRectangle": 0 ≤ AP · AB ≤ AB · AB et 0 ≤ AP · AD ≤ AD · AD Je suppose que "AP" est la ligne "rectangle.a à p" droite? Mais comment puis-je multiplier un point qui consiste en deux variables à quelque chose? Merci – Neigaard

+0

Salut Jerry, as-tu le temps de regarder ma tentative et de m'aider? – Neigaard

1

je some code in C++ (légèrement basé sur un modèle) qui doit faire ces tests d'intersection, mais je ne l'ai pas eu le temps de les tester encore. En particulier, j'ai le test d'intersection segment-cercle ainsi que l'intersection du parallélogramme-cercle, qui est censé calculer la zone d'intersection et les points d'intersection. Encore une fois, ceci n'a pas été testé depuis la rédaction de ce commentaire, vous devrez donc les tester/les adapter à vos besoins.