-
Dec 16th, 2013, 05:33 PM
#1
[Vb.Net] Pathfinder
There has been a major update. See post #4.
I've been very interested in path finding for a while now and decided to make one myself.
Features:
- A panel that draws up a grid. The grid is determined by the NodeHeightCount, NodeWidthCount, and NodeSize.
- Fills up the nodes by calling the FillPath method
- Clears the path by calling the ClearPath method
Drawbacks:
- A very slow and brutal approach
- Doesn't allow for "Blocked" nodes
Plans:
I plan on studying some other methods of path finding such as the famous A* algorithm and adjusting my code accordingly.
Notes:
The way that the program works is it first checks if the current node we are on is the end, if it is, then exit out. Next it checks if we can move up/down or left/right based on where the end node is in relation to the current node. If so, then move accordingly.
Image:
Code:
Code:
Public Class Grid
Inherits Windows.Forms.Panel
#Region "Node Properties"
Private beginning_node As Point = New Point(0, 0)
Public Property BeginningNode() As Point
Get
Return beginning_node
End Get
Set(ByVal value As Point)
If value.X > nodes_left - 1 Then
value.X = nodes_left - 1
value.Y = value.Y
ElseIf value.X < 0 Then
value.X = 0
value.Y = value.Y
End If
If value.Y > nodes_height - 1 Then
value.Y = nodes_height - 1
ElseIf value.Y < 0 Then
value.Y = 0
End If
beginning_node = value : Me.Invalidate()
End Set
End Property
Private end_node As Point = New Point(1, 1)
Public Property EndNode() As Point
Get
Return end_node
End Get
Set(ByVal value As Point)
If value.X > nodes_left - 1 Then
value.X = nodes_left - 1
value.Y = value.Y
ElseIf value.X < 0 Then
value.X = 0
value.Y = value.Y
End If
If value.Y > nodes_height - 1 Then
value.Y = nodes_height - 1
ElseIf value.Y < 0 Then
value.Y = 0
End If
If value = beginning_node Then value = New Point(1, 1)
end_node = value : Me.Invalidate()
End Set
End Property
Private _nodes As New List(Of Point)
Public ReadOnly Property Nodes() As List(Of Point)
Get
Return _nodes
End Get
End Property
Private node_default_color As Color = Me.BackColor
<System.ComponentModel.Description("Node")> Public Property NodeDefaultColor() As Color
Get
Return node_default_color
End Get
Set(ByVal value As Color)
node_default_color = value : Me.Invalidate()
End Set
End Property
Private nodes_height As Integer = 12
<System.ComponentModel.Description("Node")> Public Property NodeHeightCount() As Integer
Get
Return nodes_height
End Get
Set(ByVal value As Integer)
If value < 1 Then value = 1
nodes_height = value : Me.Invalidate()
End Set
End Property
Private node_selected_color As Color = Me.BackColor
<System.ComponentModel.Description("Node")> Public Property NodeSelectedColor() As Color
Get
Return node_selected_color
End Get
Set(ByVal value As Color)
node_selected_color = value : Me.Invalidate()
End Set
End Property
Private node_size As Size = New Size(25, 25)
<System.ComponentModel.Description("Node")> Public Property NodeSize() As Size
Get
Return node_size
End Get
Set(ByVal value As Size)
node_size = value : Me.Invalidate()
End Set
End Property
Private nodes_left As Integer = 12
<System.ComponentModel.Description("Node")> Public Property NodeWidthCount() As Integer
Get
Return nodes_left
End Get
Set(ByVal value As Integer)
If value < 1 Then value = 1
nodes_left = value : Me.Invalidate()
End Set
End Property
#End Region
#Region "Methods"
Public Sub FindPath()
'Clear existing points
Call ClearPath()
'Get a start node
Dim start_node As Point = beginning_node
'Get if the path is to the left or to the rigth
Dim horizontal_movement As Direction
'Get if the path is to the up or to the down
Dim vertical_movement As Direction
If beginning_node.X < end_node.X Then
horizontal_movement = Direction.Right
ElseIf beginning_node.X > end_node.X Then
horizontal_movement = Direction.Left
Else
horizontal_movement = Direction.None
End If
If beginning_node.Y < end_node.Y Then
vertical_movement = Direction.Down
ElseIf beginning_node.Y > end_node.Y Then
vertical_movement = Direction.Up
Else
vertical_movement = Direction.None
End If
'If vertical movement or horizontal movement is nothing then we either move only up or only down
If horizontal_movement = Direction.None Then
Dim _step As Integer = 1
If vertical_movement = Direction.Up Then
_step = -_step
End If
For i As Integer = beginning_node.Y To end_node.Y Step _step
_nodes.Add(New Point(beginning_node.X, i))
Next
ElseIf vertical_movement = Direction.None Then
Dim _step As Integer = 1
If horizontal_movement = Direction.Left Then
_step = -_step
End If
For i As Integer = beginning_node.X To end_node.X Step _step
_nodes.Add(New Point(i, beginning_node.Y))
Next
Else
Dim temp_nodes As New List(Of Point)
temp_nodes.Add(New Point(beginning_node.X, beginning_node.Y))
Do Until horizontal_movement = Direction.None AndAlso vertical_movement = Direction.None
Dim current_node As Point = temp_nodes.Item(temp_nodes.Count - 1)
If current_node = end_node Then
horizontal_movement = Direction.None
vertical_movement = Direction.None
Else
If current_node.X < end_node.X Then
horizontal_movement = Direction.Right
ElseIf current_node.X > end_node.X Then
horizontal_movement = Direction.Left
Else
horizontal_movement = Direction.None
End If
If current_node.Y < end_node.Y Then
vertical_movement = Direction.Down
ElseIf current_node.Y > end_node.Y Then
vertical_movement = Direction.Up
Else
vertical_movement = Direction.None
End If
End If
If horizontal_movement = Direction.Right Then
current_node = New Point(current_node.X + 1, current_node.Y)
ElseIf horizontal_movement = Direction.Left Then
current_node = New Point(current_node.X - 1, current_node.Y)
End If
If vertical_movement = Direction.Down Then
current_node = New Point(current_node.X, current_node.Y + 1)
ElseIf vertical_movement = Direction.Up Then
current_node = New Point(current_node.X, current_node.Y - 1)
End If
temp_nodes.Add(New Point(current_node.X, current_node.Y))
Loop
_nodes = temp_nodes
End If
Me.Invalidate()
End Sub
Public Sub ClearPath()
_nodes.Clear()
Me.Invalidate()
End Sub
#End Region
Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
For x As Integer = 0 To nodes_left - 1
For y As Integer = 0 To nodes_height - 1
Dim pt As New Point(x, y)
If pt = beginning_node OrElse _
pt = end_node OrElse _
_nodes.Contains(pt) Then
e.Graphics.FillRectangle(New SolidBrush(node_selected_color), New Rectangle(New Point(pt.X * node_size.Width, pt.Y * node_size.Height), node_size))
Else
e.Graphics.FillRectangle(New SolidBrush(node_default_color), New Rectangle(New Point(pt.X * node_size.Width, pt.Y * node_size.Height), node_size))
End If
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(New Point(pt.X * node_size.Width, pt.Y * node_size.Height), node_size))
Next
Next
For Each node As Point In _nodes
e.Graphics.FillRectangle(New SolidBrush(node_selected_color), New Rectangle(New Point(node.X * node_size.Width, node.Y * node_size.Height), node_size))
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(New Point(node.X * node_size.Width, node.Y * node_size.Height), node_size))
Next
End Sub
Private Enum Direction
Up
Down
Left
Right
None
End Enum
End Class
Last edited by dday9; Apr 17th, 2014 at 11:36 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|