2009-10-15 174 views
3

我需要一个算法来检测,如果一个圆已经打了一个广场,我看到了这个帖子: Circle-Rectangle collision detection (intersection)圆矩形碰撞检测完成exampe

它看起来像我应该去ShreevatsaR的回答,但我是一个数学傻瓜,我不知道如何完成算法。任何人都可以找到时间为我做一个完整的例子,我已经在网上搜索了这个,但还没有找到工作的例子。

非常感谢您
索伦

编辑:

确定这里是我的尝试。它不工作,它从未检测到任何碰撞。

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 2009-10-15 18:53:57

回答

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到p”的权利?但是,我怎样才能将包含两个变量的点相乘? 谢谢 – Neigaard 2009-10-16 10:59:37

+0

嗨,杰里,你有时间看看我的尝试并帮助我吗? – Neigaard 2009-10-17 05:29:45

1

我有some code in C++(轻度模板)应该做这些路口测试,但我还没有时间来检验他们没有。特别是,我有分段圆交叉点测试以及平行四边形交叉点,它应该计算交叉区域和交点。同样,在撰写评论时,这完全没有经过测试,因此您需要测试/调整它们以满足您的需求。