Compound Rotations

I’ve been continuing to work on the scripting language for generating procedural objects. During the last article I introduced the basics of Wooscript. There were a few things that weren’t quite right with the way various adjustments worked together.

This is an example of a simple script that builds a curving row of cubes. The adjust(rz, +10) adds 10 degrees to the roll that’s in the stack. As each cube is generated the rotation matrix is set using roll, pitch and yaw.

rule main {
repeat (r1, 10)
}

rule r1 {
call(box)
adjust(y, +1.2)
adjust(rz, +10)
}
// Wooscript 2.1
rule main {
repeat (10)
{
 box
 pos.y += 1.2
 rz += 10
}
}
Curve of cubes

Simple rotation rule

This looks good for single rotations, and now I want to make a wall of these curved cubes.

To do that I change the call(box) operation to repeat instantiation of another rule r2, which then adds the cube.

The change to the code is really pretty simple, and now I have a wall of cubes.

rule main {
repeat (r1, 10)
} 

rule r1 {
repeat(r2, 10)
adjust(y, +1.2)
adjust(rz, +10)
}

rule r2 {
call(box)
adjust(z, +1.2)
}
// Wooscript 2.1
rule main {
 repeat (10)
 {
  {repeat (10)
  {
   box
   pos.z += 1.2
  }}
  pos.y += 1.2
  rz += 10
 }
}
100 cubes

100 cubes in a wall

So far so good, but what I really want to do is make each of those extra rows of Cubes curve away from the centre of the circle. This will give a 3d fan instead of a flat wall.

To modify the code it’s a simple case of adding adjust(ry, +10) into the second rule. This should now rotate the cube around the y axis and leave a big 3d fan, but it doesn’t quite work…

rule main {
repeat (r1, 10)
} 

rule r1 {
repeat(r2, 10)
adjust(y, +1.2)
adjust(rz, +10)
}

rule r2 {
call(box)
adjust(ry, +10)
adjust(z, +1.2)
}
// Wooscript 2.1
rule main {
 repeat (10)
 {
  {repeat (10)
  {
   box
   pos.z += 1.2
   ry += 10
  }}
  pos.y += 1.2
  rz += 10
 }
}
100 cubes with a strange curve

Compound rotations on two axis

What happens is that each rotation occurs as if the cubes hadn’t been rotated on the other axis, so they all follow the same curve around the y axis.

What we really want is to change the code so that the rotations occur relative to previous rotations. This is probably making no sense at all right now, so I’ll just show you the picture of what I was after.

compound rotations in modelspace

Compound rotations on two axes

Much better. The way I did this was to keep track of the rotation matrix for each cube as it’s transformed. For further calls the rotation matrix itself is rotated using roll, pitch and yaw, which leads to rotations that occur relative to each other.

It’s now a simple thing to extend the ring all the way round, switch on the pathtracer and generate the final render for this article.

rule main {
repeat (r1, 20)
} 

rule r1 {
repeat (r2, 20)
adjust(y, +1.2)
adjust(rz, +10)
}

rule r2 {
call(box)
adjust(z, +1.2)
adjust(ry, +10)
adjust(rz, -5)
}
// Wooscript 2.1
rule main {
 repeat (20)
 {
  {repeat (20)
  {
   box
   pos.z += 1.2
   ry += 10
   rz -= 5
  }}
  pos.y += 1.2
  rz += 10
 }
}
3d geometry generated from stack based transformation language

Compound curves on all axes

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *

Spam Protection *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>