在线检测碰撞

发布于 2024-08-06 11:59:02 字数 212 浏览 2 评论 0原文

如何检测在线碰撞,最好是通过鼠标单击?

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

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

How do I detect collision on line, preferably with mouse click?

I don't use XNA. I use just simple WinForms. And I'm not creating a game.

EDIT: I implemented solution from brone link and got really weird results. Here's small snippet. What I'm doing wrong? Pastebin link

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

余罪 2024-08-13 11:59:02

点与线之间的最小距离:

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

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

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

Minimum Distance between a Point and a Line:

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

More referenece material in his general geometry section:

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

ι不睡觉的鱼゛ 2024-08-13 11:59:02

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

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

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

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

If you're able to use linear algebra, then you'll want to detect the distance from your test point, to the nearest point on your line segment.

  • Let AB be your line Segment.
  • Let C be your mouse point.
  • Let D be a point on AB such that the line segment CD is minimal.

You want to find the length of CD. Since AB and CD are perpendicular, you know that the slope of AB is the inverse reciprocal of the slope of CD. You know C, and a slope, so you can find the general equation for CD. Then, find the intersection of AB and CD, giving you point D.

Once you have point D, finding the length of CD is trivial. If this distance is less than some threshold value, then you know you've clicked near the line segment you're interested in.

风和你 2024-08-13 11:59:02

好吧,我不会费心解释它,因为我不记得这是如何工作的。但我早在……呃……1995 年左右就用 C++ 写了这个。我确信有更优雅的方法可以做到这一点,因为当时我只编写了大约两年的代码。无论如何,这里它被转换为 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;
}

Well, I won't bother explaining it since I don't remember how this works. But I wrote this in C++ back in ... uh... 1995-ish. I'm certain there are much more elegant ways of doing this since I'd only been writing code for about two years at the time. Anyway here it is converted to 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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文