# How do I rotate a prim or linkset along an axis that is not the center?

Please take a moment to consider if this thread is worth bumping.

## Recommended Posts

Rotating a prim along the X, Y, or Z axis is easy. My question is how do you rotate a prim along a non-standard axis? An example I'm thinking of might be a wing flapping or a door swinging open. These do not rotate along the center but instead the edge of the prim.

I imagine there's a fair amount of math involved, and if so what is it? Or is there an easier way to do this that I'm just not seeing?

##### Share on other sites

It's all explained here: https://wiki.secondlife.com/wiki/Rotation#Rotating_Vectors

There's also a very good tutorial by Grandma Bates at SLU http://www.sluniverse.com/php/vb/tutorials/62479-introduction-rotations-translations-rotation-tutorial.html

So this, for example, is how  I might script a door if, for some reason, I didn't want to path-cut it (works in linked or unlinked prims):    You would need, of course, to play round with the offset and swing if you wanted to rotate it round a different axis.

`integer intSwing =90;rotation rotSwing;vector vOffset;default{    state_entry()    {       rotSwing = llEuler2Rot(<0.0,0.0,(float)intSwing>*DEG_TO_RAD);  //90 degress on the z axis       vector size = llGetScale();       vOffset = <(size.x*-0.5),(size.y*-0.5),0.0>;//open away from someone standing in front of face 2 -- that is, in front of the prim -- hinged on the left.    }    touch_start(integer total_number)    {         list l = llGetPrimitiveParams([PRIM_POS_LOCAL,PRIM_ROT_LOCAL]);         vector v = llList2Vector(l,0);         rotation r = llList2Rot(l,1);         llSetPrimitiveParams([PRIM_POS_LOCAL,v+(vOffset-vOffset * rotSwing)*r,         PRIM_ROT_LOCAL,rotSwing*r]);         rotSwing.s*=-1;             }}`

• 1
##### Share on other sites

I'm going to have to dig through this and try to make sense of it; I like to think I'm pretty compitent but this seems complex. Thank you for the links.

##### Share on other sites

If the prim is of type box or cylinder you can make it flexible.   That moves the rotation to the edge, and allows it to be moved smoothly by the X, Y, and Z flexi parameters.  Keep softness at 0 if you want the object to move without bending.

##### Share on other sites

Huh I had no idea about that. I will try that along with Innula Zenovka's suggestion. Thank you both!

##### Share on other sites

• 8 months later...

It looks to me like a typo error on this line of the script  ?

`llSetPrimitiveParams([PRIM_POS_LOCAL,v+( * rotSwing)*r,         PRIM_ROT_LOCAL,rotSwing*r]);`
##### Share on other sites

Operator precedence.

The product will be calculated first so the line equation works as "(vOffset - (vOffset * rotSwing))" - which is why I always use explicit parenthesis to avoid (even more) confusion.

##### Share on other sites

• 3 years later...
On 1/21/2013 at 5:56 PM, Innula Zenovka said:

It's all explained here: https://wiki.secondlife.com/wiki/Rotation#Rotating_Vectors

There's also a very good tutorial by Grandma Bates at SLU http://www.sluniverse.com/php/vb/tutorials/62479-introduction-rotations-translations-rotation-tutorial.html

So this, for example, is how  I might script a door if, for some reason, I didn't want to path-cut it (works in linked or unlinked prims):    You would need, of course, to play round with the offset and swing if you wanted to rotate it round a different axis.

Argh.. the migration to the new IPS forums has messed up my script's formatting

Here is the corrected version:

```integer intSwing =90;
rotation rotSwing;
vector vOffset;

default{

state_entry(){
rotSwing = llEuler2Rot(<0.0,0.0,(float)intSwing>*DEG_TO_RAD);  //90 degrees on the z axis
vector size = llGetScale();
vOffset = <(size.x*-0.5),(size.y*-0.5),0.0>;//open away from someone standing in front of face 2 -- that is, in front of the prim -- hinged on the left.
}

touch_start(integer total_number){
list l = llGetPrimitiveParams([PRIM_POS_LOCAL,PRIM_ROT_LOCAL]);
vector v = llList2Vector(l,0);
rotation r = llList2Rot(l,1);
llSetPrimitiveParams([PRIM_POS_LOCAL,v+(vOffset-vOffset * rotSwing)*r,PRIM_ROT_LOCAL,rotSwing*r]);

rotSwing.s*=-1;
}
}

```

• 2
##### Share on other sites

• 5 months later...
On 3/18/2017 at 10:28 AM, Innula Zenovka said:

Argh.. the migration to the new IPS forums has messed up my script's formatting

Here is the corrected version:

```
integer intSwing =90;
rotation rotSwing;
vector vOffset;

default{

state_entry(){
rotSwing = llEuler2Rot(<0.0,0.0,(float)intSwing>*DEG_TO_RAD);  //90 degrees on the z axis
vector size = llGetScale();
vOffset = <(size.x*-0.5),(size.y*-0.5),0.0>;//open away from someone standing in front of face 2 -- that is, in front of the prim -- hinged on the left.
}

touch_start(integer total_number){
list l = llGetPrimitiveParams([PRIM_POS_LOCAL,PRIM_ROT_LOCAL]);
vector v = llList2Vector(l,0);
rotation r = llList2Rot(l,1);
llSetPrimitiveParams([PRIM_POS_LOCAL,v+(vOffset-vOffset * rotSwing)*r,PRIM_ROT_LOCAL,rotSwing*r]);

rotSwing.s*=-1;
}
}

```

How do I modify this script so that the door is hinged on the left instead of the right, when facing the door? Appreciate any help, I don't have experience with this.

Thanks.

##### Share on other sites

Look at the math here....

`llSetPrimitiveParams([PRIM_POS_LOCAL,v+(vOffset-vOffset * rotSwing)*r,PRIM_ROT_LOCAL,rotSwing*r]);`

Try just changing v + (vOffset - vOffset * rotSwing) * r   to   v - (vOffset - vOffset * rotSwing) * r

##### Share on other sites

5 hours ago, Rolig Loon said:

Look at the math here....

```
llSetPrimitiveParams([PRIM_POS_LOCAL,v+(vOffset-vOffset * rotSwing)*r,PRIM_ROT_LOCAL,rotSwing*r]);```

Try just changing v + (vOffset - vOffset * rotSwing) * r   to   v - (vOffset - vOffset * rotSwing) * r

Thank you

##### Share on other sites

• 3 years later...
On 3/18/2017 at 11:28 PM, Innula Zenovka said:

Argh.. the migration to the new IPS forums has messed up my script's formatting

Here is the corrected version:

```
integer intSwing =90;
rotation rotSwing;
vector vOffset;

default{

state_entry(){
rotSwing = llEuler2Rot(<0.0,0.0,(float)intSwing>*DEG_TO_RAD);  //90 degrees on the z axis
vector size = llGetScale();
vOffset = <(size.x*-0.5),(size.y*-0.5),0.0>;//open away from someone standing in front of face 2 -- that is, in front of the prim -- hinged on the left.
}

touch_start(integer total_number){
list l = llGetPrimitiveParams([PRIM_POS_LOCAL,PRIM_ROT_LOCAL]);
vector v = llList2Vector(l,0);
rotation r = llList2Rot(l,1);
llSetPrimitiveParams([PRIM_POS_LOCAL,v+(vOffset-vOffset * rotSwing)*r,PRIM_ROT_LOCAL,rotSwing*r]);

rotSwing.s*=-1;
}
}

```

thank you, you save my day !

##### Share on other sites

Please take a moment to consider if this thread is worth bumping.