Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / WPF

Amble Avalona

Rate me:
Please Sign up or sign in to vote.
4.89/5 (51 votes)
2 Feb 2011CPOL4 min read 67.3K   1.8K   49   37
A WPF animaloid
Screenshot1.png

Introduction

Following in the footsteps of my previous article, it would have been improper not to take on the task of xamlizing a four-legged creature. In short, I decided to work on a WPF project that replicated a walking four-legged animal.

Requirements

To run the project provided from the download link above, you require either of the following:

  • Visual Studio 2010
  • Expression Blend

If you're using VS 2008, you can download the source files from here.

NB: Ensure that you open the solution using Visual Basic Express if you're using the Express edition of Visual Studio.

Avalona

How It Works

To make Avalona walk, just press the right arrow key. Avalona will amble on a treadmill, this time the action taking place inside the M Labs Animaloid Research Centre.

Ambling

The amble is an easy gait (way of walking), most common in horses, where at least one leg/hoof touches the ground during the phases of motion. There is no suspension phase, i.e., a phase where all the legs are entirely off the ground. This was the primary reason I decided to replicate the amble. During this gait, a maximum of two legs can/will support the weight of the animal. The following sequence of photographs show the phases followed during this gait.

Screenshot2.png

A short and detailed explanation of the phases of movement shown above can be found here.

There are 11 phases in the photos above, which are a bit of a handful, so I narrowed it down to 5 phases which would offer me equally suitable results.

Screenshot3.png

From the initial sequence of photos, I chose the 4th, 5th, 6th, 7th, and 9th phases.

If you want to, you can watch a video of a horse ambling here.

Design and Layout

I designed Avalona, Treadmill, and the Lab_Screen in Expression Design. The rest of the elements were added in Expression Blend. The following image shows the layout of the elements of concern and their names (the same applies to the left legs),

Screenshot4.png

NB: The center of the joints of each section of Avalona act as center points.

Leg Movement

The standing posture of Avalona and that of a horse are slightly different. Avalona's limbs are more slightly angled especially those of the hind legs.

Screenshot5.png

This presented a bit of a challenge in my attempt at replicating the amble. Because of this difference, Avalona's gait is a slightly modified version of a horse's amble.

In order to get a better picture of how to proceed, I drew stick figures of the ambling horse and then drew stick figures of a ambling Avalona, taking into account their differences in standing posture. I then adjusted the elements of concern in Expression Blend, at positions similar to those of the stick figures, noting down the angles which I felt would offer suitable results. These were the results:

Screenshot6.png

Screenshot7.png

The Code

The calculations that provide us with the necessary wizardry are found in the module MovementCalculations:

VB.NET
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

We check which key has been pressed in the MainWindow KeyDown event handler:

VB.NET
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

The WalkForward method does as its name suggests:

VB.NET
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

In the method above, method calls are made based on the values of various variables, of Boolean type. The RightHindBack method rotates the various sections of Avalona's legs from the standing position to Phase 3. It later alternates to rotating elements from Phase 1 to Phase 3.

VB.NET
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

The RightHindForward method rotates the various sections of Avalona's legs from Phase 3 to Phase 5.

VB.NET
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

The LeftHindBack method is similar to the RightHindBack method, with the code for shifting from the standing position missing and an interchange of variables. The logic is still the same.

VB.NET
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

The LeftHindForward method is similar to the RightHindForward method with an interchange of variables.

VB.NET
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

Extra Resources

I'm sure that Avalona can do more than just amble. It can run, walk,... maybe even swim. If you are of the same opinion and have the time and interest, the following resources could prove to be useful:

Conclusion

I hope you enjoyed reading the article and taking Avalona for a walk, even if it was only on a treadmill. Stay tuned for the next episode when the Speedster, Xaml Man, and Avalona join forces in an epic battle against Winn Fommz... just kidding. If you want to add some enhancements to Avalona, the doors of the M Labs Animaloid Research Center are wide open once you download the source files and open the solution. Cheers!

History

  • 1st February, 2011: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Kenya Kenya
Experienced C# software developer with a passion for WPF.

