Difference between revisions of "User:Dora Gustafson/llRotBetween alternatives"
Line 82: | Line 82: | ||
== Conclusion == | == Conclusion == | ||
Functions 2, 3 and 4 have similar performances | Functions 2, 3 and 4 have similar performances. | ||
Function 1, the built-in has the | Function 1, the built-in, has a lower performance | ||
== Scripts and functions == | |||
;Function 1, llRotBetween() | |||
: This is the built in function, see [https://wiki.secondlife.com/wiki/LlRotBetween llRotBetween] | |||
;Function 2, RotBetween() | |||
: This is the suggested [https://wiki.secondlife.com/wiki/LlRotBetween#Replacement replacement] for llRotBetween | |||
;Function 3, rotV2V() | |||
<lsl>rotation rotV2V( vector a, vector b) | |||
{ | |||
a = llVecNorm(a); | |||
b = llVecNorm(b); | |||
vector c = b; | |||
while ( llFabs(a*c) > 0.999999 ) c = llVecNorm(< llFrand( 2.0)-1.0, llFrand( 2.0)-1.0, llFrand( 2.0)-1.0 >); | |||
c = llVecNorm(a%c); | |||
return ZERO_ROTATION/llAxes2Rot( a, c, a%c)*llAxes2Rot( b, c, b%c); | |||
} | |||
</lsl> | |||
;Function 4, rotbetween() | |||
<lsl>rotation Vec2Rot( vector a) | |||
{ | |||
a = llVecNorm(a); | |||
vector c = < 0.0, 0.0, 1.0 >; | |||
if ( llFabs(a*c) > 0.999999 ) c = llVecNorm(< llFrand( 2.0)-1.0, llFrand( 2.0)-1.0, 0.0 >); | |||
vector b = llVecNorm(c%a); | |||
return llAxes2Rot( a, b, a%b); | |||
} | |||
rotation rotbetween( vector a, vector b) | |||
{ | |||
return ZERO_ROTATION/Vec2Rot(a)*Vec2Rot(b); | |||
} | |||
</lsl> | |||
{{LSLC|Library}} | {{LSLC|Library}} |
Revision as of 14:07, 23 December 2012
llRotBetween, some alternatives and considerations
Under construction
Scope
Four scripts are covered, They are
- llRotBetween( vector a, vector b); // The built in function
- RotBetween( vector a, vector b); // The replacement outlined in the wiki
- rotV2V( vector a, vector b); // The shortest replacement
- rotbetween( vector a, vector b); // Using a Vector to rotation function
Tests
First the rotation solutions were compared and they didn't compare at all. Testing rotations is a bad idea since there is no single solution, but an infinite number of solutions. All 4 functions provide different valid solutions. So the sensible thing to do is to test how the solution affects a vector:
Test with random, normalized vectors
<lsl> cycles = 0; record = []; while ( cycles++ < nLimit && llGetListLength( record) < 30) {
u = llVecNorm(< llFrand( 2.0)-1.0, llFrand( 2.0)-1.0, llFrand( 2.0)-1.0 >); v = llVecNorm(< llFrand( 2.0)-1.0, llFrand( 2.0)-1.0, llFrand( 2.0)-1.0 >); solution = rotbetween( u, v); if ( llVecDist( u*solution, v) > epsilon ) record += [cycles, u, v];
}</lsl>
Results for function 1. llRotBetween
- Errors > 1E-7 / number of test cycles
- 10/13, 10/14
- Errors > 1E-6 / number of test cycles
- 7/1000, 3/1000, 8/1000
Results for function 2. RotBetween
- Errors > 1E-7 / number of test cycles
- 10/18, 10/21, 10/27
- Errors > 1E-6 / number of test cycles
- 0/1000, 0/10000
Results for function 3. rotV2V
- Errors > 1E-7 / number of test cycles
- 10/15, 10/22, 10/14
- Errors > 1E-6 / number of test cycles
- 0/1000, 1/10000, 0/10000
Results for function 4. rotbetween
- Errors > 1E-7 / number of test cycles
- 10/16, 10/23, 10/13
- Errors > 1E-6 / number of test cycles
- 0/1000, 0/10000
Test with close to parallel and anti parallel vectors
<lsl> cycles = 0; record = []; while ( cycles++ < nLimit && llGetListLength( record) < 30) {
u = llVecNorm(< llFrand( 2.0)-1.0, llFrand( 2.0)-1.0, llFrand( 2.0)-1.0 >); v = < llFrand( 2E-3)-1E-3, llFrand( 2E-3)-1E-3, llFrand( 2E-3)-1E-3 >; if ( llFrand(1.0) < 0.5 ) v -= u; else v += u; solution = rotbetween( u, v); if ( llVecDist( u*solution, v) > epsilon ) record += [cycles, u, v];
}</lsl>
Results for function 1. llRotBetween
- Errors > 1E-3 / number of test cycles
- 10/16, 10/15, 10/27
- Errors > 1E-2 / number of test cycles
- 0/1000, 0/10000
Results for function 2. RotBetween
- Errors > 1E-3 / number of test cycles
- 10/98, 10/96, 10/109
- Errors > 1E-2 / number of test cycles
- 0/1000, 0/10000
Results for function 3. rotV2V
- Errors > 1E-3 / number of test cycles
- 10/222, 10/89, 10/99
- Errors > 1E-2 / number of test cycles
- 0/1000, 0/10000
Results for function 4. rotbetween
- Errors > 1E-3 / number of test cycles
- 10/192, 10/164, 10/75
- Errors > 1E-2 / number of test cycles
- 0/1000, 0/10000
Conclusion
Functions 2, 3 and 4 have similar performances. Function 1, the built-in, has a lower performance
Scripts and functions
- Function 1, llRotBetween()
- This is the built in function, see llRotBetween
- Function 2, RotBetween()
- This is the suggested replacement for llRotBetween
- Function 3, rotV2V()
<lsl>rotation rotV2V( vector a, vector b) {
a = llVecNorm(a); b = llVecNorm(b); vector c = b; while ( llFabs(a*c) > 0.999999 ) c = llVecNorm(< llFrand( 2.0)-1.0, llFrand( 2.0)-1.0, llFrand( 2.0)-1.0 >); c = llVecNorm(a%c); return ZERO_ROTATION/llAxes2Rot( a, c, a%c)*llAxes2Rot( b, c, b%c);
} </lsl>
- Function 4, rotbetween()
<lsl>rotation Vec2Rot( vector a) {
a = llVecNorm(a); vector c = < 0.0, 0.0, 1.0 >; if ( llFabs(a*c) > 0.999999 ) c = llVecNorm(< llFrand( 2.0)-1.0, llFrand( 2.0)-1.0, 0.0 >); vector b = llVecNorm(c%a); return llAxes2Rot( a, b, a%b);
}
rotation rotbetween( vector a, vector b) {
return ZERO_ROTATION/Vec2Rot(a)*Vec2Rot(b);
} </lsl>