# how to add two rotations? - vrml

This is a discussion on how to add two rotations? - vrml ; Hi, can someone provide me the formula to add two rotaions like 1 0 0 1.57 + 0 1 0 1.57=? Thanks a lot Lucia...

1. ## how to add two rotations?

Hi,

can someone provide me the formula to add two rotaions like

1 0 0 1.57 + 0 1 0 1.57=?

Thanks a lot

Lucia

2. ## Re: how to add two rotations?

Use matrix addition? - can't remember of the top of my head..... try Google.

"Lucia" <cheng_lucia@yahoo.com> wrote in message
news:7390d0bf.0501100738.5c1a2db1@posting.google.com...
> Hi,
>
> can someone provide me the formula to add two rotaions like
>
> 1 0 0 1.57 + 0 1 0 1.57=?
>
> Thanks a lot
>
> Lucia

3. ## Re: how to add two rotations?

Lucia <cheng_lucia@yahoo.com> wrote:
> Hi,

> can someone provide me the formula to add two rotaions like

> 1 0 0 1.57 + 0 1 0 1.57=?

What means "add" ?

When you add two values, it makes no difference if you make (a + b) or (b + a)

For rotationations, it makes a difference, if you do rotation1 first and
rotation2 second or rotation2 first and rotation1 second.

To account two combined rotations, you can convert the axis/angle pair
to a normalized quaternion and then use quaternion multiplication.

There is a FAQ about matrix and quaternion math in the internet, which
tells about quaternions and rotations.

