3d Rotations, Convergence / Divergence concept

I’m trying to accurately create an interactive 3d model of a physical item (a skateboard truck). The design is nearly there, but I’m having trouble “leveling” the wheel axis after a local adjustment. In real live you lean a skateboard, the wheels stay on the ground (?) and because of the angles and pivots involved, the axis turns. Lean left, steer left.

In 3d space modeling this isn’t quite so simple. I can tilt the board (a tiny increment) , but I’m having trouble wrapping my head around the whole level off the wheels and axle. I know that when a wheel /axle axis has a directional vector with Y value = zero, then its level.

Initial design was to just try a tiny increment, rotate the truck/axle/wheel combo, test for level. Pray things converge. Which, they don’t.

Working Demo…

Current work in progress code…

And for reference: Here’s what a production truck looks like.


The model is intended to show the effects of different tilt angles and rake values on performance.

My question here involve improving the code for the hanger / axle leveling. Right now its really poor code with lots of iterations in a for loop, test for approximately level then break, ugh. Not really good coding technique.

– converge / diverge algorithm? Take initial big rotation steps, watch results, intentionally overshoot, reduce increment size, reverse direction, try again?
– In the alternative, look at existing interim axle position, attempt to calculate the rotation required to make it level (conceptually this is really difficult as the axis of hanger rotation is changing in 3d space)

Other opportunities for improvement? Many thanks,

Funny how writing the issue down can change how you view something.

I will say, I have a difficult time learning new concepts if the original intro is too abstruse. I can start in reality, then extrapolate to the theoretical, but I can’t start in the purely theoretical. With that in mind… here’s a proposal. For the next conversation, left / right is the directions as observed by the person standing on top of the skateboard.

  • Look at the interim axle vector direction.
  • Look at left side wheel. Is it a higher or lower “elevation” then right wheel?
  • If left wheel is higher, rotate truck clockwise (when viewed down the truck hanger axis from board “down”.)
  • If left wheel is lower, rotate truck counterclockwise.
  • Adjust a test rotation in big increments until wheel relative heights change in the opposite heights.
  • When that happens, cut the rotation cut increment in half, then go in the opposite rotation direction until it flips again…
  • Test for near zero with every iteration. Obviously stop when the axle is level.
  • repeat (via a recursive function?)

I think this idea has possibilities…

Using if/else and loops for physics is usually not a good idea, you will end up with a billion conditionals and questionable results - unless this is specifically what you want to do for any reason. I’d say either use a physics library (ex. ammo.js / cannon.js), or do some research on inverse kinematics - ie. math for simulating how joined movable parts react when you move one of them.

Yes, I pretty much realize that. I tried the left / right increment adjustment thing… too many degrees of freedom… I made a simple improvement to the existing for loop and that seems to work pretty smoothly, probably well enough for the conversation I’m having with the skateboard design folks. This is not a commercial offering, just a way to help folks understand some subtle design issues. The online model link above just updated. Oh, and if you want to understand the leveling testing, turn on the browser inspector console.

I’m still having a difficult time with the hanger flipping direction when the angles are steep. I don’t think its a gimbal lock issue… I saw a sample code for a quaternion rotation but it doesn’t seem to be working correctly. Any experience there? When you play with the model using the Quaternion function the rotations are jumpy, odd and slow.

I converted code from prototype to stand alone function… I think this is correct.

  const rotateAboutQuaternion = (mesh, axis, axisPosition, angle) => {
        // from https://stackoverflow.com/a/32038265/2487730    from: WestLangley
        var q = new THREE.Quaternion();
        q.setFromAxisAngle(axis, angle);

The code I’ve been using: This code works pretty smoothly except at high hanger angles.

    //rotates a mesh's geometry about a specified axis and pivot
    //the axis is a normalized Vector3   S.O. 12746011
    const rotateAbout = (mesh, axis, axisPosition, angle) => {
        mesh.geometry.applyMatrix4(new THREE.Matrix4().makeTranslation(mesh.position.x - axisPosition.x, mesh.position.y - axisPosition.y, mesh.position.z - axisPosition.z));  //translate geometry to axis location
        mesh.geometry.applyMatrix4(new THREE.Matrix4().makeRotationAxis(axis, angle));    //rotate geometry about axis
        mesh.geometry.applyMatrix4(new THREE.Matrix4().makeTranslation(axisPosition.x - mesh.position.x, axisPosition.y - mesh.position.y, axisPosition.z - mesh.position.z));  //translate geometry back to original location

Again, its not clear if this is my problem (or I’m still stuck with the convergence issue…)

Any ideas here?

Which part of that is the final question… :’) (One sentence pls, and you’re banned from using “degrees of freedom”, “gimbal lock”, “convergence”, and “disruptive technology”.)

Apologies for not replying earlier… I tried but I got this message "You’ve reached the maximum number of replies a new user can create on their first day. Please wait XX hours before trying again."

Not sure I understand your comments.

Were you able to use the mouse on your monitor to duplicate the jumpy response when you adjust tilt angles via the top slider? This is most pronounced with Hanger Axis Slider and Rake Slider each set to the far right.



What do you think is causing the image to jump around the screen, a poor implementation of the leveling routine or a fragile 3d rotation function, perhaps something only a rocket scientist might observe? When I say jumping around, the part is being unexpectedly rotated 180 degrees and back again during a tilt slider operation.

Any tips or hints within THREE.js to make improvements? Many thanks.