0

如何在线检测碰撞,最好用鼠标点击?

我不使用 XNA。我只使用简单的 WinForms。而且我不是在创造游戏。

编辑:我从 brone 链接实现了解决方案,得到了非常奇怪的结果。这是小片段。我做错了什么?Pastebin 链接

4

3 回答 3

5

点和线之间的最小距离:

http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/

他的一般几何部分中的更多参考资料:

http://local.wasp.uwa.edu.au/~pbourke/geometry/

于 2009-10-03T23:25:44.557 回答
1

如果您能够使用线性代数,那么您将需要检测从测试点到线段上最近点的距离。

  • 让 AB 成为您的线段。
  • 让 C 成为您的鼠标点。
  • 令 D 为 AB 上的一个点,使得线段 CD 最小。

你想找到CD的长度。因为 AB 和 CD 是垂直的,所以你知道 AB 的斜率是 CD 斜率的倒数。你知道 C 和斜率,所以你可以找到 CD 的一般方程。然后,找到 AB 和 CD 的交点,给出 D 点。

一旦你有了 D 点,找到 CD 的长度就很简单了。如果这个距离小于某个阈值,那么您就知道您点击了您感兴趣的线段附近。

于 2009-10-03T23:09:58.610 回答
0

好吧,我不会费心解释它,因为我不记得它是如何工作的。但我在 C++ 中写了这个……呃…… 1995-ish。我确信有更优雅的方法可以做到这一点,因为当时我只写了大约两年的代码。无论如何,它被转换为 C#:

static bool PointHitSegment(Point[] line, Point hitPoint, int errorMargin)
{
    if (hitPoint.X >= (Math.Max(line[0].X, line[1].X) + errorMargin) ||
        hitPoint.X <= (Math.Min(line[0].X, line[1].X) - errorMargin) ||
        hitPoint.Y >= (Math.Max(line[0].Y, line[1].Y) + errorMargin) ||
        hitPoint.Y <= (Math.Min(line[0].Y, line[1].Y) - errorMargin))
        return false;

    if (line[0].X == line[1].X || line[0].Y == line[1].Y)
        return true;

    double y1, y2, x1, x2;
    double m, b;
    int ny;

    if (Math.Abs(line[0].Y - line[1].Y) <= Math.Abs(line[0].X - line[1].X))
    {
        y1 = line[0].Y;
        y2 = line[1].Y;
        x1 = line[0].X;
        x2 = line[1].X;
    }
    else
    {
        y1 = line[0].X;
        y2 = line[1].X;
        x1 = line[0].Y;
        x2 = line[1].Y;

        int tmp = hitPoint.Y;
        hitPoint.Y = hitPoint.X;
        hitPoint.X = tmp;
    }

    m = (y2 - y1) / (x2 - x1);
    b = y1 - m * x1;

    ny = (int)((m * ((double)hitPoint.X) + b) + 0.5);

    if (Math.Abs(hitPoint.Y - ny) > errorMargin)
        return false;

    return true;
}
于 2009-10-03T23:49:44.023 回答