📄 steeringbehavior.vb
字号:
'// -- Group Behaviors -- //
'//-------------------------------- Cohesion ------------------------------
'//
'// returns a steering force that attempts to move the agent towards the
'// center of mass of the agents in its immediate area
'//------------------------------------------------------------------------
Private Function Cohesion(ByVal neighbors As ArrayList) As Vector2D
'//first find the center of mass of all the agents
Dim CenterOfMass, SteeringForce As Vector2D
Dim NeighborCount As Integer = 0
'//iterate through the neighbors and sum up all the position vectors
Dim a As Integer
For a = 0 To neighbors.Count - 1
'//make sure *this* agent isn't included in the calculations and that
'//the agent being examined is close enough ***also make sure it doesn't
'//include the evade target ***
If (Not neighbors(a) Is m_pVehicle) And CType(neighbors(a), Vehicle).IsTagged() And (Not neighbors(a) Is m_pTargetAgent1) Then
CenterOfMass.PlusEqual(CType(neighbors(a), Vehicle).Pos())
NeighborCount += 1
End If
Next
If NeighborCount > 0 Then
'//the center of mass is the average of the sum of positions
CenterOfMass.DividedEqual(CDbl(NeighborCount))
'//now seek towards that position
SteeringForce = Seek(CenterOfMass)
End If
'//the magnitude of cohesion is usually much larger than separation or
'//allignment so it usually helps to normalize it.
Return Vector2D.Vec2DNormalize(SteeringForce)
End Function
'//---------------------------- Separation --------------------------------
'//
'// this calculates a force repelling from the other neighbors
'//------------------------------------------------------------------------
Private Function Separation(ByVal neighbors As ArrayList) As Vector2D
Dim SteeringForce As Vector2D
Dim a As Integer
For a = 0 To neighbors.Count - 1
'//make sure this agent isn't included in the calculations and that
'//the agent being examined is close enough. ***also make sure it doesn't
'//include the evade target ***
If (Not neighbors(a) Is m_pVehicle) And CType(neighbors(a), Vehicle).IsTagged() And (Not neighbors(a) Is m_pTargetAgent1) Then
Dim ToAgent As Vector2D = m_pVehicle.Pos().Minus(CType(neighbors(a), Vehicle).Pos())
'//scale the force inversely proportional to the agents distance
'//from its neighbor.
SteeringForce.PlusEqual(Vector2D.Vec2DNormalize(ToAgent).Divided(ToAgent.Length()))
End If
Next
Return SteeringForce
End Function
'//---------------------------- Alignment ---------------------------------
'//
'// returns a force that attempts to align this agents heading with that
'// of its neighbors
'//------------------------------------------------------------------------
Private Function Alignment(ByVal neighbors As ArrayList) As Vector2D
'//used to record the average heading of the neighbors
Dim AverageHeading As Vector2D
'//used to count the number of vehicles in the neighborhood
Dim NeighborCount As Integer = 0
'//iterate through all the tagged vehicles and sum their heading vectors
Dim a As Integer
For a = 0 To neighbors.Count - 1
'//make sure *this* agent isn't included in the calculations and that
'//the agent being examined is close enough ***also make sure it doesn't
'//include any evade target ***
If (Not neighbors(a) Is m_pVehicle) And CType(neighbors(a), Vehicle).IsTagged() And (Not neighbors(a) Is m_pTargetAgent1) Then
AverageHeading.PlusEqual(CType(neighbors(a), Vehicle).Heading())
NeighborCount += 1
End If
Next
'//if the neighborhood contained one or more vehicles, average their
'//heading vectors.
If (NeighborCount > 0) Then
AverageHeading.DividedEqual(CDbl(NeighborCount))
AverageHeading.MinusEqual(m_pVehicle.Heading())
End If
Return AverageHeading
End Function
'//the following three are the same as above but they use cell-space
'//partitioning to find the neighbors
'//-------------------------------- Cohesion ------------------------------
'//
'// returns a steering force that attempts to move the agent towards the
'// center of mass of the agents in its immediate area
'//
'// USES SPACIAL PARTITIONING
'//------------------------------------------------------------------------
Private Function CohesionPlus(ByVal neighbors As ArrayList) As Vector2D
'//first find the center of mass of all the agents
Dim CenterOfMass, SteeringForce As Vector2D
Dim NeighborCount As Integer = 0
'//iterate through the neighbors and sum up all the position vectors
Dim i As Integer
Dim pV As Vehicle
For i = 0 To m_pVehicle.World.CellSpace.Neighbors.Count - 1
'//make sure *this* agent isn't included in the calculations and that
'//the agent being examined is close enough
pV = m_pVehicle.World.CellSpace.Neighbors(i)
If Not pV Is m_pVehicle Then
Dim ToAgent As Vector2D = m_pVehicle.Pos().Plus(pV.Pos())
'//scale the force inversely proportional to the agents distance
'//from its neighbor.
CenterOfMass.PlusEqual(pV.Heading)
NeighborCount += 1
End If
Next
If (NeighborCount > 0) Then
'//the center of mass is the average of the sum of positions
CenterOfMass.DividedEqual(CDbl(NeighborCount))
'//now seek towards that position
SteeringForce = Seek(CenterOfMass)
End If
'//the magnitude of cohesion is usually much larger than separation or
'//allignment so it usually helps to normalize it.
Return Vector2D.Vec2DNormalize(SteeringForce)
End Function
'//---------------------------- Separation --------------------------------
'//
'// this calculates a force repelling from the other neighbors
'//
'// USES SPACIAL PARTITIONING
'//------------------------------------------------------------------------
Private Function SeparationPlus(ByVal agents As ArrayList) As Vector2D
Dim SteeringForce As Vector2D
'//iterate through the neighbors and sum up all the position vectors
Dim i As Integer
Dim pV As Vehicle
For i = 0 To m_pVehicle.World.CellSpace.Neighbors.Count - 1
'//make sure this agent isn't included in the calculations and that
'//the agent being examined is close enough
pV = m_pVehicle.World.CellSpace.Neighbors(i)
If Not pV Is m_pVehicle Then
Dim ToAgent As Vector2D = m_pVehicle.Pos().Plus(pV.Pos())
'//scale the force inversely proportional to the agents distance
'//from its neighbor.
SteeringForce.PlusEqual(Vector2D.Vec2DNormalize(ToAgent).Divided(ToAgent.Length()))
End If
Next
Return SteeringForce
End Function
'//---------------------------- Alignment ---------------------------------
'//
'// returns a force that attempts to align this agents heading with that
'// of its neighbors
'//
'// USES SPACIAL PARTITIONING
'//------------------------------------------------------------------------
Private Function AlignmentPlus(ByVal agents As ArrayList) As Vector2D
'//This will record the average heading of the neighbors
Dim AverageHeading As Vector2D
'//This count the number of vehicles in the neighborhood
Dim NeighborCount As Double = 0.0
'//iterate through the neighbors and sum up all the position vectors
Dim i As Integer
Dim pV As Vehicle
For i = 0 To m_pVehicle.World.CellSpace.Neighbors.Count - 1
'//make sure this agent isn't included in the calculations and that
'//the agent being examined is close enough
pV = m_pVehicle.World.CellSpace.Neighbors(i)
If Not pV Is m_pVehicle Then
Dim ToAgent As Vector2D = m_pVehicle.Pos().Plus(pV.Pos())
AverageHeading.PlusEqual(pV.Heading)
NeighborCount += 1
End If
Next
'//if the neighborhood contained one or more vehicles, average their
'//heading vectors.
If (NeighborCount > 0.0) Then
AverageHeading.DividedEqual(NeighborCount)
AverageHeading.MinusEqual(m_pVehicle.Heading())
End If
Return AverageHeading
End Function
'/* .......................................................
' END BEHAVIOR DECLARATIONS
'.......................................................*/
'//calculates and sums the steering forces from any active behaviors
'//---------------------- CalculateWeightedSum ----------------------------
'//
'// this simply sums up all the active behaviors X their weights and
'// truncates the result to the max available steering force before
'// returning
'//------------------------------------------------------------------------
Private Function CalculateWeightedSum() As Vector2D
If IsOn(behavior_type.wall_avoidance) Then
m_vSteeringForce.PlusEqual(WallAvoidance(m_pVehicle.World().Walls()).Mutiply(m_dWeightWallAvoidance))
End If
If IsOn(behavior_type.obstacle_avoidance) Then
m_vSteeringForce.PlusEqual(ObstacleAvoidance(m_pVehicle.World().Obstacles()).Mutiply(m_dWeightObstacleAvoidance))
End If
If IsOn(behavior_type.evade) Then
'assert(m_pTargetAgent1 && "Evade target not assigned");
m_vSteeringForce.PlusEqual(Evade(m_pTargetAgent1).Mutiply(m_dWeightEvade))
End If
'//these next three can be combined for flocking behavior (wander is
'//also a good behavior to add into this mix)
If Not isSpacePartitioningOn() Then
If IsOn(behavior_type.separation) Then
m_vSteeringForce.PlusEqual(Separation(m_pVehicle.World().Agents()).Mutiply(m_dWeightSeparation))
End If
If IsOn(behavior_type.allignment) Then
m_vSteeringForce.PlusEqual(Alignment(m_pVehicle.World().Agents()).Mutiply(m_dWeightAlignment))
End If
If IsOn(behavior_type.cohesion) Then
m_vSteeringForce.PlusEqual(Cohesion(m_pVehicle.World().Agents()).Mutiply(m_dWeightCohesion))
End If
Else
If IsOn(behavior_type.separation) Then
m_vSteeringForce.PlusEqual(SeparationPlus(m_pVehicle.World().Agents()).Mutiply(m_dWeightSeparation))
End If
If IsOn(behavior_type.allignment) Then
m_vSteeringForce.PlusEqual(AlignmentPlus(m_pVehicle.World().Agents()).Mutiply(m_dWeightAlignment))
End If
If IsOn(behavior_type.cohesion) Then
m_vSteeringForce.PlusEqual(CohesionPlus(m_pVehicle.World().Agents()).Mutiply(m_dWeightCohesion))
End If
End If
If IsOn(behavior_type.wander) Then
m_vSteeringForce.PlusEqual(Wander().Mutiply(m_dWeightWander))
End If
If IsOn(behavior_type.seek) Then
m_vSteeringForce.PlusEqual(Seek(m_pVehicle.World().Crosshair()).Mutiply(m_dWeightSeek))
End If
If IsOn(behavior_type.flee) Then
m_vSteeringForce.PlusEqual(Flee(m_pVehicle.World().Crosshair()).Mutiply(m_dWeightFlee))
End If
If IsOn(behavior_type.arrive) Then
m_vSteeringForce.PlusEqual(Arrive(m_pVehicle.World().Crosshair(), m_Deceleration).Mutiply(m_dWeightArrive))
End If
If IsOn(behavior_type.pursuit) Then
'assert(m_pTargetAgent1 && "pursuit target not assigned");
m_vSteeringForce.PlusEqual(Pursuit(m_pTargetAgent1).Mutiply(m_dWeightPursuit))
End If
If IsOn(behavior_type.offset_pursuit) Then
'assert (m_pTargetAgent1 && "pursuit target not assigned");
'assert (!m_vOffset.isZero() && "No offset assigned");
m_vSteeringForce.PlusEqual(OffsetPursuit(m_pTargetAgent1, m_vOffset).Mutiply(m_dWeightOffsetPursuit))
End If
If IsOn(behavior_type.interpose) Then
'assert (m_pTargetAgent1 && m_pTargetAgent2 && "Interpose agents not assigned");
m_vSteeringForce.PlusEqual(Interpose(m_pTargetAgent1, m_pTargetAgent2).Mutiply(m_dWeightInterpose))
End If
If IsOn(behavior_type.hide) Then
'assert(m_pTargetAgent1 && "Hide target not assigned");
m_vSteeringForce.PlusEqual(Hide(m_pTargetAgent1, m_pVehicle.World().Obstacles()).Mutiply(m_dWeightHide))
End If
If IsOn(behavior_type.follow_path) Then
m_vSteeringForce.PlusEqual(FollowPath().Mutiply(m_dWeightFollowPath))
End If
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -