提问者:小点点

没有sqrt的两个圆之间的距离检查


我试图在不使用平方根的情况下进行两个圆之间的距离检查。根据网上的许多消息来源(例如这个),这样做的方法是从平方距离中减去圆半径之和的平方(使用毕达哥拉斯定理)。然而,这似乎不起作用。根据Wolfram Alpha和我自己的测试,检查不像sqrt版本那样有效。以下是Wolfram中比较的两个方程:http://www.wolframalpha.com/input/?i=sqrt(d)-(r1+r2)

以及不符合的相关规范:

T DistanceTo(Point p) const {
    return sqrt((p.x - x)*(p.x - x) + (p.y - y)*(p.y - y));
}

T DistanceToSq(Point p) const {
    return (p.x - x)*(p.x - x) + (p.y - y)*(p.y - y);
}

float Unit::GetDistanceTo(Unit * tgt)   const {
    auto dist = _pos.DistanceTo(tgt->GetPos());
    dist -= GetRadius() + tgt->GetRadius();
    return dist;
}
float Unit::GetDistanceToSq(Unit * tgt) const {
    auto dist = _pos.DistanceToSq(tgt->GetPos());
    auto radii = (GetRadius() + tgt->GetRadius());
    dist -= radii * radii;
    return dist;
}

template<typename Func>
void ForEachRange(Unit * owner, float range, Func func = [](Unit * tgt)) {
    auto range_sq = range * range;

    for(Unit * p : m_players) {
        if(owner == p || owner->GetDistanceToSq(p) >= range_sq) {
            if(owner != p && owner->GetDistanceTo(p) < range)
                assert(0);

            continue;
        }

        assert(owner->GetDistanceTo(p) < range);

        func(p);
    }
}

是我做错了什么,还是公式根本不正确?


共2个答案

匿名用户

你问Wolfram Alphasqrt(d)-(r1 r2)

让我们从您的查询中获取第一个不等式并使用代数消除平方根:

sqrt(d) - (r1 + r2) < y
            sqrt(d) < y + r1 + r2
                  d < (y + r1 + r2)²

你看到这与你的第二个不等式有什么不同了吗d-(r1 r2)^2

你可以跟随你的直觉,也可以遵循代数规则,但是其中一个给出了更好的答案。;^)

匿名用户

当您在范围内找到某些内容时,您的for循环不会结束。我认为您想要一个中断而不是继续。当循环未能在范围内找到任何内容时,您还应该有一些东西。