1
votes

I am working on showing a 3D model (IFC) in Java3D. I need to rotate the object with 2 vectors, a direction vector and a axis vector that are given by the IFC model.

But I can't figure out how to get the right angle.

Code:

// Create vectors
Vector3f directionVector = new Vector3f(dx, dy, dz);
Vector3f axisVector = new Vector3f(ax, ay, az);

//Calculate angle
float angle = axisVector.angle(directionVector);

//create AxisAngle4f
AxisAngle4f axisAngle = new AxisAngle4f(axisVector, angle);

The axisVector is always (0.0, 0.0, 1.0), so it needs to be rotated on the Z-axis

But when I calculate the angle it seems always 1.5707964 (90°):

Example 1:
dir:    (-1.0, 0.0, 0.0)
axis:   (0.0, 0.0, 1.0)
angle:  1.5707964 (90.00000250447816)
AA:     (0.0, 0.0, 1.0, 1.5707964)

Example 2:
dir:    (0.0, 1.0, 0.0)
axis:   (0.0, 0.0, 1.0)
angle:  1.5707964 (90.00000250447816)
AA:     (0.0, 0.0, 1.0, 1.5707964)

Example 3:
dir:    (1.0, 0.0, 0.0)
axis:   (0.0, 0.0, 1.0)
angle:  1.5707964 (90.00000250447816)
AA:     (0.0, 0.0, 1.0, 1.5707964)

I know through testing that -1.0 means inverted so 180°.

Can some one help me understanding what I am doing wrong?

Edit

Documentation for the placement object (Direction and axis)

Screenshots of the results:

  • Orange: are the floors
  • Green: is the roof
  • Red: is de rotation point
  • Left: Side perspective
  • Right: Top perspective
  • The group of 3 slabs have direction direction (0.0, 1.0, 0.0)
  • The group of 2 slabs have direction direction (1.0, 0.0, 0.0)
  • Roof has direction: (-1.0, 0.0, 0.0)

I did the *2 test to simulate the 180° of -1.0. as you can see in the last example the roof is correctly drawn.

enter image description here

enter image description here

3

3 Answers

2
votes

You don't need the angle between the direction vector and the axis vector. Since your axis vector is always (0.0, 0.0, 1.0), you can define a constant vector of (1.0, 0.0, 0.0) to which you can compare the direction vector, i.e.:

// Create vectors
Vector3f directionVector = new Vector3f(dx, dy, dz);
Vector3f axisVector = new Vector3f(ax, ay, az);
Vector3f constantBaseVector = new Vector3f(1, 0, 0);

//Calculate angle
float angle = constantBaseVector.angle(directionVector);

//create AxisAngle4f
AxisAngle4f axisAngle = new AxisAngle4f(axisVector, angle);
1
votes

I'm guessing that axisVector.angle(directionVector) returns the angle between the two vectors.

In all three of your examples you're comparing unit vectors on the base axes with the unit vector of the z-axis, which are perpendicular to each other by definition. What are you expecting to get?

To me the angle between -x and z is 90°, the angle between y and z is 90° and the angle between x and z is 90°. So all the data is correct, what are you expecting to get?

EDIT:

Example one: angle between (-1, 0, 0) and (0, 0, 1) = 90° Example two: angle between (0, 1, 0) and (0, 0, 1) = 90° Example three: angle between (1, 0, 0) and (0, 0, 1) = 90°

Please draw these vectors in a cartesian coordinate system and it should be clear. Also, please note that the angle between two vectors is the smallest angle on the plane that these two vectors define.

1
votes

The angle between each axis should be 90°, and calculating the angle between any two vectors will only give values in the range 0° - 180°, rather than the 360° you need.

Also, if the zAxis is not (0, 0, 1), then you would need to calculate a rotation axis as well as the angle.

Instead, you can create a rotation matrix from the 3 axis directions, and create a transform object from that. The y-axis is the cross-product of the x and z axes:

// Given xAxis and zAxis.
Vector3f xAxis = new Vector3f(1, 0, 0);
Vector3f zAxis = new Vector3f(0, 0, 1);

// Create yAxis.
Vector3f yAxis = new Vector3f();
yAxis.cross(zAxis, xAxis);

// Create rotation matrix from axes.
Matrix4f rotationMatrix = new Matrix4f();
rotationMatrix.setRow(0, new Vector4f(xAxis));
rotationMatrix.setRow(1, new Vector4f(yAxis));
rotationMatrix.setRow(2, new Vector4f(zAxis));
rotationMatrix.setRow(3, new Vector4f(0, 0, 0, 1));

// Create transform.
Transform3D transform = new Transform3D(rotationMatrix);

// Transform points.
Vector3f vector = new Vector3f(0, 1, 0);
transform.transform(vector);
System.out.println(vector);