You can also use the multiply in the VRML javascript API, but unfortunalty
the standard do not clear say, what is first and what is second rotation, so
different browsers can give different results 8-(

#VRML V2.0 utf8

DEF Script1 Script
{
field SFRotation rot1 0 1 0 1.570000
field SFRotation rot2 0 0 1 1.570000
url
[
"javascript:

// field SFRotation rot1 //
// field SFRotation rot2 //

function initialize()
{
print('rot1 * rot2: ' + rot1.multiply(rot2));
print('rot2 * rot1: ' + rot2.multiply(rot1));
}

"
]
}

Transform
{
children
[
Transform
{
children
[
DEF Shape1 Shape
{
appearance Appearance
{
material Material
{
}
}
geometry Extrusion
{
crossSection
[
1.041146 -1.152379
-2.848128e-2 -2.414731
-1 -1
-1 1
0.755227 0.743695
]
solid FALSE
}
}
]
rotation 0 0 1 1.570000
}
]
rotation 0 1 0 1.570000
translation -3.460000 0 0
}

Transform
{
children
[
USE Shape1
]
rotation 0.577043 0.577503 0.577503 2.093480
translation 0.839999 0 0
}

Transform
{
children
[
Transform
{
children
[
USE Shape1
]
rotation 0 1 0 1.570000
translation 0.909412 0 7.242899e-4
}
]
rotation 0 0 1 1.570000
translation 2.100883e-3 2.637850 -0.209701
}

Transform
{
children
[
USE Shape1
]
rotation -0.577043 0.577503 0.577503 2.093480
translation -2.029705 2.639470 -0.209701
}

Viewpoint
{
orientation 4.273203e-2 0.997040 -6.390678e-2 0.455952
position 2.951291 1.185134 9.724634
}

4. ## Re: how to add two rotations?

Lucia wrote:
> Hi,
>
> can someone provide me the formula to add two rotaions like
>
> 1 0 0 1.57 + 0 1 0 1.57=?

To add VRML rotations you have to use quaternions. At the end of this
email is some C code that converts VRML rotation to quaternions,
multiplies quaternions to add the rotations, and converts the resulting
quaternion back to a VRML rotation.

There is also a tool called Dizzy available here
http://www.vapourtech.com/dev/vrmltools.php that adds VRML rotations.

--
Bob Lipman
http://cic.nist.gov/lipman/
--

/*
* A little program to figure out the single axis+angle that
* corresponds to a series of rotations.
*
* Written by Gavin Bell.
*/

#include <stdio.h>
#include <math.h>

/*
* Convert axis/angle to quaternion form:
* Assumes axis is unit-length, angle is in radians.
*/
void
to_quaternion(float axis[3], float angle, float result[4])
{
int i;
for (i = 0; i < 3; i++) {
result[i] = axis[i]*sin(angle / 2.0);
}
result[3] = cos(angle / 2.0);
}
/*
* Convert unit-length quaternion to axis/angle.
*/
void
from_quaternion(float q[4], float axis[3], float *angle)
{
int i;
*angle = acos(q[3]) * 2.0;
for (i = 0; i < 3; i++) {
axis[i] = q[i] / sin(*angle / 2.0);
}
}

/*
* Multiply two quaternions together. Result may be the same as
* either input:
*/
void
multiply_quaternion(float q1[4], float q2[4], float result[4])
{
float tmp[4];
tmp[0] = q2[3] * q1[0] + q2[0] * q1[3] +
q2[1] * q1[2] - q2[2] * q1[1];
tmp[1] = q2[3] * q1[1] + q2[1] * q1[3] +
q2[2] * q1[0] - q2[0] * q1[2];
tmp[2] = q2[3] * q1[2] + q2[2] * q1[3] +
q2[0] * q1[1] - q2[1] * q1[0];
tmp[3] = q2[3] * q1[3] - q2[0] * q1[0] -
q2[1] * q1[1] - q2[2] * q1[2];
result[0] = tmp[0]; result[1] = tmp[1];
result[2] = tmp[2]; result[3] = tmp[3];
}

#define MAX_ROTATIONS 10

main(int argc, char **argv)
{
float axis[MAX_ROTATIONS][3], angle[MAX_ROTATIONS];
float q[4], result_axis[3], result_angle;
int num_entered = 0;
int i;

printf("\nThis program allows you to enter a series of rotations\n"
"about the X, Y, or Z axes. It will combine them into\n"
"one rotation about an arbitrary axis, suitable for\n"
"use in a VRML camera's orientation field or any other\n"
"VRML SFRotation field.\n"
"Enter rotations as if you are rotating the object or\n"
"camera (the opposite order from nested transformations in\n"
"a VRML file):\n\n");

for (i = 0; i < MAX_ROTATIONS; i++) {
char axisString[10];
int done = 0;
float angle_degrees;

axis[i][0] = 0.0;
axis[i][1] = 0.0;
axis[i][2] = 0.0;
angle[i] = 0.0;

if (i == 0) {
printf("Axis (X, Y or Z): ");
} else {
printf("Axis [XYZ or Q]: ");
}
fflush(stdout);
scanf("%s", axisString);
switch(axisString[0]) {
case 'X':
case 'x':
axis[i][0] = 1.0;
break;
case 'Y':
case 'y':
axis[i][1] = 1.0;
break;
case 'Z':
case 'z':
axis[i][2] = 1.0;
break;
default:
done = 1;
break;
}
if (done) {
num_entered = i;
break;
}

printf("Angle in degrees: ");
fflush(stdout);
scanf("%f", &angle_degrees);
angle[i] = angle_degrees * 3.141592653 / 180.0;
printf(" You entered: (%g %g %g), %g\n", axis[i][0],
axis[i][1], axis[i][2], angle[i]);
}

to_quaternion(axis[0], angle[0], q);
for (i = 1; i < num_entered; i++) {
float q1[4];

to_quaternion(axis[i], angle[i], q1);
multiply_quaternion(q, q1, q);
}
from_quaternion(q, result_axis, &result_angle);

printf("\nCombined rotation is:\n");
printf("Transform { rotation %g %g %g %g }\n\n",
result_axis[0], result_axis[1], result_axis[2],
result_angle);

return 0;
}

5. ## Re: how to add two rotations?

Joerg Scheurich aka MUFTI <rusmufti@helpdesk.rus.uni-stuttgart.de>
wrote:
> You can also use the multiply in the VRML javascript API, but unfortunalty
> the standard do not clear say, what is first and what is second rotation, so
> different browsers can give different results 8-(

Cortona and Contact are consistent with each other, and with the usual
mathematical notation (which is as good a definition of "right" as any):
if rot3 = rot1.multiply(rot2), then the following two pieces of VRML
will apply the same transformation to the children.

Transform {
rotation rot3
children [ ... ]
}

Transform {
rotation rot1
children Transform {
rotation rot2
children [ ... ]
}
}

CosmoPlayer does it the other way round (i.e. "wrong"), but it's
obsolete and can be ignored.

In some browsers (I've found this with the Mac version of Cortona), you
must make sure that the axes of the SFRotations are normalised (i.e.
unit vectors) before calling .multiply(), otherwise you get incorrect
results.

-- Richard Kennaway

6. ## Re: how to add two rotations?

On Tue, 2005-01-11 at 14:33 +0000, Richard Kennaway wrote:

[snip]

> In some browsers (I've found this with the Mac version of Cortona), you
> must make sure that the axes of the SFRotations are normalised (i.e.
> unit vectors) before calling .multiply(), otherwise you get incorrect
> results.

Technically a browser is in error for allowing you even to have an
SFRotation whose axis isn't normalized. By definition, the axis of an
SFRotation is normalized.

--
Braden McDaniel e-mail: <braden@endoframe.com>
<http://endoframe.com> Jabber: <braden@jabber.org>

7. ## Re: how to add two rotations?

> Technically a browser is in error for allowing you even to have an
> SFRotation whose axis isn't normalized. By definition, the axis of an
> SFRotation is normalized.

The requirement of a normalized axis

http://www.web3d.org/x3d/specificati...tml#SFRotation

| The first three values specify a normalized rotation axis vector about
| which the rotation takes place.

is one of the silliest point in the VRML97 standard. The rotation axis vector
represent only a direction. Length make no sense for a direction.

If the length of the rotation axis vector would be allowed to be anything,
nothing is lost, cause only the normalization of a quaternion (which is
accounted differently) is required to account rotations.

The same problem is repeated in the X3D standard draft:

http://www.web3d.org/x3d/specificati...tml#SFRotation

| The first three values specify a normalized rotation axis vector about
| which the rotation takes place.

Most VRML browsers (except possibly OpenVRML based) understand not
normalized axis vectors, cause proofing the normalization costs about the
same computer time as normalizing the axis vector (which lead to nothing...).

so long
MUFTI
--
Englisch: Deutsch:
collator die Zusammentragmaschine
to collateralize [finan.] lombardieren
(von dict.leo.org)

8. ## Re: how to add two rotations?

Robert Lipman wrote:

> There is also a tool called Dizzy available here
> http://www.vapourtech.com/dev/vrmltools.php that adds VRML rotations.

Here's a simple Java applet I wrote which multiplies rotations:

http://www.ccir.ed.ac.uk/~jad/multiply/index.html

Beats doing it in your head.

James

9. ## Re: how to add two rotations?

bensmyth wrote:
> Use matrix addition? - can't remember of the top of my head..... try

Google.
>
> "Lucia" <cheng_lucia@yahoo.com> wrote in message
> news:7390d0bf.0501100738.5c1a2db1@posting.google.com...
> > Hi,
> >
> > can someone provide me the formula to add two rotaions like
> >
> > 1 0 0 1.57 + 0 1 0 1.57=?
> >
> > Thanks a lot
> >
> > Lucia

in my post "help finding fundamental 3d maths" the example i showed was
the use of vrmlmatrix to 'add' two rotations, this could have textual
output and draggable vectors added to produce a usable tool, or just
edit the example with the angles reguired.

simon.

10. ## Re: how to add two rotations? my code for VB

In Visual Basic I use :-

Sub xyzRotate( _
ByVal x As Double, ByVal y As Double, ByVal z As Double, _
ByRef ox As Double, ByRef oy As Double, ByRef oz As Double, ByRef w As
Double)

' computes one orientation and rotations from rotattions about x,y,z
' rotation is passed back byRef in ox,oy,oz,w

Dim i As Integer
Dim b As Double
Dim axisX(3) As Double, axisY(3) As Double, axisZ(3) As Double
Dim angle(9) As Double, q(4) As Double, r(4) As Double, a(4) As Double,
c(4) As Double

axisX(1) = 1: angle(1) = x
axisY(3) = 1: angle(3) = y
axisZ(2) = 1: angle(2) = z

For i = 1 To 3: q(i) = axisX(i) * Sin(angle(1) / 2): Next: q(4) =
Cos(angle(1) / 2)
For i = 1 To 3: r(i) = axisY(i) * Sin(angle(2) / 2): Next: r(4) =
Cos(angle(2) / 2)

a(1) = r(4) * q(1) + r(1) * q(4) + r(2) * q(3) - r(3) * q(2)
a(2) = r(4) * q(2) + r(2) * q(4) + r(3) * q(1) - r(1) * q(3)
a(3) = r(4) * q(3) + r(3) * q(4) + r(1) * q(2) - r(2) * q(1)
a(4) = r(4) * q(4) - r(1) * q(1) - r(2) * q(2) - r(3) * q(3)

For i = 1 To 3: r(i) = axisZ(i) * Sin(angle(3) / 2): Next: r(4) =
Cos(angle(3) / 2)

c(1) = r(4) * a(1) + r(1) * a(4) + r(2) * a(3) - r(3) * a(2)
c(2) = r(4) * a(2) + r(2) * a(4) + r(3) * a(1) - r(1) * a(3)
c(3) = r(4) * a(3) + r(3) * a(4) + r(1) * a(2) - r(2) * a(1)
c(4) = r(4) * a(4) - r(1) * a(1) - r(2) * a(2) - r(3) * a(3)

w = math.Acos(c(4)) * 2
b = Sin(w / 2)
If b = 0 Then b = 0.000001
ox = c(1) / b
oy = c(2) / b
oz = c(3) / b
End Sub

"Lucia" <cheng_lucia@yahoo.com> wrote in message
news:7390d0bf.0501100738.5c1a2db1@posting.google.com...
> Hi,
>
> can someone provide me the formula to add two rotaions like
>
> 1 0 0 1.57 + 0 1 0 1.57=?
>
> Thanks a lot
>
> Lucia

+ Reply to Thread
Page 1 of 2 1 2 Last