Getting Real Rotation
|
|
Lazink Maeterlinck
Registered User
Join date: 8 Nov 2005
Posts: 332
|
02-14-2009 13:16
Ok, I thought I got what I needed, but it wasn't working properly.
I want to find the angle between the z-axis (world) and the local x-axis. So to do so, I need to get the llRot2Fwd result (should be the x axis vector) and find the angle between that and the world z-axis, <0.0, 0.0, 1.0>, so I can figure out the angle between them from 0 (local x axis pointing straight up) all the way to 359 degrees. Now, I can crack open one of my old Calc books and do it manually, but is there an LSL function that has this built in already? I tried llAngleBetween and llRotBetween, but neither does the result I want.
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
02-14-2009 15:45
From: Lazink Maeterlinck the local x axis is pointing in relation to the local z axis Sure you don't mean "the local x axis is pointing in relation to the world z axis"?
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Lazink Maeterlinck
Registered User
Join date: 8 Nov 2005
Posts: 332
|
02-14-2009 15:50
Yes I did, why I edited the question about a billion times  you caught me between edits 
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
02-14-2009 16:10
Okay then, just in case we are on the same wavelength now try this simple compass I use. It demos a couple of different things: integer onOff = 1; rotation rotOffset;
default { touch_start(integer n) { if (onOff) { rotOffset = llEuler2Rot(<0,0,0>);//90 * DEG_TO_RAD //Just depending on the prim type or if you are attaching as a hud //you can adjust the rotOffset here. //Example: this will work fine in a box prim in world but attach it to hud //point and you will need to change this to: //rotOffset = llEuler2Rot(<0,0,270 * DEG_TO_RAD>); llSetText("", <0, 0, 0 >, 0.0); llSetTimerEvent(0.5); } else { llSetText("", <0, 0, 0 >, 0.0); llSetTimerEvent(0.0); } onOff = !onOff; } timer() { vector fwd = llRot2Fwd(llGetRot() * rotOffset); integer rot = (integer) (llRot2Angle(llGetRot() * rotOffset) * 57.296); if (fwd.y > 0) { rot = 180 + (180 - rot); } llSetText("bearing = " + (string) rot, <1, 0, 0 >, 1.0); } }
EDIT: Between your edits and my posting this. I think my example which was just meant to demo a couple of points is actually much closer to what you were actually asking for 
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Lazink Maeterlinck
Registered User
Join date: 8 Nov 2005
Posts: 332
|
02-14-2009 16:25
it's close..... what I need is to basically get the angle between the world z axis, and the object x-axis, from 0 degrees (being local x-axis pointing straight up) to 359.9999, (local x-axis pointing slightly to the left of the world z-axis). When I use your code, I'm getting a few weird spots where it's reporting pointing straight down is 240 from 90. (90 degree clockwise turn).
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
02-14-2009 16:29
From: Lazink Maeterlinck it's close..... what I need is to basically get the angle between the world z axis, and the object x-axis, from 0 degrees (being local x-axis pointing straight up) to 359.9999, (local x-axis pointing slightly to the left of the world z-axis). When I use your code, I'm getting a few weird spots where it's reporting pointing straight down is 240 from 90. (90 degree clockwise turn). Try replacing llRot2Fwd with llRot2Up or llRot2Left and then correct this part: if (fwd.y > 0)
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Lazink Maeterlinck
Registered User
Join date: 8 Nov 2005
Posts: 332
|
02-14-2009 19:02
Ok, Jesse and I worked on the problem and still couldn't get it to work right. I took a 2D approach and got this, which works fine from 0 to 180, probibly can do a quandrent check default { touch_start(integer total_number) { //Formula is cos theta = (<a> * <b>) / (||a|| * ||b||) vector UP = <0.0, 0.0, 1.0>; vector localXAxis = llRot2Fwd(llGetRot()); float dotProduct = UP * localXAxis; float magnitude = llVecMag(localXAxis); // left out mag of UP because it's 1 float angle = llAcos(dotProduct / magnitude) * RAD_TO_DEG; llSay(0, (string) angle); } }
Jesse tried to get it to work in 3D with this: integer onOff = 1; rotation rotOffset;
default { touch_start(integer n) { if (onOff) { rotOffset = llEuler2Rot(<-90 * DEG_TO_RAD,0,0>);//90 * DEG_TO_RAD llSetText("", <0, 0, 0 >, 0.0); llSetTimerEvent(0.5); } else { llSetText("", <0, 0, 0 >, 0.0); llSetTimerEvent(0.0); } onOff = !onOff; } timer() { vector fwd = llRot2Fwd(llGetRot() * rotOffset); integer rot = (integer) (llRot2Angle(llGetRot() * rotOffset) * 57.296); if (fwd.y > 0) { rot = 180 + (180 - rot); } llSetText("fwd = " + (string)fwd + "\nbearing = " + (string) rot, <1, 0, 0 >, 1.0); } }
both work on certain conditions, but neither of us can figure out a way to make it work when the object is rotated arbitralily. Any help would be much appreciated.
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
02-14-2009 19:27
Adn to put it in context. This is a cylinder which has been rotated 90 on it's x axis. Just imagine a clock face and trying to get that reading. Mine works as long as the prim is set at <90,0,variable> but if you take and change the y then it skews the output.
brain hurts!
Hey Void!!!!! Where ru? I love the simple way you explain rots!
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
02-14-2009 23:27
I'm not exactly sure what you mean if you're asking for an angle between 0 and 360 degrees. For any two arbitrary vectors in 3-space, there is an angle between them that ranges from 0 to 180 degrees. You should be able to get it using the following logic: float angleBetween = llAcos(v1*v2); float angleBetweenInDegrees = angleBetween*RAD_TO_DEG;
I'm not sure what you want in terms of angles between two vectors if you expect angles greater than 180 degrees. Unless you mean like a compass heading? That goes like this: rotation currRot = llGetRot(); vector fwd = llRot2Fwd(currRot);
float heading; if (llFabs(fwd.z) >: 0.999) { // Pointing straight up/down. Choose some angle arbitrarily, like... heading = 0.0; } else { heading = llAtan2(fwd.y, fwd.x); }
float headingInDegrees = heading*DEG_TO_RAD;
|
|
Lazink Maeterlinck
Registered User
Join date: 8 Nov 2005
Posts: 332
|
02-15-2009 00:02
Yeah, I got the logic for angle between two vectors, and got it to work like 99% of the time using that and checking the quadrent that the local x is pointing in. But it's that 1% that is killing me. It's now turned into more of trying to understand this rotations in SL better for me. Let me explain how this would work. You have a cylinder, on the top side, is an arrow pointing in a direction, like a compass, that is constantly spinning around (around the local z-axis). Now, you toss the compass in the air, and it rotates on all axis. What I want to know how to do, is how to get the direction the arrow is pointing, whenever I want, as if I was looking at the compass head on. It may be simple, just look at the forward axis, and the up axis, and the world z axis, and it may not, but it's been kicking my butt for a while. 
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
02-15-2009 10:31
Err...yeah. If the arrow points in the direction of the prim's local x-axis, it should just be a matter of 'llRot2Fwd(llGetRot())' at any particular point in time.
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
02-15-2009 11:51
From: Hewee Zetkin Err...yeah. If the arrow points in the direction of the prim's local x-axis, it should just be a matter of 'llRot2Fwd(llGetRot())' at any particular point in time. Nope
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
02-15-2009 12:45
Why do you say that? If the arrow points in the direction of the prim's x-axis, and you want to know which way the arrow is pointing in global coordinates, we know pretty well a reliable and accurate way to get that vector. I'm not sure where the, "Nope," comes in. Which part are you disagreeing with?
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
02-15-2009 12:50
From: Hewee Zetkin Why do you say that? If the arrow points in the direction of the prim's x-axis, and you want to know which way the arrow is pointing in global coordinates, we know pretty well a reliable and accurate way to get that vector. I'm not sure where the, "Nope," comes in. Which part are you disagreeing with? All of it. Did you actually try it in world????????????? Or are you just theorizing Heewee?
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Lazink Maeterlinck
Registered User
Join date: 8 Nov 2005
Posts: 332
|
02-15-2009 12:51
That doesn't work, because it gives you the forward axis (local x) yes, but to check that with relation to how it's orientated around the local z, and the world z. I'll pull out my calc book some and see if I can find a good formula there, I suppose, but if anyone has run into this problem, and has a solution, and willing to share, would love to know! 
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
02-15-2009 15:34
I've used it many, many times in-world.
I guess the question is really what is expected. How is it oriented around the local z-axis? In the same way it is ALWAYS oriented relative to the local z-axis. It is at right angles to both the local z-axis and the local y-axis, such that x%y=z in the usual right-hand manner. How is it oriented relative to the world z-axis? Well, 'fwd = llRot2Fwd(llGetRot())' gives the local x-axis direction in the global coordinate frame. If you want the angle between local x and global z, 'llAcos(fwd.z)' will give it. If you want the "heading", so to speak, 'llAtan2(fwd.y, fwd.x)' will give it. Not exactly sure what other angle or orientation you are looking for. Not sure exactly what other angle or orientation is useful. Maybe you can clarify with a picture or something so we can come up with an answer for this so-far vaguely defined question.
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
02-15-2009 15:50
From: Hewee Zetkin Maybe you can clarify with a picture or something so we can come up with an answer for this so-far vaguely defined question. Post # 8 "Adn to put it in context. This is a cylinder which has been rotated 90 on it's x axis. Just imagine a clock face and trying to get that reading. Mine works as long as the prim is set at <90,0,variable> but if you take and change the y then it skews the output." Take a cylinder and drop t in world with these numbers in the edit window<90,0,0>. THis will turn it on it's side. Now drop this script in it from post#7 integer onOff = 1; rotation rotOffset;
default { touch_start(integer n) { if (onOff) { rotOffset = llEuler2Rot(<-90 * DEG_TO_RAD,0,0>);//90 * DEG_TO_RAD llSetText("", <0, 0, 0 >, 0.0); llSetTimerEvent(0.5); } else { llSetText("", <0, 0, 0 >, 0.0); llSetTimerEvent(0.0); } onOff = !onOff; } timer() { vector fwd = llRot2Fwd(llGetRot() * rotOffset); integer rot = (integer) (llRot2Angle(llGetRot() * rotOffset) * 57.296); if (fwd.y > 0) { rot = 180 + (180 - rot); } llSetText("fwd = " + (string)fwd + "\nbearing = " + (string) rot, <1, 0, 0 >, 1.0); } }
Footnote per post #7 "both work on certain conditions, but neither of us can figure out a way to make it work when the object is rotated arbitralily. Any help would be much appreciated." That script with that prim works fine rotating the prim around it's local z axis which is the world x axis, reading the bearing correctly. But take and rotate it around the world z axis and the results are not right. Don't know how to make it any more un-vague. It is readily apparent that there is a problem when it is tried in world.
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Lazink Maeterlinck
Registered User
Join date: 8 Nov 2005
Posts: 332
|
02-15-2009 16:11
Ok, Lets try this example:
You have a clock with a second hand, constantly spinning, not ticking but a constant spin at any speed. I take the clock, and throw it in the air, making it tumble on all axis'. So now it's rotating around the local x (the second hand pointing in the same direction at the local positive x) it's local y, and it's local z, (so it's rotating in all three dimensions) as the clock is in the air, I want to know exactly what time it is, by looking at the second hand at any moment in time, and being able to translate where it's pointing to, to the time it actually is.
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
02-15-2009 16:32
From: Lazink Maeterlinck Ok, Lets try this example:
You have a clock with a second hand, constantly spinning, not ticking but a constant spin at any speed. I take the clock, and throw it in the air, making it tumble on all axis'. So now it's rotating around the local x (the second hand pointing in the same direction at the local positive x) it's local y, and it's local z, (so it's rotating in all three dimensions) as the clock is in the air, I want to know exactly what time it is, by looking at the second hand at any moment in time, and being able to translate where it's pointing to, to the time it actually is. Okay. That makes sense. The reason it makes sense, and the ONLY reason it makes sense, is that the clock has moving parts. It's not ONE arrow, but two (no, THREE, because presumably we only look at the clock from the front side and can distinguish between 2 o'clock and 10 o'clock even if the numbers aren't written). The 12 o'clock position is not, for example, the clock's z-axis; if it were, the second hand would be stuck pointing at 3 o'clock, 9 o'clock, or straight in or out of the clock's face. If you wanted to impose other constraints on the problem, like, "The clock's 12 o'clock position always points as close to vertical as possible," then there is another reference we can compare to (but we might need a third, as I eluded to above when I spoke of only looking at the clock from the "front"  . Otherwise, you might need to compose your object of two prims. P.S. Jesse - I tend to ignore code logic that works, "some," or even, "most," of the time. That implies the code is based on incorrect logic and is NOT necessarily a correct indication of the intent of the writer. That's why I usually ask for a written, intuitive explanation of what is desired in this kind of situation.
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
02-15-2009 16:40
From: Hewee Zetkin Okay. That makes sense. The reason it makes sense, and the ONLY reason it makes sense, is that the clock has moving parts. It's not ONE arrow, but two (no, THREE, because presumably we only look at the clock from the front side and can distinguish between 2 o'clock and 10 o'clock even if the numbers aren't written). The 12 o'clock position is not, for example, the clock's z-axis; if it were, the second hand would be stuck pointing at 3 o'clock, 9 o'clock, or straight in or out of the clock's face. If you wanted to impose other constraints on the problem, like, "The clock's 12 o'clock position always points as close to vertical as possible," then there is another reference we can compare to (but we might need a third, as I eluded to above when I spoke of only look at the clock from the "front"  . Otherwise, you might need to compose your object of two prims. P.S. Jesse - I tend to ignore code logic that works, "some," or even, "most," of the time. That implies the code is based on incorrect logic and is NOT necessarily a correct indication of the intent of the writer. That's why I usually ask for a written, intuitive explanation of what is desired in this kind of situation. Wait after all of this, after even the code was ignored, after descriptions were called vague even thou anyone had to do was log in , give it a spin and it was clear as ice. This is it? A detailed, actually over detailed and now obtuse re-explanation? LMAO I'll repeat once again. Hey Void!!!!!
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime. From: someone I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
02-15-2009 16:46
From: Jesse Barnett Wait after all of this, after even the code was ignored, after descriptions were called vague even thou anyone had to do was log in , give it a spin and it was clear as ice. This is it? A detailed, actually over detailed and now obtuse re-explanation? LMAO
I'll repeat once again. Hey Void!!!!! The, "over detailed and now obtuse re-explanation," was actually an explanation of why this is impossible without further logical constraints, using the same metaphor used in the very clear problem statement given by Lazink's last post.
|
|
Taff Nouvelle
Virtual Business Owners
Join date: 4 Sep 2006
Posts: 216
|
02-15-2009 17:23
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
02-15-2009 17:26
Okay. I am going to take a stab at it based on the ASSUMPTION that the "clock's" local z-axis points in the clock's "forward" direction (meaning you'd always choose to look at the clock from a point in the clock's POSITIVE, not negative, z-direction) and the ASSUMPTION that the clock's 12 o'clock position always points "up" (like it is magnetically attracted to the sky). These are my best GUESSES based on the problem statement, but they may not be what Lazink intends. I have as yet no way of knowing. rotation rot = llGetRot(); vector secondHandDir = llRot2Fwd(rot); vector outOfFaceDir = llRot2Up(rot); if (llFabs(outOfFaceDir.z) > 0.999) { // Clock is flat, with its face pointed either straight up or straight down. // No way of knowing which way the clock's 12 o'clock position should point. // Therefore, can't find answer. } else { vector threeOclockDir = llVecNorm(<0.0, 0.0, 1.0>%outOfFaceDir); vector twelveOclockDir = outOfFaceDir%threeOclockDir; // Already a unit vector
float horizontalComp = secondHandDir*threeOclockDir; float verticalComp = secondHandDir*twelveOclockDir;
float angleInRad = llAtan2(horizontalComp, verticalComp); if (angleInRad < 0.0) { amgleInRad += TWO_PI; } float angleInDeg = angleInRad*RAD_TO_DEG;
float seconds = 60.0*angleInRad/TWO_PI; // ;-) }
Try to picture in your mind which way each of these vectors will be pointing. Maybe cutting out a circular piece of paper and sticking a needle through the middle to point in the local z direction ('outOfFaceDir'), then figuring out what direction each cross-product will produce using the right-hand-rule will help (perhaps draw and label each on the paper). See http://en.wikipedia.org/wiki/Right-hand_rule
|
|
Lazink Maeterlinck
Registered User
Join date: 8 Nov 2005
Posts: 332
|
02-16-2009 00:12
Sorry it took so long to reply, from my testing, this works very well Hewee, Thank you. If I understand this right, your finding the plane that includes the world z axis, and the up axis, then finding the vector that is perpendicular to to the up axis, that falls in the plane that we found. Then you find the angle between the perpendicular axis and the fwd axis. This problem really kicked my butt, hate 3d rotation. Big thank you to Jesse and Hewee for helping me work on this problem. 
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
02-16-2009 13:04
Glad it helped. Sometimes (or maybe often) coming up with the right questions is more difficult even than coming up with the answers to those questions.
|