Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Need hellp with rotation math

Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
05-11-2006 00:37
CODE

| Root
| __
| / \
| | |
| \__/ ^
| //
| //
| //
| //
| //
| V Rot. center


The line down the left is to ensure the spaces show up correctly.

Let's say we have an object with 2 prims. A root prim that's a sphere, and a child prim that's a long bar or cylinder (for ease of illustration with bad ASCII art). Let's say the cylinder's length is along its local Z axis. The cylinder's position and rotation aren't aligned with the root prim.

I want to rotate the cylinder around one of its ends. What would the code for this look like? The rotation is easy, it will be:

CODE
llSetLocalRot(desiredRot * localRot);


Assuming my desired rotation is relative to the cylinder's local axis. But the problem is the translation that needs to happen with this rotation to get the prim to rotate around its end.

I've managed to get partway through this, I think. To find the rotation center, this is what I did:

CODE

vector p = llGetLocalPos(); // This is the vector from center of root prim to center of cylinder

vector direction = llRot2Up(llGetLocalRot()); // Unit vector pointing in the direction of the cylinder

vector size = llGetScale();
float length = size.z; // Length of prim
vector cylinder = direction * length; // Vector "pointing in the direction of the cylinder", magnitude is the length of the cylinder

vector rotOrigin = p - (cylinder / 2.0); // Subtract half the length of the cylinder


Hopefully, so far so good? But here's the problem. I tried:

CODE
vector newPos = rotOrigin + (p - rotOrigin) * desiredRot * localRot;


But that didn't seem to work, probably because the rotation is calculated relative to the cylinder, but this ends up rotating the same angle around the root prim? Or something like that. This is where my brain explodes, so I won't try to explain it any further. If anyone knows how to do this, I will be most grateful :)

And I can't build this so that the cylinder is cut in a way that the prim center is at the visible end of the prim. This will be on a flexi prim so the length of the prim has to be its Z axis, and the only cut that I know of that will allow me to cut in half on the Z axis is the sphere -> dimple -> back to cylinder torture sequence, which is undone when you turn flexi on. But if there is some other building trick I can use to achieve this, that would help a lot too.

Thanks,
Ziggy
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
05-11-2006 00:57
I'm not great at these things, but I don't know if these operations are commutative. It might be that putting brackets around the desiredRot * localRot part at the end, to force it to evaluate the final rot and then multiply by the vector gives you the right result... Past that, sorry, can't help... hopefully someone who's more comfortable with these lovely things will come by soon!
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
05-11-2006 01:25
You mean associative Eloise, and yes, they should be.

Ziggy, so a kindof dumb way to get it working... if you know how to get the position of the endpoint of the cylinder before you rotate it, then run the same algorithm to find the endpoint of the cylinder after you rotate it (using the new rotation in the same function). Then offset the position by the difference of the two results. It seems to me that has to work...
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
05-11-2006 02:15
Thank Siefert! Told you I was no good at these!
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
05-11-2006 08:14
I tried the braces thing, didn't do much good.

The endpoint of the cylinder after I rotate it... but that's the thing, I want to rotate around the endpoint, so that position shouldn't change after the rotation. Though maybe I could calculate the other endpoint, the one that's moving, and then find the midpoint between the two endpoints and try and put the prim there. That's worth trying.

I am so bad at this :)
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
05-11-2006 11:48
CODE
vector p;// This is the vector from center of root prim to center of cylinder
rotation desiredRot;

vector rot_origin(rotation my_local_rot)
{
vector direction = llRot2Up(my_local_rot); // Unit vector pointing in the direction of the cylinder

vector size = llGetScale();
float length = size.z; // Length of prim
vector cylinder = direction * length; // Vector "pointing in the direction of the cylinder", magnitude is the length of the cylinder

return p - (cylinder / 2.0); // Subtract half the length of the cylinder
}

default
{
state_entry()
{
p = llGetLocalPos();
vector rot_origin_before = rot_origin(llGetLocalRot());
rotation new_local_rot = desiredRot * localRot;
vector rot_origin_after = rot_origin(new_local_rot);
llSetLocalRot(new_local_rot);
llSetPos(p - rot_origin_before + rot_origin_after);
}
}


Assuming your code to find the rot_origin works (I haven't checked it), this should do what you want. I think. I haven't tested any of this...
_____________________
-Seifert Surface
2G!tGLf 2nLt9cG
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
05-11-2006 12:03
Ahh, I see. Rotate the prim around its center, find where the end moved to, and then move it back. Now I understand what you were saying. I'll try this out tonight. Thanks a lot, it's definitely a good idea :)
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
05-12-2006 00:20
It worked! Yay! :) Thanks a lot.

I had to make one small change. This line:

CODE
llSetPos(p - rot_origin_before + rot_origin_after);


... had to be reversed. after - before is the direction in which the endpoint moved due to the rotation. I'm trying to negate that, so that line changed to

CODE
llSetPos(p + rot_origin_before - rot_origin_after);


But the basic idea worked great :)