Awards,
  • CodeProject MVP 2013
  • CodeProject MVP 2012
  • CodeProject MVP 2021

Comments and Discussions

 
GeneralMy vote of 3 Pin
gopal pradhan1-Oct-12 2:53
gopal pradhan1-Oct-12 2:53 
GeneralMy vote of 5 Pin
ComputerJin13-Dec-11 20:30
ComputerJin13-Dec-11 20:30 
GeneralRe: My vote of 5 Pin
Meshack Musundi6-Feb-12 20:52
professionalMeshack Musundi6-Feb-12 20:52 
GeneralMy vote of 5 Pin
murali.isu9-Aug-11 22:04
professionalmurali.isu9-Aug-11 22:04 
GeneralRe: My vote of 5 Pin
Meshack Musundi6-Feb-12 20:51
professionalMeshack Musundi6-Feb-12 20:51 
QuestionMy Vote Of 5 Pin
Jyothikarthik_N11-Jul-11 21:26
Jyothikarthik_N11-Jul-11 21:26 
AnswerRe: My Vote Of 5 Pin
Meshack Musundi11-Jul-11 22:24
professionalMeshack Musundi11-Jul-11 22:24 
Generalnice but... Pin
Abudreas19-Mar-11 2:11
Abudreas19-Mar-11 2:11 
GeneralRe: nice but... Pin
Meshack Musundi19-Mar-11 2:47
professionalMeshack Musundi19-Mar-11 2:47 
Thanks. I happen to be pretty good with a pencil and other non-computer artistic devices. The mouse is something that I'm trying to get accustomed to. I have no formal training as an artist but I try my best.
GeneralMy vote of 5 Pin
Minhajul Shaoun14-Mar-11 10:10
Minhajul Shaoun14-Mar-11 10:10 
GeneralRe: My vote of 5 Pin
Meshack Musundi15-Mar-11 19:46
professionalMeshack Musundi15-Mar-11 19:46 
GeneralMy Vote of 5 Pin
RaviRanjanKr10-Mar-11 7:11
professionalRaviRanjanKr10-Mar-11 7:11 
GeneralRe: My Vote of 5 Pin
Meshack Musundi10-Mar-11 8:16
professionalMeshack Musundi10-Mar-11 8:16 
GeneralMy vote of 5 Pin
Abhinav S9-Mar-11 18:07
Abhinav S9-Mar-11 18:07 
GeneralRe: My vote of 5 Pin
Meshack Musundi10-Mar-11 5:30
professionalMeshack Musundi10-Mar-11 5:30 
GeneralMy vote is 5 Pin
Sunasara Imdadhusen7-Mar-11 22:40
professionalSunasara Imdadhusen7-Mar-11 22:40 
GeneralRe: My vote is 5 Pin
Meshack Musundi8-Mar-11 2:02
professionalMeshack Musundi8-Mar-11 2:02 
GeneralWow! Pin
Marcelo Ricardo de Oliveira7-Mar-11 6:34
mvaMarcelo Ricardo de Oliveira7-Mar-11 6:34 
GeneralRe: Wow! Pin
Meshack Musundi7-Mar-11 7:25
professionalMeshack Musundi7-Mar-11 7:25 
GeneralNice article Pin
Toniyo Jackson6-Mar-11 20:02
Toniyo Jackson6-Mar-11 20:02 
GeneralRe: Nice article Pin
Meshack Musundi7-Mar-11 0:41
professionalMeshack Musundi7-Mar-11 0:41 
GeneralMy vote of 5 Pin
Anthony Daly25-Feb-11 9:03
Anthony Daly25-Feb-11 9:03 
GeneralRe: My vote of 5 Pin
Meshack Musundi25-Feb-11 19:59
professionalMeshack Musundi25-Feb-11 19:59 
GeneralMy vote of 5 Pin
David C# Hobbyist.14-Feb-11 8:24
professionalDavid C# Hobbyist.14-Feb-11 8:24 
GeneralRe: My vote of 5 Pin
Meshack Musundi14-Feb-11 18:14
professionalMeshack Musundi14-Feb-11 18:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.