Amble Avalona






4.89/5 (50投票s)
一个 WPF 动物形态

引言
继我上一篇文章的脚步,不给四足动物Xaml化任务添砖加瓦就太不应该了。简而言之,我决定做一个WPF项目来模拟一只四足动物行走。
要求
要运行从上面的下载链接提供的项目,你需要以下之一
- Visual Studio 2010
- Expression Blend
如果您正在使用VS 2008,可以从这里下载源代码文件。
注意:如果您使用的是Visual Studio的Express版本,请确保使用Visual Basic Express打开解决方案。
Avalona
工作原理
要让Avalona行走,只需按右箭头键。Avalona将在跑步机上缓步前行,这次的场景发生在M Labs Animaloid Research Centre。
缓步
缓步是一种轻松的步态(行走方式),在马匹中最为常见,在运动的各个阶段至少有一条腿/蹄子接触地面。没有悬空阶段,也就是说,所有腿都完全离开地面的阶段。这是我决定模拟缓步的主要原因。在此步态下,最多可以有两条腿支撑动物的体重。以下一系列照片展示了在此步态下遵循的各个阶段。
上面照片中展示的运动阶段的简短而详细的解释可以在这里找到。
上面的照片中有11个阶段,有点太多了,所以我将其缩减到5个阶段,这也能提供同样合适的结果。
从初始的照片序列中,我选择了第4、5、6、7和9个阶段。
如果您愿意,可以在这里观看一匹马缓步行走的视频。
设计和布局
我在Expression Design中设计了Avalona
、Treadmill
和Lab_Screen
。其余的元素则是在Expression Blend中添加的。下图显示了相关元素的布局及其名称(左腿也同样适用),
注意:Avalona每个部分的关节中心充当着中心点。
腿部运动
Avalona的站立姿势与马匹的站立姿势略有不同。Avalona的四肢角度更小,特别是后腿。
这给我尝试模拟缓步带来了一些挑战。由于这种差异,Avalona的步态是马匹缓步的略微修改版本。
为了更清晰地了解如何进行,我画了缓步马的火柴人图,然后画了缓步Avalona的火柴人图,同时考虑了它们站立姿势的差异。然后,我在Expression Blend中调整了相关元素,使其处于与火柴人图相似的位置,并记下了我认为能提供合适结果的角度。这些就是结果。
代码
提供我们所需魔力的计算在MovementCalculations
模块中。
Module MovementCalculations
Public RhtHindLeg_A_Angles() As Integer = {4, 8, 14, -4, -14}
Public RhtHindLeg_B_Angles() As Integer = {4, 8, 14, 20, -10}
Public RhtHindLeg_C_Angles() As Integer = {-4, -10, -31, -42, 4}
Public RhtHindLegPawAngles() As Integer = {-4, 2, 3, 22, 20}
Public LeftHindLeg_A_Angles() As Integer = {-14, -12, -9, -5, 4}
Public LeftHindLeg_B_Angles() As Integer = {-10, -14, -20, -10, 4}
Public LeftHindLeg_C_Angles() As Integer = {4, 9, 21, 12, -4}
Public LeftHindLegPawAngles() As Integer = {20, 22, 8, 3, -4}
Public RhtForeLeg_A_Angles() As Integer = {3, 4, 5, 9, 6}
Public RhtForeLeg_B_Angles() As Integer = {2, 9, 13, 15, -41}
Public RhtForeLeg_C_Angles() As Integer = {0, 0, 0, 18, 68}
Public RhtForeLegPawAngles() As Integer = {-5, -13, -18, -25, -31}
Public LeftForeLeg_A_Angles() As Integer = {6, 9, 1, -8, 3}
Public LeftForeLeg_B_Angles() As Integer = {-41, -60, -46, -8, 2}
Public LeftForeLeg_C_Angles() As Integer = {68, 66, 55, 0, 0}
Public LeftForeLegPawAngles() As Integer = {-31, -16, -8, 29, -5}
' Get to Phase 1
Public LeftHindLeg_A_Shift1 As Double = _
Math.Abs(LeftHindLeg_A_Angles(0) / RhtHindLeg_A_Angles(0))
Public LeftHindLeg_B_Shift1 As Double = _
Math.Abs(LeftHindLeg_B_Angles(0) / RhtHindLeg_A_Angles(0))
Public LeftHindLeg_C_Shift1 As Double = _
(LeftHindLeg_C_Angles(0) / RhtHindLeg_A_Angles(0))
Public LeftHindLegPawShift1 As Double = _
(LeftHindLegPawAngles(0) / RhtHindLeg_A_Angles(0))
Public RhtForeLeg_A_Shift1 As Double = _
(RhtForeLeg_A_Angles(0) / RhtHindLeg_A_Angles(0))
Public RhtForeLeg_B_Shift1 As Double = _
(RhtForeLeg_B_Angles(0) / RhtHindLeg_A_Angles(0))
Public RhtForeLegPawShift1 As Double = _
Math.Abs(RhtForeLegPawAngles(0) / RhtHindLeg_A_Angles(0))
Public LeftForeLeg_A_Shift1 As Double = _
(LeftForeLeg_A_Angles(0) / RhtHindLeg_A_Angles(0))
Public LeftForeLeg_B_Shift1 As Double = _
Math.Abs(LeftForeLeg_B_Angles(0) / RhtHindLeg_A_Angles(0))
Public LeftForeLeg_C_Shift1 As Double = _
(LeftForeLeg_C_Angles(0) / RhtHindLeg_A_Angles(0))
Public LeftForeLegPawShift1 As Double = _
Math.Abs(LeftForeLegPawAngles(0) / RhtHindLeg_A_Angles(0))
' Phase 2s
Public Phase2Shift As Double = _
(RhtHindLeg_A_Angles(1) - RhtHindLeg_A_Angles(0))
Public RhtHindLeg_B_Shift2 As Double = _
(RhtHindLeg_B_Angles(1) - RhtHindLeg_B_Angles(0)) / Phase2Shift
Public RhtHindLeg_C_Shift2 As Double = _
Math.Abs(RhtHindLeg_C_Angles(1) - RhtHindLeg_C_Angles(0)) / Phase2Shift
Public RhtHindLegPawShift2 As Double = _
(RhtHindLegPawAngles(1) - RhtHindLegPawAngles(0)) / Phase2Shift
Public LeftHindLeg_A_Shift2 As Double = _
(LeftHindLeg_A_Angles(1) - LeftHindLeg_A_Angles(0)) / Phase2Shift
Public LeftHindLeg_B_Shift2 As Double = _
Math.Abs(LeftHindLeg_B_Angles(1) - LeftHindLeg_B_Angles(0)) / Phase2Shift
Public LeftHindLeg_C_Shift2 As Double = _
(LeftHindLeg_C_Angles(1) - LeftHindLeg_C_Angles(0)) / Phase2Shift
Public LeftHindLegPawShift2 As Double = _
(LeftHindLegPawAngles(1) - LeftHindLegPawAngles(0)) / Phase2Shift
Public RhtForeLeg_A_Shift2 As Double = _
(RhtForeLeg_A_Angles(1) - RhtForeLeg_A_Angles(0)) / Phase2Shift
Public RhtForeLeg_B_Shift2 As Double = _
(RhtForeLeg_B_Angles(1) - RhtForeLeg_B_Angles(0)) / Phase2Shift
Public RhtForeLegPawShift2 As Double = _
Math.Abs(RhtForeLegPawAngles(1) - RhtForeLegPawAngles(0)) / Phase2Shift
Public LeftForeLeg_A_Shift2 As Double = _
(LeftForeLeg_A_Angles(1) - LeftForeLeg_A_Angles(0)) / Phase2Shift
Public LeftForeLeg_B_Shift2 As Double = _
Math.Abs(LeftForeLeg_B_Angles(1) - LeftForeLeg_B_Angles(0)) / Phase2Shift
Public LeftForeLeg_C_Shift2 As Double = _
Math.Abs(LeftForeLeg_C_Angles(1) - LeftForeLeg_C_Angles(0)) / Phase2Shift
Public LeftForeLegPawShift2 As Double = _
(LeftForeLegPawAngles(1) - LeftForeLegPawAngles(0)) / Phase2Shift
' Phase 3s
Public Phase3Shift As Double = _
(RhtHindLeg_A_Angles(2) - RhtHindLeg_A_Angles(1))
Public RhtHindLeg_B_Shift3 As Double = _
(RhtHindLeg_B_Angles(2) - RhtHindLeg_B_Angles(1)) / Phase3Shift
Public RhtHindLeg_C_Shift3 As Double = _
Math.Abs(RhtHindLeg_C_Angles(2) - RhtHindLeg_C_Angles(1)) / Phase3Shift
Public RhtHindLegPawShift3 As Double = _
(RhtHindLegPawAngles(2) - RhtHindLegPawAngles(1)) / Phase3Shift
Public LeftHindLeg_A_Shift3 As Double = _
(LeftHindLeg_A_Angles(2) - LeftHindLeg_A_Angles(1)) / Phase3Shift
Public LeftHindLeg_B_Shift3 As Double = _
Math.Abs(LeftHindLeg_B_Angles(2) - LeftHindLeg_B_Angles(1)) / Phase3Shift
Public LeftHindLeg_C_Shift3 As Double = _
(LeftHindLeg_C_Angles(2) - LeftHindLeg_C_Angles(1)) / Phase3Shift
Public LeftHindLegPawShift3 As Double = _
Math.Abs(LeftHindLegPawAngles(2) - LeftHindLegPawAngles(1)) / Phase3Shift
Public RhtForeLeg_A_Shift3 As Double = _
(RhtForeLeg_A_Angles(2) - RhtForeLeg_A_Angles(1)) / Phase3Shift
Public RhtForeLeg_B_Shift3 As Double = _
(RhtForeLeg_B_Angles(2) - RhtForeLeg_B_Angles(1)) / Phase3Shift
Public RhtForeLegPawShift3 As Double = _
Math.Abs(RhtForeLegPawAngles(2) - RhtForeLegPawAngles(1)) / Phase3Shift
Public LeftForeLeg_A_Shift3 As Double = _
Math.Abs(LeftForeLeg_A_Angles(2) - LeftForeLeg_A_Angles(1)) / Phase3Shift
Public LeftForeLeg_B_Shift3 As Double = _
(LeftForeLeg_B_Angles(2) - LeftForeLeg_B_Angles(1)) / Phase3Shift
Public LeftForeLeg_C_Shift3 As Double = _
Math.Abs(LeftForeLeg_C_Angles(2) - LeftForeLeg_C_Angles(1)) / Phase3Shift
Public LeftForeLegPawShift3 As Double = _
(LeftForeLegPawAngles(2) - LeftForeLegPawAngles(1)) / Phase3Shift
' Phase 4s
Public Phase4Shift As Double = _
Math.Abs(RhtHindLeg_A_Angles(3) - RhtHindLeg_A_Angles(2))
Public RhtHindLeg_B_Shift4 As Double = _
(RhtHindLeg_B_Angles(3) - RhtHindLeg_B_Angles(2)) / Phase4Shift
Public RhtHindLeg_C_Shift4 As Double = _
Math.Abs(RhtHindLeg_C_Angles(3) - RhtHindLeg_C_Angles(2)) / Phase4Shift
Public RhtHindLegPawShift4 As Double = _
(RhtHindLegPawAngles(3) - RhtHindLegPawAngles(2)) / Phase4Shift
Public LeftHindLeg_A_Shift4 As Double = _
(LeftHindLeg_A_Angles(3) - LeftHindLeg_A_Angles(2)) / Phase4Shift
Public LeftHindLeg_B_Shift4 As Double = _
(LeftHindLeg_B_Angles(3) - LeftHindLeg_B_Angles(2)) / Phase4Shift
Public LeftHindLeg_C_Shift4 As Double = _
Math.Abs(LeftHindLeg_C_Angles(3) - LeftHindLeg_C_Angles(2)) / Phase4Shift
Public LeftHindLegPawShift4 As Double = _
Math.Abs(LeftHindLegPawAngles(3) - LeftHindLegPawAngles(2)) / Phase4Shift
Public RhtForeLeg_A_Shift4 As Double = _
(RhtForeLeg_A_Angles(3) - RhtForeLeg_A_Angles(2)) / Phase4Shift
Public RhtForeLeg_B_Shift4 As Double = _
(RhtForeLeg_B_Angles(3) - RhtForeLeg_B_Angles(2)) / Phase4Shift
Public RhtForeLeg_C_Shift4 As Double = _
(RhtForeLeg_C_Angles(3)) / Phase4Shift
Public RhtForeLegPawShift4 As Double = _
Math.Abs(RhtForeLegPawAngles(3) - RhtForeLegPawAngles(2)) / Phase4Shift
Public LeftForeLeg_A_Shift4 As Double = _
Math.Abs(LeftForeLeg_A_Angles(3) - LeftForeLeg_A_Angles(2)) / Phase4Shift
Public LeftForeLeg_B_Shift4 As Double = _
(LeftForeLeg_B_Angles(3) - LeftForeLeg_B_Angles(2)) / Phase4Shift
Public LeftForeLeg_C_Shift4 As Double = _
CDbl((LeftForeLeg_C_Angles(2)) / Phase4Shift)
Public LeftForeLegPawShift4 As Double = _
(LeftForeLegPawAngles(3) - LeftForeLegPawAngles(2)) / Phase4Shift
' Phase 5s
Public Phase5Shift As Double = _
Math.Abs(RhtHindLeg_A_Angles(4) - RhtHindLeg_A_Angles(3))
Public RhtHindLeg_B_Shift5 As Double = _
Math.Abs(RhtHindLeg_B_Angles(4) - RhtHindLeg_B_Angles(3)) / Phase5Shift
Public RhtHindLeg_C_Shift5 As Double = _
(RhtHindLeg_C_Angles(4) - RhtHindLeg_C_Angles(3)) / Phase5Shift
Public RhtHindLegPawShift5 As Double = _
Math.Abs(RhtHindLegPawAngles(4) - RhtHindLegPawAngles(3)) / Phase5Shift
Public LeftHindLeg_A_Shift5 As Double = _
(LeftHindLeg_A_Angles(4) - LeftHindLeg_A_Angles(3)) / Phase5Shift
Public LeftHindLeg_B_Shift5 As Double = _
(LeftHindLeg_B_Angles(4) - LeftHindLeg_B_Angles(3)) / Phase5Shift
Public LeftHindLeg_C_Shift5 As Double = _
Math.Abs(LeftHindLeg_C_Angles(4) - LeftHindLeg_C_Angles(3)) / Phase5Shift
Public LeftHindLegPawShift5 As Double = _
Math.Abs(LeftHindLegPawAngles(4) - LeftHindLegPawAngles(3)) / Phase5Shift
Public RhtForeLeg_A_Shift5 As Double = _
Math.Abs(RhtForeLeg_A_Angles(4) - RhtForeLeg_A_Angles(3)) / Phase5Shift
Public RhtForeLeg_B_Shift5 As Double = _
Math.Abs(RhtForeLeg_B_Angles(4) - RhtForeLeg_B_Angles(3)) / Phase5Shift
Public RhtForeLeg_C_Shift5 As Double = _
(RhtForeLeg_C_Angles(4) - RhtForeLeg_C_Angles(3)) / Phase5Shift
Public RhtForeLegPawShift5 As Double = _
(RhtForeLegPawAngles(4) - RhtForeLegPawAngles(3)) / Phase5Shift
Public LeftForeLeg_A_Shift5 As Double = _
(LeftForeLeg_A_Angles(4) - LeftForeLeg_A_Angles(3)) / Phase5Shift
Public LeftForeLeg_B_Shift5 As Double = _
(LeftForeLeg_B_Angles(4) - LeftForeLeg_B_Angles(3)) / Phase5Shift
Public LeftForeLegPawShift5 As Double = _
Math.Abs(LeftForeLegPawAngles(4) - LeftForeLegPawAngles(3)) / Phase5Shift
End Module
我们在MainWindow KeyDown
事件处理程序中检查按下了哪个键。
Private Sub MainWindow_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Input.KeyEventArgs) Handles Me.KeyDown
If e.Key = Key.Right Then
WalkForward()
End If
End Sub
WalkForward
方法的作用正如其名。
Private Sub WalkForward()
If FocusOnRightHind = True Then
If MoveRhtLegBackwards = True Then
RightHindBack()
Else
RightHindForward()
End If
Else
If MoveLeftLegBackwards = True Then
LeftHindBack()
Else
LeftHindForward()
End If
End If
TreadmillRedTr.Angle -= 5
RightHindLeg_A.RenderTransform = RhtHindLeg_A_Tr
RightHindLeg_B.RenderTransform = RhtHindLeg_B_Tr
RightHindLeg_C.RenderTransform = RhtHindLeg_C_Tr
RightHindLegPaw.RenderTransform = RhtHindPawTr
LeftHindLeg_A.RenderTransform = LeftHindLeg_A_Tr
LeftHindLeg_B.RenderTransform = LeftHindLeg_B_Tr
LeftHindLeg_C.RenderTransform = LeftHindLeg_C_Tr
LeftHindLegPaw.RenderTransform = LeftHindPawTr
RightForeLeg_A.RenderTransform = RhtForeLeg_A_Tr
RightForeLeg_B.RenderTransform = RhtForeLeg_B_Tr
RightForeLeg_C.RenderTransform = RhtForeLeg_C_Tr
RightForeLegPaw.RenderTransform = RhtForePawTr
LeftForeLeg_A.RenderTransform = LeftForeLeg_A_Tr
LeftForeLeg_B.RenderTransform = LeftForeLeg_B_Tr
LeftForeLeg_C.RenderTransform = LeftForeLeg_C_Tr
LeftForeLegPaw.RenderTransform = LeftForePawTr
TreadmillRedGroup.RenderTransform = TreadmillRedTr
End Sub
在上述方法中,根据各种布尔型变量的值调用方法。RightHindBack
方法将Avalona腿部的各个部分从站立位置旋转到阶段3。之后,它会交替地将元素从阶段1旋转到阶段3。
Private Sub RightHindBack()
' Get to Phase 1. This executes only once.
If RhtHindLeg_A_Tr.Angle < 4 Then
RhtHindLeg_A_Tr.Angle += 1 * speed
RhtHindLeg_B_Tr.Angle += 1 * speed
RhtHindLeg_C_Tr.Angle -= 1 * speed
RhtHindPawTr.Angle -= 1 * speed
LeftHindLeg_A_Tr.Angle -= LeftHindLeg_A_Shift1 * speed
LeftHindLeg_B_Tr.Angle -= LeftHindLeg_B_Shift1 * speed
LeftHindLeg_C_Tr.Angle += LeftHindLeg_C_Shift1 * speed
LeftHindPawTr.Angle += LeftHindLegPawShift1 * speed
RhtForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift1 * speed
RhtForeLeg_B_Tr.Angle += RhtForeLeg_B_Shift1 * speed
RhtForePawTr.Angle -= RhtForeLegPawShift1 * speed
LeftForeLeg_A_Tr.Angle += LeftForeLeg_A_Shift1 * speed
LeftForeLeg_B_Tr.Angle -= LeftForeLeg_B_Shift1 * speed
LeftForeLeg_C_Tr.Angle += LeftForeLeg_C_Shift1 * speed
LeftForePawTr.Angle -= LeftForeLegPawShift1 * speed
End If
' Get to Phase 2
If RhtHindLeg_A_Tr.Angle >= 4 And RhtHindLeg_A_Tr.Angle < 8 Then
RhtHindLeg_A_Tr.Angle += 1 * speed
RhtHindLeg_B_Tr.Angle += RhtHindLeg_B_Shift2 * speed
RhtHindLeg_C_Tr.Angle -= RhtHindLeg_C_Shift2 * speed
RhtHindPawTr.Angle += RhtHindLegPawShift2 * speed
LeftHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift2 * speed
LeftHindLeg_B_Tr.Angle -= LeftHindLeg_B_Shift2 * speed
LeftHindLeg_C_Tr.Angle += LeftHindLeg_C_Shift2 * speed
LeftHindPawTr.Angle += LeftHindLegPawShift2 * speed
RhtForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift2 * speed
RhtForeLeg_B_Tr.Angle += RhtForeLeg_B_Shift2 * speed
RhtForePawTr.Angle -= RhtForeLegPawShift2 * speed
LeftForeLeg_A_Tr.Angle += LeftForeLeg_A_Shift2 * speed
LeftForeLeg_B_Tr.Angle -= LeftForeLeg_B_Shift2 * speed
LeftForeLeg_C_Tr.Angle -= LeftForeLeg_C_Shift2 * speed
LeftForePawTr.Angle += LeftForeLegPawShift2 * speed
End If
' Get to Phase 3
If RhtHindLeg_A_Tr.Angle >= 8 And RhtHindLeg_A_Tr.Angle < 14 Then
RhtHindLeg_A_Tr.Angle += 1 * speed
RhtHindLeg_B_Tr.Angle += RhtHindLeg_B_Shift3 * speed
RhtHindLeg_C_Tr.Angle -= RhtHindLeg_C_Shift3 * speed
RhtHindPawTr.Angle += RhtHindLegPawShift3 * speed
LeftHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift3 * speed
LeftHindLeg_B_Tr.Angle -= LeftHindLeg_B_Shift3 * speed
LeftHindLeg_C_Tr.Angle += LeftHindLeg_C_Shift3 * speed
LeftHindPawTr.Angle -= LeftHindLegPawShift3 * speed
RhtForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift3 * speed
RhtForeLeg_B_Tr.Angle += RhtForeLeg_B_Shift3 * speed
RhtForePawTr.Angle -= RhtForeLegPawShift3 * speed
LeftForeLeg_A_Tr.Angle -= LeftForeLeg_A_Shift3 * speed
LeftForeLeg_B_Tr.Angle += LeftForeLeg_B_Shift3 * speed
LeftForeLeg_C_Tr.Angle -= LeftForeLeg_C_Shift3 * speed
LeftForePawTr.Angle += LeftForeLegPawShift3 * speed
End If
If RhtHindLeg_A_Tr.Angle = 14 Then
MoveRhtLegBackwards = False
End If
End Sub
RightHindForward
方法将Avalona腿部的各个部分从阶段3旋转到阶段5。
Private Sub RightHindForward()
' Get to Phase 4
If RhtHindLeg_A_Tr.Angle <= 14 And RhtHindLeg_A_Tr.Angle > -4 Then
RhtHindLeg_A_Tr.Angle -= 1 * speed
RhtHindLeg_B_Tr.Angle += RhtHindLeg_B_Shift4 * speed
RhtHindLeg_C_Tr.Angle -= RhtHindLeg_C_Shift4 * speed
RhtHindPawTr.Angle += RhtHindLegPawShift4 * speed
LeftHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift4 * speed
LeftHindLeg_B_Tr.Angle += LeftHindLeg_B_Shift4 * speed
LeftHindLeg_C_Tr.Angle -= LeftHindLeg_C_Shift4 * speed
LeftHindPawTr.Angle -= LeftHindLegPawShift4 * speed
RhtForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift4 * speed
RhtForeLeg_C_Tr.Angle += RhtForeLeg_C_Shift4 * speed
RhtForePawTr.Angle -= RhtForeLegPawShift4 * speed
LeftForeLeg_A_Tr.Angle -= LeftForeLeg_A_Shift4 * speed
LeftForeLeg_B_Tr.Angle += LeftForeLeg_B_Shift4 * speed
LeftForeLeg_C_Tr.Angle -= LeftForeLeg_C_Shift4 * speed
LeftForePawTr.Angle += LeftForeLegPawShift4 * speed
ShiftAvalonaUp()
End If
If RhtHindLeg_A_Tr.Angle = -4 Then
LeftForeLeg_C_Tr.Angle = 0
End If
' Get to Phase 5
If RhtHindLeg_A_Tr.Angle <= -4 And RhtHindLeg_A_Tr.Angle > -14 Then
' Multiply by 0.5 since Phase 8 in the original sequence
' was jumped when creating the 5 Phase sequence.
RhtHindLeg_A_Tr.Angle -= 1 * speed * 0.5
RhtHindLeg_B_Tr.Angle -= RhtHindLeg_B_Shift5 * speed * 0.5
RhtHindLeg_C_Tr.Angle += RhtHindLeg_C_Shift5 * speed * 0.5
RhtHindPawTr.Angle -= RhtHindLegPawShift5 * speed * 0.5
LeftHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift5 * speed * 0.5
LeftHindLeg_B_Tr.Angle += LeftHindLeg_B_Shift5 * speed * 0.5
LeftHindLeg_C_Tr.Angle -= LeftHindLeg_C_Shift5 * speed * 0.5
LeftHindPawTr.Angle -= LeftHindLegPawShift5 * speed * 0.5
RhtForeLeg_A_Tr.Angle -= RhtForeLeg_A_Shift5 * speed * 0.5
RhtForeLeg_B_Tr.Angle -= RhtForeLeg_B_Shift5 * speed * 0.5
RhtForeLeg_C_Tr.Angle += RhtForeLeg_C_Shift5 * speed * 0.5
RhtForePawTr.Angle += RhtForeLegPawShift5 * speed * 0.5
LeftForeLeg_A_Tr.Angle += LeftForeLeg_A_Shift5 * speed * 0.5
LeftForeLeg_B_Tr.Angle += LeftForeLeg_B_Shift5 * speed * 0.5
LeftForePawTr.Angle -= LeftForeLegPawShift5 * speed * 0.5
ShiftAvalonaDown()
End If
If RhtHindLeg_A_Tr.Angle = -14 Then
FocusOnRightHind = False
' Set angles to Phase 5 stance
RhtHndFocusPhase5Stance()
End If
End Sub
LeftHindBack
方法与RightHindBack
方法相似,只是缺少了从站立位置转移的代码,并且变量进行了交换。逻辑仍然相同。
Private Sub LeftHindBack()
' Get to Phase 2
If LeftHindLeg_A_Tr.Angle >= 4 And LeftHindLeg_A_Tr.Angle < 8 Then
LeftHindLeg_A_Tr.Angle += 1 * speed
LeftHindLeg_B_Tr.Angle += RhtHindLeg_B_Shift2 * speed
LeftHindLeg_C_Tr.Angle -= RhtHindLeg_C_Shift2 * speed
LeftHindPawTr.Angle += RhtHindLegPawShift2 * speed
RhtHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift2 * speed
RhtHindLeg_B_Tr.Angle -= LeftHindLeg_B_Shift2 * speed
RhtHindLeg_C_Tr.Angle += LeftHindLeg_C_Shift2 * speed
RhtHindPawTr.Angle += LeftHindLegPawShift2 * speed
LeftForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift2 * speed
LeftForeLeg_B_Tr.Angle += RhtForeLeg_B_Shift2 * speed
LeftForePawTr.Angle -= RhtForeLegPawShift2 * speed
RhtForeLeg_A_Tr.Angle += LeftForeLeg_A_Shift2 * speed
RhtForeLeg_B_Tr.Angle -= LeftForeLeg_B_Shift2 * speed
RhtForeLeg_C_Tr.Angle -= LeftForeLeg_C_Shift2 * speed
RhtForePawTr.Angle += LeftForeLegPawShift2 * speed
End If
' Get to Phase 3
If LeftHindLeg_A_Tr.Angle >= 8 And LeftHindLeg_A_Tr.Angle < 14 Then
LeftHindLeg_A_Tr.Angle += 1 * speed
LeftHindLeg_B_Tr.Angle += RhtHindLeg_B_Shift3 * speed
LeftHindLeg_C_Tr.Angle -= RhtHindLeg_C_Shift3 * speed
LeftHindPawTr.Angle += RhtHindLegPawShift3 * speed
RhtHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift3 * speed
RhtHindLeg_B_Tr.Angle -= LeftHindLeg_B_Shift3 * speed
RhtHindLeg_C_Tr.Angle += LeftHindLeg_C_Shift3 * speed
RhtHindPawTr.Angle -= LeftHindLegPawShift3 * speed
LeftForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift3 * speed
LeftForeLeg_B_Tr.Angle += RhtForeLeg_B_Shift3 * speed
LeftForePawTr.Angle -= RhtForeLegPawShift3 * speed
RhtForeLeg_A_Tr.Angle -= LeftForeLeg_A_Shift3 * speed
RhtForeLeg_B_Tr.Angle += LeftForeLeg_B_Shift3 * speed
RhtForeLeg_C_Tr.Angle -= LeftForeLeg_C_Shift3 * speed
RhtForePawTr.Angle += LeftForeLegPawShift3 * speed
End If
If LeftHindLeg_A_Tr.Angle = 14 Then
MoveLeftLegBackwards = False
End If
End Sub
LeftHindForward
方法与RightHindForward
方法相似,只是变量进行了交换。
Private Sub LeftHindForward()
' Get to Phase 4
If LeftHindLeg_A_Tr.Angle <= 14 And LeftHindLeg_A_Tr.Angle > -4 Then
LeftHindLeg_A_Tr.Angle -= 1 * speed
LeftHindLeg_B_Tr.Angle += RhtHindLeg_B_Shift4 * speed
LeftHindLeg_C_Tr.Angle -= RhtHindLeg_C_Shift4 * speed
LeftHindPawTr.Angle += RhtHindLegPawShift4 * speed
RhtHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift4 * speed
RhtHindLeg_B_Tr.Angle += LeftHindLeg_B_Shift4 * speed
RhtHindLeg_C_Tr.Angle -= LeftHindLeg_C_Shift4 * speed
RhtHindPawTr.Angle -= LeftHindLegPawShift4 * speed
LeftForeLeg_A_Tr.Angle += RhtForeLeg_A_Shift4 * speed
LeftForeLeg_B_Tr.Angle += RhtForeLeg_B_Shift4 * speed
LeftForeLeg_C_Tr.Angle += RhtForeLeg_C_Shift4 * speed
LeftForePawTr.Angle -= RhtForeLegPawShift4 * speed
RhtForeLeg_A_Tr.Angle -= LeftForeLeg_A_Shift4 * speed
RhtForeLeg_B_Tr.Angle += LeftForeLeg_B_Shift4 * speed
RhtForeLeg_C_Tr.Angle -= LeftForeLeg_C_Shift4 * speed
RhtForePawTr.Angle += LeftForeLegPawShift4 * speed
ShiftAvalonaUp()
End If
If LeftHindLeg_A_Tr.Angle = -4 Then
RhtForeLeg_C_Tr.Angle = 0
End If
' Get to Phase 5
If LeftHindLeg_A_Tr.Angle <= -4 And LeftHindLeg_A_Tr.Angle > -14 Then
' Multiply by 0.5 since Phase 8 in the original sequence
' was jumped when creating the 5 Phase sequence.
LeftHindLeg_A_Tr.Angle -= 1 * speed * 0.5
LeftHindLeg_B_Tr.Angle -= RhtHindLeg_B_Shift5 * speed * 0.5
LeftHindLeg_C_Tr.Angle += RhtHindLeg_C_Shift5 * speed * 0.5
LeftHindPawTr.Angle -= RhtHindLegPawShift5 * speed * 0.5
RhtHindLeg_A_Tr.Angle += LeftHindLeg_A_Shift5 * speed * 0.5
RhtHindLeg_B_Tr.Angle += LeftHindLeg_B_Shift5 * speed * 0.5
RhtHindLeg_C_Tr.Angle -= LeftHindLeg_C_Shift5 * speed * 0.5
RhtHindPawTr.Angle -= LeftHindLegPawShift5 * speed * 0.5
LeftForeLeg_A_Tr.Angle -= RhtForeLeg_A_Shift5 * speed * 0.5
LeftForeLeg_B_Tr.Angle -= RhtForeLeg_B_Shift5 * speed * 0.5
LeftForeLeg_C_Tr.Angle += RhtForeLeg_C_Shift5 * speed * 0.5
LeftForePawTr.Angle += RhtForeLegPawShift5 * speed * 0.5
RhtForeLeg_A_Tr.Angle += LeftForeLeg_A_Shift5 * speed * 0.5
RhtForeLeg_B_Tr.Angle += LeftForeLeg_B_Shift5 * speed * 0.5
RhtForePawTr.Angle -= LeftForeLegPawShift5 * speed * 0.5
ShiftAvalonaDown()
End If
If LeftHindLeg_A_Tr.Angle = -14 Then
FocusOnRightHind = True
MoveRhtLegBackwards = True
MoveLeftLegBackwards = True
LeftHndFocusPhase5Stance()
End If
End Sub
额外资源
我相信Avalona能做的不仅仅是缓步。它可以奔跑、行走……甚至可能游泳。如果您也这么认为,并且有时间和兴趣,以下资源可能会有所帮助。
结论
希望您喜欢阅读这篇文章,并带着Avalona走了一段路,即使它只是一台跑步机。请继续关注下一集,届时Speedster、Xaml Man和Avalona将联手对抗Winn Fommz……开玩笑的。如果您想为Avalona添加一些增强功能,只要下载源代码并打开解决方案,M Labs Animaloid Research Center的大门就为您敞开。祝您一切顺利!
历史
- 2011 年 2 月 1 日:初始发布