Results 1 to 12 of 12

Thread: [RESOLVED] Find proximity of controls to selected control

  1. #1

    Thread Starter
    Member VisualBrian's Avatar
    Join Date
    Nov 2019
    Location
    North America
    Posts
    61

    Resolved [RESOLVED] Find proximity of controls to selected control

    I've created a map where I can create/place/drag rooms around to link them up. This is the basis for an adventure story creator.
    Name:  roomz-1.jpg
Views: 309
Size:  17.0 KB

    I'm trying to write the code to check and determine whether two controls (rooms) are linked (next to each other). While this is simple when all the rooms are the same size, it quickly becomes convoluted when they are different sizes/shapes.

    Code:
        Private Sub Room_MouseMove(ByVal sender As System.Object, ByVal e As System.EventArgs)
            FormEditor.LabelPortals.Text = sender.name & " - Right click to edit. Links to"
            ' detect portals
            For Each ctrl In Me.Controls.Cast(Of Control)().ToArray()
                If ctrl.Tag = "room" And Not ctrl Is sender Then
                    ' small rooms
                    ' north
                    If ctrl.Top + GridSize = sender.top And ctrl.Left = sender.left Then
                        FormEditor.LabelPortals.Text &= " - " & ctrl.Name
                    End If
                    ' south
                    If ctrl.Top = sender.top + GridSize And ctrl.Left = sender.left Then
                        FormEditor.LabelPortals.Text &= " - " & ctrl.Name
                    End If
                    ' west
                    If ctrl.Left = sender.left - GridSize And ctrl.Top = sender.top Then
                        FormEditor.LabelPortals.Text &= " - " & ctrl.Name
                    End If
                    ' east
                    If ctrl.Left = sender.left + GridSize And ctrl.Top = sender.top Then
                        FormEditor.LabelPortals.Text &= " - " & ctrl.Name
                    End If
                    ' large rooms
                    ' north
                    If ctrl.Width = GridSize * 2 And ctrl.Height = GridSize * 2 And _
                        ctrl.Top = sender.Top - GridSize * 2 And ctrl.Left = sender.left Or ctrl.Left = sender.left - GridSize Then
                        FormEditor.LabelPortals.Text &= " - " & ctrl.Name
                    End If
                End If
            Next
        End Sub
    I'm sure there is a better way to do this, but I'm not sure what it would be or what to search for. Any help is appreciated.
    I may not know anything, but I know it well!

  2. #2
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,613

    Re: Find proximity of controls to selected control

    I would suggest you create a class to hold the information for each room. This class could be put into the .Tag property of the control, or it could contain the control as a member. If all the rooms will be square, then you could have a List(of yourClass) for North, South, East, and West. Then, figuring out what bounded what would be a matter of checking the list for any particular class.
    My usual boring signature: Nothing

  3. #3

    Thread Starter
    Member VisualBrian's Avatar
    Join Date
    Nov 2019
    Location
    North America
    Posts
    61

    Re: Find proximity of controls to selected control

    Right now, the .Tag property holds something else as shown in the code and all the rooms are not square as shown in the pic. Some are wide, some tall, some large, some small. The small, square rooms are simple and that works fine in the code above. It's the different shaped and sized rooms that become difficult.
    I may not know anything, but I know it well!

  4. #4

    Thread Starter
    Member VisualBrian's Avatar
    Join Date
    Nov 2019
    Location
    North America
    Posts
    61

    Re: Find proximity of controls to selected control

    The only thing I've been able to think of is to move each control (room) 1 pixel in all 4 directions and check its bounds against the selected room bounds.

    Code:
            For Each ctrl In Me.Controls.Cast(Of Control)().ToArray()
                If ctrl.Tag = "room" And Not ctrl Is sender Then
                    ' north
                    ctrl.Top += 1
                    If ctrl.Bounds.IntersectsWith(sender.bounds) Then
                        FormEditor.LabelPortals.Text &= " - " & ctrl.Name
                    End If
                    ctrl.Top -= 1
                    ' south
                    ctrl.Top -= 1
                    If ctrl.Bounds.IntersectsWith(sender.bounds) Then
                        FormEditor.LabelPortals.Text &= " - " & ctrl.Name
                    End If
                    ctrl.Top += 1
                    ' west
                    ctrl.Left += 1
                    If ctrl.Bounds.IntersectsWith(sender.bounds) Then
                        FormEditor.LabelPortals.Text &= " - " & ctrl.Name
                    End If
                    ctrl.Left -= 1
                    ' east
                    ctrl.Left -= 1
                    If ctrl.Bounds.IntersectsWith(sender.bounds) Then
                        FormEditor.LabelPortals.Text &= " - " & ctrl.Name
                    End If
                    ctrl.Left += 1
                End If
            Next
    This gives me a readout of all rooms linked to the selected room and works, though it seems there is probably a better way to do it. Any thoughts are appreciated.
    I may not know anything, but I know it well!

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,613

    Re: Find proximity of controls to selected control

    The .Tag can hold anything. You have it holding some trivial string. That string could just as easily be the class I was talking about. For the check you are showing, you'd just be checking Is YourClass rather than = SomeString.

    I also didn't mean to leave square in there. It doesn't matter whether or not it's technically square, that's why I was saying that there should be a list for each side such that there can be multiple items adjacent to any side. The key point is that the room is at least a convex shape, and if that is some form of rectangle, as shown, that's even easier. Room 6 has one room to the south (room 9), one room to the east (room 7) and one room to the west (room 0). However, room 6 could have two rooms to the north, though you currently have none.

    Furthermore, if you're image is anything like what you are actually doing, you could say that room 9 is in south slot 0 for room 6, while nothing is in south slot 1 for room 6. Each room would have a predictable number of slots based on it's size.
    My usual boring signature: Nothing

  6. #6

    Thread Starter
    Member VisualBrian's Avatar
    Join Date
    Nov 2019
    Location
    North America
    Posts
    61

    Re: Find proximity of controls to selected control

    Sorry I'm not that advanced and have no formal training. I just do this for fun in my retirement. I have no idea how what you said would tell me which rooms border any selected room.
    But thanks for responding.
    I may not know anything, but I know it well!

  7. #7
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,364

    Re: Find proximity of controls to selected control

    Quote Originally Posted by VisualBrian View Post
    Sorry I'm not that advanced and have no formal training. I just do this for fun in my retirement. I have no idea how what you said would tell me which rooms border any selected room.
    But thanks for responding.
    In Shaggy’s answer, west would be to the left of, east, to the right of, north would be above and south below
    Imagine your smallest box being 30*30 pixels, the next size being 30*60 or 60*30, you can see how 1 unit could be 30*30

  8. #8

    Thread Starter
    Member VisualBrian's Avatar
    Join Date
    Nov 2019
    Location
    North America
    Posts
    61

    Re: Find proximity of controls to selected control

    Quote Originally Posted by .paul. View Post
    In Shaggy’s answer, west would be to the left of, east, to the right of, north would be above and south below
    Imagine your smallest box being 30*30 pixels, the next size being 30*60 or 60*30, you can see how 1 unit could be 30*30
    Yes, thank you. I have all that and all the info about each room is already recorded to file as it's changed, on the fly: name, tag, width, height, left, top, text, image, etc.
    I'm only working on a quick way to grab the names of any rooms which borders the room I click on so those room names can be added to a list. When the map is built, the links to those rooms are automatically inserted in the story text of the room to allow the player to proceed to another available room. The code above works well, but I'll know better when there are more rooms. I'm just thinking that there is a better way to accomplish it.
    I may not know anything, but I know it well!

  9. #9
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,613

    Re: Find proximity of controls to selected control

    I did something like this a while back, but I had both rectangular and triangular shapes. Figuring out the boundaries in an efficient manner was a challenge. It was far enough back that I don't remember it all, though, so that doesn't help much. The key to remember is that memory is cheap. Keeping lists of what bounds what, which room is accessible from the others, or any other arrangement that makes sense is fine, even if it means multiple options.

    One other suggestion is that, since everything is a rectangle, you don't need to change the size of any control. Instead, every control has a bounds, which is a rectangle. Suppose you have a room that has the left,top of (120,150). To figure out what is to the east of that, you could take a point that is (left - 15, top + 15) That would be a point that is to the left of the room. The Rectangle structure has a method that returns true if a point is within it. So, you could check whether any controls contain that point, if so, then they bound the room in question on that side. For a room that was 30 wide and 60 high, the points would be (left-15,top+15) and (left-15, top+45) for rooms on the left, (left+15,top-15) for rooms above, (left+15, top+height+15) for rooms below, and (left+width+15,top+15) and (left+weidth+15,top+45) for rooms on the right. Given any room and any size, so long as all sides are multiples of 30, the points that need to be checked can be calculated pretty easily from the control in question.
    My usual boring signature: Nothing

  10. #10

    Thread Starter
    Member VisualBrian's Avatar
    Join Date
    Nov 2019
    Location
    North America
    Posts
    61

    Re: Find proximity of controls to selected control

    The Rectangle structure has a method that returns true if a point is within it.
    @Shaggy Hiker

    That sounds promising and thanks for explaining it so well. As the map becomes more populated it will be interesting to see which method is most efficient.
    I may not know anything, but I know it well!

  11. #11
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    38,613

    Re: Find proximity of controls to selected control

    The rectangle methods are VERY efficient, so any time you can make use of them, do so. Anything that could move or change the size of a control could easily end up having a costly side effect simply because it will force the control to paint itself.
    My usual boring signature: Nothing

  12. #12

    Thread Starter
    Member VisualBrian's Avatar
    Join Date
    Nov 2019
    Location
    North America
    Posts
    61

    Re: Find proximity of controls to selected control

    Quote Originally Posted by Shaggy Hiker View Post
    The rectangle methods are VERY efficient, so any time you can make use of them, do so. Anything that could move or change the size of a control could easily end up having a costly side effect simply because it will force the control to paint itself.
    Makes a lot of sense. Thanks.
    I may not know anything, but I know it well!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width