Rotational Math - 1,000 $L reward for solution
|
|
Sinuna Falta
Registered User
Join date: 9 Jul 2007
Posts: 3
|
01-14-2008 04:07
same problem.. still looking for a solution to this rotational nightmare.. but will pay again.. if I can just get it solved.
1,000 Linden prize to the person who can slove it.
PROBLEM DESCRIPTION RESTATED:
1.) take a cube which has been randomly spun so that it has a known but unpredictable rotation. 2.) draw an imaginary line from the center of the cube passing through the center of side 1 and extending forever. 3.) view this line from directly above the cube and it will point in a compass direction.. ie: North, South... South-South-East etc. 4.) COMPUTE THE ROTATION NECESSARY TO SET THE CUBE SO THAT: a.) the immaginary line still points in the same compass direction. b.) Side 2 of the cube points directly UP.
SAME PROBLEM STATED DIFFERENTLY:
1.) Immagine an Avatar has spun wildly and is in a random position. 2.) draw a line out of her belly-button extending forward. 3.) that line (when viewed from directly above or below) will define the desired Z rotation. 4.) force her X and Y rotations to ZERO.. and her Z to the desired rotation. ie: stand her up straight but keep her faceing in the same compass direction.
PS.. Previous winners can keep their prizes.. you've all done a lot to help me understand this wierd thing SL calls math. And you're invited to help again. Note: this problems was first posted on SLX in Mid-December and prises were awarded.. re-opening the contest because I still need the answser.
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
01-14-2008 07:40
// Flatten rotation on XY plane // Ordinal Malaprop // 14 January 2008
default { state_entry() { llSetText("Rotate me and then touch me to flatten my rotation", <1.0, 1.0, 1.0>, 1.0); }
touch_start(integer n) { rotation rot = llGetRot(); // This is the direction the object is facing vector fwd = llRot2Fwd(rot); // Flatten it on the XY plane fwd = llVecNorm(<fwd.x, fwd.y, 0.0>); // Now rotate to point in that direction llSetRot(llRotBetween(<1.0, 0.0, 0.0>, fwd)); } }
_____________________
http://ordinalmalaprop.com/forum/ - visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!
http://ordinalmalaprop.com/engine/ - An Engine Fit For My Proceeding, my Aethernet Journal
http://www.flickr.com/groups/slgriefbuild/ - Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
01-14-2008 07:43
That should do what I think you are asking. It flattens the current forward vector relative to the XY plane, and points the object towards that vector. Of course it would only work for nonphysical objects, since it uses llSetRot, but that gives you the correct rotation, anyway.
_____________________
http://ordinalmalaprop.com/forum/ - visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!
http://ordinalmalaprop.com/engine/ - An Engine Fit For My Proceeding, my Aethernet Journal
http://www.flickr.com/groups/slgriefbuild/ - Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
01-14-2008 09:44
I do not wish monetary reward for helping. That's why I'm posting in this forum. Please keep the L$ or give it to Ordinal, who posted at least half the solution already. You are wording the problem in terms of a coordinate system, so the best way to solve it is by using a function that maps a set of axes to a rotation. The LSL library has such a function: llAxes2Rot(). From the second problem statement, I take it you want the horizontal direction of the x-axis to remain constant, and for the z-axis to be aligned with the world's z-axis. Ordinal showed how to compute the correct x-axis. So what remains is to take a vector product to find the desired y-axis: vector origX = llRot2Fwd(rot); vector newX = llVecNorm(<origX.x, origX.y, 0.0>); vector newZ = <0.0, 0.0, 1.0>; vector newY = newZ%newX; // should already be a unit vector, since newX and newZ are orthonormal rotation newRot = llAxes2Rot(newX, newY, newZ);
There is a corner case that is very unlikely, but that you might test for. If origX.x and origX.y are both zero (the object is "facing" straight up or down), you PROBABLY want to rotate about the y-axis, so that the xz-plane doesn't change. Like so: vector origZ = llRot2Up(rot); vector newX; if (origX.z < 0.0) // facing down { newX = origZ; } else // facing up { newX = -origZ; } vector newZ = <0.0, 0.0, 1.0>; vector newY = newZ%newX; // should already be a unit vector, since newX and newZ are orthonormal rotation newRot = llAxes2Rot(newX, newY, newZ);
|
|
Tyken Hightower
Automagical
Join date: 15 Feb 2006
Posts: 472
|
01-14-2008 10:14
Ordinal's should give the same rotation as yours. Also, there is no need to change the corner result, as it has an undefined compass direction, and altering it is meaningless.
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
01-14-2008 13:09
From: Tyken Hightower Ordinal's should give the same rotation as yours. Not necessarily. Ordinal's computation ensures that the x-axis points in the correct direction. This doesn't NECESSARILY guarantee the other axes point in the correct direction, at least in the general case. There is still a degree of freedom that hasn't been nailed down, so the cube/avatar COULD wind up facing in a horizontal direction, but with your "up" being sideways. From: someone Also, there is no need to change the corner result, as it has an undefined compass direction, and altering it is meaningless. For absolute correctness you are right; it falls outside the problem domain. However, if this is being used for something practical, this case too might be desired. I suggested this solution because it seemed natural to me to keep the xz-plane the same and pitch until horizontal. It is how we normally recover from looking straight up or down as humans, and it is "continuous", so to speak, with the answer if the x-axis is close to vertical. By the way, there's a simpler version of the corner case solution. It is equivalent: vector origY = llRot2Left(rot); vector newY = origY; vector newZ = <0.0, 0.0, 1.0>; vector newX = newY%newZ; // should already be a unit vector, since newY and newZ are orthonormal rotation newRot = llAxes2Rot(newX, newY, newZ);
|
|
Lee Ponzu
What Would Steve Do?
Join date: 28 Jun 2006
Posts: 1,770
|
01-14-2008 13:49
I am not clear why you would do vector newX = llVecNorm(<origX.x, origX.y, 0.0>  ; The flatten should be to whatever altitude the object is currently at, not to 0.0 (I think) which would be p = llGetPos(); flat = < orig.x, orig.y, p.z > Also, why bother with the llVecNorm? It doesn't seem to add anything useful, and can be computationally nasty. Lastly, to the original problem formation, have you thought about when the avatar ends up almost on its back or front. As the others say, in this case you don't really have a very clear compass direction. Maybe you should spin again or something. lee
_____________________
So many monkeys, so little Shakespeare.
|
|
Seifert Surface
Mathematician
Join date: 14 Jun 2005
Posts: 912
|
01-14-2008 15:21
From: Lee Ponzu flat = < orig.x, orig.y, p.z > OrigX is a vector specifying a direction, not a position. The desired direction should have zero z in the component. From: Lee Ponzu Also, why bother with the llVecNorm? It doesn't seem to add anything useful, and can be computationally nasty. llAxes2Rot doesn't like it if the input is not in the form of perpendicular unit vectors. It gives the wrong answer unless the vectors are normalised.
_____________________
-Seifert Surface 2G!tGLf 2nLt9cG
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
01-14-2008 15:23
We are dealing with vectors here, not points. Essentially direction, not position. It is unfortunate that most 3D libraries do not make the distinction. Just think of it as RELATIVE to a location; in this case, the location of the avatar/object. If an avatar in the final orientation extended its arm and pointed in the direction it was looking, there would be no z difference in the arm from shoulder to fingertip, therefore the z component of the local x-axis direction is zero.
The vectors are normalized because normal vectors are very useful when talking about direction. If we didn't do it in the LSL, it would be done eventually by the server to calculate a local transformation anyway. llAxes2Rot() requires normal (and orthogonal) vectors in any case, and can act very strange when it doesn't get them.
EDIT: Oops. Slow typer, as always. LOL.
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
01-14-2008 15:44
From: Hewee Zetkin Not necessarily. Ordinal's computation ensures that the x-axis points in the correct direction. This doesn't NECESSARILY guarantee the other axes point in the correct direction, at least in the general case. There is still a degree of freedom that hasn't been nailed down, so the cube/avatar COULD wind up facing in a horizontal direction, but with your "up" being sideways. It won't, though; there is no cause to change that axis when rotating the forward position between <1,0,0> and the target, and that aside, the function doesn't think there is, either. I see the point but that is not how the function acts.
_____________________
http://ordinalmalaprop.com/forum/ - visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!
http://ordinalmalaprop.com/engine/ - An Engine Fit For My Proceeding, my Aethernet Journal
http://www.flickr.com/groups/slgriefbuild/ - Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
01-14-2008 16:28
From: Ordinal Malaprop It won't, though; there is no cause to change that axis when rotating the forward position between <1,0,0> and the target, and that aside, the function doesn't think there is, either. I see the point but that is not how the function acts. Actually the llRotBetween() function simply returns a rotation that when applied to the first vector results in the second. There are plenty of examples where applying this rotation would NOT leave the local z-axis pointed straight up. For example, what if the original orientation were up-side-down, with the forward direction already horizontal? llRotBetween() would think there is no rotation to be done. Also, this is a relative rotation; to apply it to the object (imagine applying it to the fwd vector), you'd have to concatenate it with the object's current rotation: llSetRot(llGetRot()*llRotBetween(<1.0, 0.0, 0.0>, fwd)); Otherwise it would be like applying the difference in orientation between fwd and the new forward vector to the unrotated forward vector (<1.0, 0.0, 0.0>  , which doesn't make sense.
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
01-14-2008 16:42
From: Hewee Zetkin For example, what if the original orientation were up-side-down, with the forward direction already horizontal? llRotBetween() would think there is no rotation to be done. It doesn't. It is hardcoded. The original position assumes a vertical Z-axis. By all means try it. The rotation generated by the llRotBetween is between a standard all-axes-parallel-to-standard-ones, to an x-and-y-pointing-towards-a-vector-and z-parallel-to-standard.
_____________________
http://ordinalmalaprop.com/forum/ - visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!
http://ordinalmalaprop.com/engine/ - An Engine Fit For My Proceeding, my Aethernet Journal
http://www.flickr.com/groups/slgriefbuild/ - Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
01-14-2008 17:01
From: Ordinal Malaprop The rotation generated by the llRotBetween is between a standard all-axes-parallel-to-standard-ones, to an x-and-y-pointing-towards-a-vector-and z-parallel-to-standard. Strange. If so, it is an undocumented feature. The LSL editor states simply "rotation llRotBetween(vector v1, vector v2) returns the rotation to rotate v1 to v2". Also see http://wiki.secondlife.com/wiki/LlRotBetween and http://www.lslwiki.net/lslwiki/wakka.php?wakka=llRotBetweenIn fact, even as you state it this cannot work except in a certain set of cases; there are an infinite number of starting reference frames with the forward axis pointed in a particular direction, and only one correct final reference frame. Even if llRotBetween() assumes the final reference frame has a horizontal y-axis, you cannot provide it with enough information for it to accurately know your initial frame. The transformation cannot be many-to-one.
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
01-14-2008 17:11
Bah. NVM. I'm sorry if I'm confusing folks. Ordinal is correct. Because this was very similar to an application I did a while ago (and probably because I've been operating on about 1.5 hours of sleep), I thought we were losing too much information. But actually the final solution IS unique for any horizontal direction. The application I developed before actually preserved as much orientation as possible while making the local y-axis horizontal, which is a bit different.
Apologies all the way around.
My confusion lay in the fact that a relative rotation was being used. But that relative rotation was being calculated AND applied to an initial reference frame identical to the global frame, so it's all good.
|
|
Sinuna Falta
Registered User
Join date: 9 Jul 2007
Posts: 3
|
The contest is closed.
01-14-2008 17:37
the prize was awarded to NOISOK MAYO over on the SLexchage thread: http://www.slexchange.com/modules.php?name=Forums&file=viewtopic&t=32952&postdays=0&postorder=asc&start=0Lukass Lukass .. aka NOISOK MAYO..receives the entire 1,000 and my very sincere thanks.. he not only solved it.. he also provided a fix for the 2 no solution cases, and a customization to perform the same function for any one of the three axes'.. and he didn't even charge extra for the Spanish lessons.. Note: his final solution is a little bit different.. he came to my house and customized it to use different axes if necessary. I suspect that the answers above would work..and perhaps even work in all cases.. I don't know because I just don't understand the math well enough. I award two additional 250 $L prizes to Ordinal Malaprop and Hewee Zetkin for their thoughtful attention to this problem. I apologize if anyone above feels that this is not fair, please say so, or contact me in-world. Gracias a todos. Sinuna (bueno.. talvez una pequena) Falta.
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
01-14-2008 17:41
Erm, okay. His code is awful by the way, but I am not exactly in need of L$1000  Please donate it to the Arbor Foundation, or, if the methods are confusing which they probably are, give it to me and I will.
_____________________
http://ordinalmalaprop.com/forum/ - visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!
http://ordinalmalaprop.com/engine/ - An Engine Fit For My Proceeding, my Aethernet Journal
http://www.flickr.com/groups/slgriefbuild/ - Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names
|
|
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
|
01-14-2008 17:53
I appreciate the thought as well, but as I stated off the bat I really don't want money for helping here either. Use it to upload a few upside-down, inside-out animations or something. Isn't that how we feel about now? 
|
|
Sinuna Falta
Registered User
Join date: 9 Jul 2007
Posts: 3
|
perhaps
01-14-2008 19:41
From: Ordinal Malaprop Erm, okay. His code is awful by the way, but I am not exactly in need of L$1000  Please donate it to the Arbor Foundation, or, if the methods are confusing which they probably are, give it to me and I will. Awful is not (in my opinion) the correct adjective to describe something that works, correctly, in all cases. I've been hireing, asking, and rewarding on forums and in scripting groups for a month trying to find someone who could do the math and get it right. His code may not be "pretty", "elegant", "robust", "fast", "thin", "neat", or any of those other words that programers like to use while they talk about a program that doesn't actually meet the spec, but it is certainly not "awful". Thank you Sinuna Falta
|
|
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
|
01-14-2008 19:53
From: Sinuna Falta Awful is not (in my opinion) the correct adjective to describe something that works, correctly, in all cases. I've been hiring, asking, and rewarding on forums and in scripting groups for a month trying to find someone who could do the math and get it right. His code may not be "pretty", "elegant", "robust", "fast", "thin", "neat", or any of those other words that programers like to use while they talk about a program that doesn't actually meet the spec, but it is certainly not "awful".
Thank you Sinuna Falta You've been trying the wrong forums then. Next time, try posting in the Products Wanted forum down below this one. Several of the top scripters keep a look out there for jobs. A contest as you posted here would definitely be a good way to get several responses. Technically thou, this forum is strictly for people learning to script or need help with a script they are working on, not for people looking for scripts. Glad that you solved your problem thou.
_____________________
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
|
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
01-15-2008 04:06
No, it was rude to call it "awful", I should not have done so, it's just that...
Oh, never mind.
_____________________
http://ordinalmalaprop.com/forum/ - visit Ordinal's Scripting Colloquium for scripting discussion with actual working BBCode!
http://ordinalmalaprop.com/engine/ - An Engine Fit For My Proceeding, my Aethernet Journal
http://www.flickr.com/groups/slgriefbuild/ - Second Life Griefbuild Digest, pictures of horrible ad griefing and land spam, and the naming of names
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
01-15-2008 20:49
From: Ordinal Malaprop No, it was rude to call it "awful", I should not have done so, it's just that...
Oh, never mind. oh you know you want to.... =) sloppy, arcane(could be a compliment), voodoo logic, ineffecient, laggy... those are the words to break down 'awful' code... assuming it was bad, I didn't really look =)
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
|
01-16-2008 10:33
just for fun I dug up my solution it doesn't care if you're upside down, it gives compas direction based on East since lsl treats east as forward (I could update for up or down but I'm too lazy) the only slight flaw it that pointing straight up or down gets you east (which I was also too lazy to add a line for) it can be tweeaked to treat north as forward string fStrCompass8( rotation vRotDirection ){ string vStrReturn; vector vPosTest = <1.0, 0.0, 0.0> * vRotDirection; //-- use <0, 1, 0> if you build north aligned float vFltDegrees = llAtan2( vPosTest.y, vPosTest.x ) * RAD_TO_DEG; float vFltShort = llFabs( vFltDegrees ); if ( vFltShort > 22.5 && vFltShort < 157.5){ if (vFltDegrees > 0){ vStrReturn += "N"; }else{ vStrReturn += "S"; } } if (vFltShort < 67.5){ vStrReturn += "E"; }else if (vFltShort > 112.5){ vStrReturn += "W"; } return vStrReturn; }
default{ touch_start(integer total_number){ llOwnerSay( fStrCompass8( llGetRot() ) ); } }
decided to take a different approach from dissecting the rotation angles and instead rotated a pont to serve as a direction to make flattening safer and get a clean z rotation, it'd work faster if I used radians but it was easier to run degrees :  hrug::
_____________________
| | . "Cat-Like Typing Detected" | . This post may contain errors in logic, spelling, and | . grammar known to the SL populace to cause confusion | | - Please Use PHP tags when posting scripts/code, Thanks. | - Can't See PHP or URL Tags Correctly? Check Out This Link... | - 
|
|
Tazmania Trefusis
Registered User
Join date: 13 Jan 2008
Posts: 85
|
04-16-2008 09:20
Do we get to see this 'final finished' code by the way?..unless ive missed it somewhere. Just curious
Thanks
|
|
Eyerocker Picket
Imaginary Menagerie Mgr.
Join date: 18 Sep 2006
Posts: 151
|
Rotations buggered
04-16-2008 11:43
All of these scripts were written before the havok4 implimentation and I have not tested any of these for functionallity since. The rotation scripts that I currently have stop working after about 6 hours on my sims. I am wondering if (I appologise for hijacking the thread) anyone else has noticed this behavoir and is there a solution to rotation scripts breaking after a certain length of time.
|