# Module: Rabbit::TrackBall

Defined in:
lib/rabbit/trackball.rb

Classes: Vector

## Constant Summary collapse

SIZE =

This size should really be based on the distance from the center of rotation to the point on the object underneath the mouse. That point would then track the mouse as closely as possible. This is a simple example, though, so that is left as an Exercise for the Programmer.

`0.8`
RENORM_COUNT =

Given two rotations, e2 and e2, expressed as quaternion rotations, figure out the equivalent single rotation and stuff it into dest.

This routine also normalizes the result every RENORM_COUNT times it is called, to keep error from creeping in.

NOTE: This routine is written so that q1 or q2 may be the same as dest (or each other).

`97`
@@quats_count =
`0`

## Class Method Summary collapse

• Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet if we are away from the center of the sphere.

## Class Method Details

### .add_quats(q1, q2) ⇒ Object

 ``` 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226``` ```# File 'lib/rabbit/trackball.rb', line 210 def add_quats(q1, q2) t1 = q1.vscale(q2[3]) t2 = q2.vscale(q1[3]) t3 = q2.vcross(q1) tf = t1.vadd(t2) tf = t3.vadd(tf) tf[3] = q1[3] * q2[3] - q1.vdot(q2, 3) @@quats_count += 1 ret = tf if (@@quats_count > RENORM_COUNT) @@quats_count = 0 ret = tf.normalize_quat end ret end```

### .tb_project_to_sphere(r, x, y) ⇒ Object

Project an x,y pair onto a sphere of radius r OR a hyperbolic sheet if we are away from the center of the sphere.

 ``` 185 186 187 188 189 190 191 192 193 194``` ```# File 'lib/rabbit/trackball.rb', line 185 def tb_project_to_sphere(r, x, y) d = Math.sqrt(x * x + y * y) if (d < r * 0.70710678118654752440) # Inside sphere z = Math.sqrt(r * r - d * d) else # On hyperbola t = r / 1.41421356237309504880 z = t * t / d end z end```

### .trackball(p1x, p1y, p2x, p2y) ⇒ Object

 ``` 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179``` ```# File 'lib/rabbit/trackball.rb', line 156 def trackball(p1x, p1y, p2x, p2y) if (p1x == p2x && p1y == p2y) return Vector.new([0.0, 0.0, 0.0, 1.0]) end # First, figure out z-coordinates for projection of P1 and P2 to # deformed sphere p1 = Vector.new([p1x, p1y, tb_project_to_sphere(SIZE, p1x, p1y)]) p2 = Vector.new([p2x, p2y, tb_project_to_sphere(SIZE, p2x, p2y)]) # Now, we want the cross product of P1 and P2 a = p2.vcross(p1) # Figure out how much to rotate around that axis. d = p1.vsub(p2) t = d.vlength / (2.0 * SIZE) # Avoid problems with out-of-control values... t = 1.0 if (t > 1.0) t = -1.0 if (t < -1.0) phi = 2.0 * Math.asin(t) a.axis_to_quat(phi) end```