圆形-矩形碰撞检测完成示例

3
我需要一个算法来检测圆是否撞到了正方形,我看到了这篇文章:Circle-Rectangle collision detection (intersection)
看起来我应该选择ShreevatsaR的答案,但我不懂数学,也不知道如何完成算法。请问有人可以为我提供完整的示例吗?我已经在网上搜索过了,但还没有找到可行的示例。
非常感谢
Soeren
编辑:
好的,这是我的尝试。它不起作用,它从未检测到任何碰撞。
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);
}

你所链接的问题中已经有了圆形/矩形碰撞检测的完整实现。除此之外,我怀疑除非你付出真正的努力并展示你的尝试,否则没有人会愿意帮助你。 - patros
2个回答

1
他似乎留下的主要部分是InteresectsCircle(line, circle)。
#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;
}

非常感谢 :) 我正在尝试将此代码放入我的程序中,并实现缺失的“pointInRectangle”函数,但我不理解“pointInRectangle”的描述:0 ≤ AP·AB ≤ AB·AB and 0 ≤ AP·AD ≤ AD·AD我猜“AP”是线段“rectangle.a到p”,对吗?但是我如何将由两个变量组成的点乘以任何东西呢?谢谢 - Neigaard
嗨,Jerry,你有时间看看我的尝试并帮我吗? - Neigaard

1

我有一些用C++编写的代码(轻度模板化),应该可以进行这些交集测试,但我还没有时间来测试它们。特别是,我有线段-圆形相交测试以及平行四边形-圆形相交测试,后者应该计算交集面积和交点。再次强调,在撰写此评论时,这些代码完全未经过测试,因此您需要根据自己的需求进行测试/适应。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接