Rotate vectors in 3D

Hi there!

I did some research about this topic on this forum and in general. The subject was discussed here before but with no-code solutions for 3D. I like to address that topic again with the hope to find an easy solution that can help me and the following to come.

Let’s say I like to create a Box between two 3D vectors, therefore i have to rotate it according to the angle between V1 to V2. This thread has the same issue in 2D - WEBGL cylinder between two points.
Following that i manage to rotate the XY positions accordingly, but still not for Z.

XY rotations are correct, still missing Z rotation.

current use:

				PVector heading = new PVector(position2.x - position.x, position2.y - position.y,
						position2.z - position.z);
				PVector midpoint = PVector.lerp(position, position2, 0.5f);

				canvas.strokeWeight(2);
				canvas.noFill();
				canvas.stroke(0, 255, 0);
				canvas.line(p1.pos.x, p1.pos.y, p1.pos.z, p2.pos.x, p2.pos.y, p2.pos.z);

				canvas.stroke(255);
				canvas.pushMatrix();

				canvas.translate(midpoint.x, midpoint.y, midpoint.z);
				canvas.rotate(heading.heading() + PApplet.PI / 1.0f);
				canvas.box(heading.mag(), 5, 5);
				canvas.popMatrix();

I was also trying to play with getRotatedAroundAxis of Toxiclibs.

As noted - Any pointers will be greatly appreciated :wink:
Thanks!

1 Like

Hello, I may not have the exact solution, but you may find a simple workaround using these few lines of code:

Say you want to rotate something to face a normalized vector, v

rotateY(atan2(-v.x,-v.z));
rotateX(asin(-v.y));

works great for images that always face the camera

2 Likes

For very limited cases, you can hack 3D rotation using PVector and hope that you don’t run into gimbal lock.

As soon as you need something general-purpose, though, representing rotation state in terms of xyz has lots of known problems. Instead, use quaternions. They are complicated and it is a pain – but they actually work. The PeasyCam library has a great reference implementation.

1 Like

Thankyou for the good answer, jeremy! I intend to study the suggested peasycam example. For now, i have aimed my predatory cone using bennyhackers code. I had to use acos instead of asin.
I have so much to learn, as i would like to work with vr.

2 Likes

As @jeremydouglass points out the best solution is to use quaternions because they are flexible, powerful and don’t exhibit gimbol lock. Now having said that there are a number of caveats with using quaternions and using them with Processing.

Creating your own quaternion class is a possibility provided you are seriously good at maths and matrices, the alternative is to find a library implementation.

Both PeasyCam and Shapes3D libraries use the Apache Commons Maths Library which provides an easy to use Rotation class. This class is a wrapper for quaternions but concentrates on providing methods for rotating vectors which is what you want.

Sounds too good to be true? Here is the downside, the library uses the double data type throughout and Processing uses the float. The library also has its own vector class (Vector3D) and cannot (unsurprisingly) use Processing’s PVector class.

Just to prove we can all make mistakes, when I decided to incorporate this library into Shapes3D I spent days hacking the library code to provide a Rotation class that used float and the PVector class, i.e. compatible with Processing. I did a load of static tests comparing the output of Apache and my float version and they looked good. The problem came when using it for real, I got some very unexpected visual rotations and when I debugged the code I found a lot of Float.NaN values (NaN - not a number). It was obvious the float data type lacked the precision for some of the intermediate calculations. What a waste of time LOL.

PeasyCam and Shapes3D use slightly different approaches to using the library:

  • PeasyCam a beautiful library, has created a separate jar file (peasy-math.jar) for the maths and links to that.
  • Shapes3D is different because it needs a more intimate link with the Processing sketch and uses the PVector class. I have actually copied the source code of the relevant Maths library classes into Shapes3D and created a utility class to convert between PVector and Vector3D objects.

I suggest that you install Shapes3D because it exposes all of the Apche Maths library you need for rotations and the Util class in Shapes3D provided useful methods for converting between Vector3D and PVector objects.

Try some simple experiments first because it will take awhile to get to understand the Rotation class and how to use it, at least it did for me.

4 Likes

Wow, what a great answer, @quark. Sharing this kind of in-depth project experience is invaluable.

Hello,

Some additional resources:




https://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/

:)

3 Likes