The great wanderer uses all three axes for movement and makes a distinction based on the directions along those axes: up, down, left, right, forward and backward. These all represent directions along the $x,y,z$ axes in a Cartesian system but does not allow for “fluent” movement where the great wanderer would be aware of any other rotations along the horizon, other than $\frac{\pi}{2}$ rads.

Let's take for instance a 2-dimensional Cartesian system with two axes $x$ and $y$:

            ,-'    y ^     /`-.
          ,'         |    /    `.
        ,'           |   /       `.
       ,'         up |  / r+      `.
       /             |-+           |
      |             O| |            |
      |    - - - - - +---------->   |
      |       left / |  right  x    |
      `.          /                .'
       |         /   |             /
        \       / r-   down       /
         `.    /     |          ,'
           `._               _,'
              `-.__     __.-'

Up to this point in the article, we notice that the automaton is able to distinguish between “up”, “down”, “left”, “right”, “forward” and “backward”, which all represent $\frac{pi}/2$ radians rotations around the axes $x$,$y$ and $z$ from origin point $O$. If we simply the model, as shown in the figure above, then we only have 4 directions along the $x,y$ axes.

We can now circumscribe the Cartesian system inside a circle with $2 * \pi$ radians and notice that the rays $r^{+}$ and $r^{-}$ describe two directions along an arbitrary rotation around the $x$ and $y$ axes.

Thus, for all chosen rotations in $2 * \pi$ radians of the circle we obtain 2 distinct directions: $r^{+}$ and $r^{-}$ since the rays are symmetrical. Since we have already said that the great wanderer uses an automaton with 6 states, we can generalize over the states of the automaton in order to expand it so that more directions are possible. We could reverse the situation and simplify the automaton so that it would consist of two states representing directions along “just” the $x^{+}$ and $y^{+}$ axes. In that case, we would have an automaton with two states, each corresponding to the radian-rotations around the origin point:

QT = [ d(\frac{pi}{2}), d(0) ]

Adding back the $x^{-}$ and $y^{-}$ directions, we get an automaton with four states:

QT = [ d(\frac{3*pi}{2}), d(\pi), d(\frac{pi}{2}), d(0) ]

Going even further back and by adding the $z$ axes, we obtain another two states, forward and backward:

QT = [ fwd, bwd, d(\frac{3*\pi}{2}), d(\pi), d(\frac{pi}{2}), d(0) ]

We can observe that the number of angles chosen along the arc of the circle is directly linked to the number of states in the automaton.

We can thus define something called course affinity which would be the number of states that the automaton of a great wanderer would have and it will describe the number of possible directions that the wanderer could both sense (!) and move along.


It is also clear that the geometric shape of the great wanderer is related to its course affinity. For example, for a 6-state free roamer, a number of 6 sensors is needed (each symmetrically placed at $pi$-radians) from the centre of the object in order to detect collisions.

Thus, a 6-state automaton would need 6 sensors which describe the 6 directions of the automaton. It is interesting to note that the number of states will always be even for a complete wanderer that senses a direction and its opposite.

              up ^ y+
                 |     / forward
               +-|---+/  z+
              /  |  //
             /   | //|
      left  +----|+/ +    right
     - - - -|- - +|-------->
     -x     |   /|| /     x+
            |    ||/
                 | down
   backward /      y-

Thus, we know that a 6-state automaton will require a symmetrical geometric body with 6 symmetrically placed sensors.

Suppose we additionally add the bisectrices of each plane defined by the 2-combinations of the axes $x,y,z$ minus the singularities $x,x$, $y,y$ and $z,z$. When we add the bisectrices, we are really just rotating the Cartesian system around the origin point by $\frac{\pi}{4}$ and thereby adding another 6 directions and obtaining thus 12 directions which describe a dodecahedron:

Dodecahedron or 12-cube, geometric body with 12 symmetrically disposed faces.

As, we said, we can generalize and observe that the number of faces is given by the rotation of the Cartesian system in $\frac{\pi}{4}$ increments, duplicating each time the number of axes and the number of directions.

For 3 axes, we have 6 directions, and hence 6 faces (cube). For 6 axes, we have 12 directions, and hence 12 faces (dodecahedron). For 12 axes, we have 24 directions, and hence 24 faces (24-cube). For $n$ axes, we have $2n$ directions (2n-cube).

Every time the number of faces being an even number (multiples of 2).

Thus an n-axes wanderer, requires 2n-state automatons with 2n faces. The general formula that maps axes to states is given by:

n-axes -> 2n->directions -> 2n-faces

