确定哪些对象落在选择矩形(选取框)内

发布于 2024-10-01 19:45:10 字数 295 浏览 5 评论 0原文

我正在编写一个程序(除其他外)为用户提供类似 IDE 的环境,用户可以在其中使用矩形选择工具选择一个或多个对象。

所有选择都将是一个简单的矩形,所有可选择的对象也将是简单的矩形。

我已经有了代码(VB.Net)来在视觉上创建橡皮筋效果 - 我需要的是一种有效的算法,它可以告诉我哪些对象的至少一部分区域位于最终选择矩形内。

如果它有助于可视化,我想要做的将与在 Windows 桌面上的图标上拖动选择框相同...无论哪个图标的部分区域位于该选择选取框内,都会突出显示(选定)。

任何帮助将不胜感激...提前谢谢您

I'm writing a program that (amongst other things) provides an IDE-like environment for the user where they can select one or more objects with a rectangualr selection tool.

All selections will be a simple rectangle, and all selectable objects will be simple rectangles as well.

I already have the code (VB.Net) to create the rubber-banding effect visually - what I need is an efficient algorithm that will tell me what objects have at least a portion of their area within the final selection rectangle.

If it helps to visualize, what I want to do would be identical to dragging a selection box over icons on the Windows desktop... whichever icons have even a portion of their areas located within that selection marquee are highlighted (selected).

Any help would be appreciated... thank you in advance

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

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

发布评论

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

评论(2

乖乖 2024-10-08 19:45:10
Dim Rect1 As New Rectangle(10, 10, 20, 20)
Dim Rect2 As New Rectangle(5, 5, 20, 20)

Debug.Print(Rect1.IntersectsWith(Rect2))
Dim Rect1 As New Rectangle(10, 10, 20, 20)
Dim Rect2 As New Rectangle(5, 5, 20, 20)

Debug.Print(Rect1.IntersectsWith(Rect2))
醉生梦死 2024-10-08 19:45:10

IntersectsWith 的作用如下BigFunger 已经提到过。但此外,您应该检查矩形是否 包含 另一个矩形(intersectsWith 仅检查相交)。

一个小样本表格演示了它:

Public Class SelectionRectangle
    Private first As Point
    Private allRectangles As New List(Of RectangleF)

    Private Sub form_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseDown
        first = New Point(e.X, e.Y)
    End Sub

    Private Sub form_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseUp
        Dim p As New Pen(Brushes.Black, 2)
        Dim g As Graphics
        Dim second As New Point(e.X, e.Y)
        Dim x, y, w, h As Int32
        x = DirectCast(IIf(first.X > second.X, second.X, first.X), Int32)
        y = DirectCast(IIf(first.Y > second.Y, second.Y, first.Y), Int32)
        w = Math.Abs(second.X - first.X)
        h = Math.Abs(second.Y - first.Y)
        Dim nextRec As New RectangleF(x, y, w, h)
        Dim intersects As Boolean = False
        For Each rec As RectangleF In allRectangles
            If rec.Contains(nextRec) OrElse rec.IntersectsWith(nextRec) Then
                intersects = True
                Exit For
            End If
        Next
        If Not intersects Then
            p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot
            g = Me.CreateGraphics()
            g.DrawLine(p, first.X, first.Y, second.X, first.Y)
            g.DrawLine(p, second.X, second.Y, first.X, second.Y)
            g.DrawLine(p, first.X, first.Y, first.X, second.Y)
            g.DrawLine(p, second.X, second.Y, second.X, first.Y)
            allRectangles.Add(nextRec)
        Else
            Beep()
        End If
    End Sub
End Class

更新:将此代码更改为 1.首先在两个方向上进行检查,2.对您来说更重要的是:还检查一个矩形是否不仅与另一个矩形相交,而且还检查是否它包含另一个。

IntersectsWith works as BigFunger already has mentioned. But aditionally you should check if a rectangle contains another rectangle(intersectsWith only checks for intersection).

A small sample-form that demonstrates it:

Public Class SelectionRectangle
    Private first As Point
    Private allRectangles As New List(Of RectangleF)

    Private Sub form_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseDown
        first = New Point(e.X, e.Y)
    End Sub

    Private Sub form_MouseUp(ByVal sender As Object, ByVal e As MouseEventArgs) Handles Me.MouseUp
        Dim p As New Pen(Brushes.Black, 2)
        Dim g As Graphics
        Dim second As New Point(e.X, e.Y)
        Dim x, y, w, h As Int32
        x = DirectCast(IIf(first.X > second.X, second.X, first.X), Int32)
        y = DirectCast(IIf(first.Y > second.Y, second.Y, first.Y), Int32)
        w = Math.Abs(second.X - first.X)
        h = Math.Abs(second.Y - first.Y)
        Dim nextRec As New RectangleF(x, y, w, h)
        Dim intersects As Boolean = False
        For Each rec As RectangleF In allRectangles
            If rec.Contains(nextRec) OrElse rec.IntersectsWith(nextRec) Then
                intersects = True
                Exit For
            End If
        Next
        If Not intersects Then
            p.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot
            g = Me.CreateGraphics()
            g.DrawLine(p, first.X, first.Y, second.X, first.Y)
            g.DrawLine(p, second.X, second.Y, first.X, second.Y)
            g.DrawLine(p, first.X, first.Y, first.X, second.Y)
            g.DrawLine(p, second.X, second.Y, second.X, first.Y)
            allRectangles.Add(nextRec)
        Else
            Beep()
        End If
    End Sub
End Class

UPDATE: changed this code to 1.first check in both directions and 2. and more important for you: checks also if one rectangle not only intersects another but additionally if it contains another.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文