such that each axis requires 2 states, which allows the movement of a generalized great wanderer in $2n$ directions.

Geometric Convergence

We can observe that each time we rotate the Carthesian system in order to generate 2n directions, we are really just generating multiples of 2n-Hypercubes. It is interesting to note that if the even number if faces ($2n$) were replaced by an uneven $2n+1$ iterator over geometries, we would obtain only theoretical and non-practical geometries which could not be engineered.

Also, it is consequential that by increasing the number of faces of a cube, the shape will eventually converge to a sphere - similar to increasing the number of sides of a square which converges to a circle.

Automaton Expansion

Now that we have deduced the correspondence between axes, directions, faces and states, we can automatically generate code that will take as input the number of directions and create an n-great wanderer that moves along those directions.

This is primarily due to the symmetry of the code that great wanderer uses, in which every state is defined by the code-block:

state direction
    state_entry() {
        currentState = "direction";
        llSetTimerEvent(2); // Anti-stuck.
    collision_start(integer num) {
        state compute;
    timer() {
        if(llFabs(llVecMag(llList2Vector(llGetObjectDetails(llGetKey(), [OBJECT_VELOCITY]), 0))) < ENGINE_SPEED/2) state compute;

Thus, by snapping together blocks of code, we can just alter the structure and add states.

The algorithm that is used in order to expand a great wanderer into an n-great wanderer is the following:

  • expand the probability array and the named equivalent to n-axes or (2n-axes)-directions:
list qD = [ "forward", "backward", "left", "right", "up", "down", ..., (2n-axes)-drections ];
list QT = [ .15, .17, .17, .17, .17, .17, ..., (2n-axes)-directions, probabilities ];

where the $qD * QT$ is a bijective map where each element of $qD$ maps to exactly one element of $QT$. The initial spray of probabilities in $QT$ along each direction $d$ is given by $P(d)=\frac{1}{(2n-axes)}$ such that:

\sum_{n=1}^{2n} P(d) = 1

  • handle each (2n-axes)-direction to the cumulative probability algorithm:
                if(llList2String(dirs, itra) == "right") state right;
                if(llList2String(dirs, itra) == "up") state up;
                if(llList2String(dirs, itra) == "left") state left;
                if(llList2String(dirs, itra) == "down") state down;
                For direction in (2n-axes) - drections:
                  If direction is state, then:
                    Jump to state.
  • expand the jump table in the recomputing state compute to include n-directions, similarly to the previous point:
        if(nextState == "right") state right;
        if(nextState == "up") state up;
        if(nextState == "left") state left;
        if(nextState == "down") state down;        
        For direction in (2n-axes) - drections:
          Forall state in states:
            If next state is state then goto state
  • extend the thrust and anti-thrust symmetrically to include the (2n-axes)-directions:
    if(direction == "right") { llSetVelocity(<-ENGINE_SPEED,0,0>, TRUE); return; }
    if(direction == "up") { llSetVelocity(<0,ENGINE_SPEED,0>, TRUE); return; }
    if(direction == "left") { llSetVelocity(<ENGINE_SPEED,0,0>, TRUE); return; }
    if(direction == "down") { llSetVelocity(<0,-ENGINE_SPEED,0>, TRUE); return; }
    For axis in 2n-axes:
      Apply forward velocity along axis.
    if(direction == "right") { llSetVelocity(<ENGINE_SPEED,0,0>, TRUE); return; }
    if(direction == "up") { llSetVelocity(<0,-ENGINE_SPEED,0>, TRUE); return; }
    if(direction == "left") { llSetVelocity(<-ENGINE_SPEED,0,0>, TRUE); return; }
    if(direction == "down") { llSetVelocity(<0,ENGINE_SPEED,0>, TRUE); return; } 
    For axes in 2n-axes:
      Apply backward velocity along axis.

Generalized Great Wanderer Algorithm

  1. For all n-axes, 2n-directions or 2n-faces of the wanderer, do:
    1. Generate a bijection mapping states to probabilities so that all probabilities add up to 1: $qD$->$QT$ and $\sum_{n=1}^{2n} P(2n) = 1$.
  2. Stable-sort both QT and qD in descending order.
  3. Jump to the first element in qD.
  4. Propulse object along that direction.
  5. If a collision is detected, then:
    1. Decrement P(n) in the $QT$ probability set by a factor (increasing factor along each axis?).
  6. Goto 2.

secondlife/great_wanderer/generalized.txt · Last modified: 2017/02/22 18:20 (external edit)

Access website using Tor

For the copyright, license, warranty and privacy terms for the usage of this website please see the license and privacy pages.