Difference between revisions of "User:Dora Gustafson/llRotBetween alternatives"

From Second Life Wiki
Jump to navigation Jump to search
Line 26: Line 26:
     if ( llVecDist( u*solution, v) > epsilon ) record += [cycles, u, v];
     if ( llVecDist( u*solution, v) > epsilon ) record += [cycles, u, v];
}</lsl>
}</lsl>
====Results for function 1. llRotBetween====
<table style="width: 800px;" border="1" cellpadding="2"
;Errors > 1E-7 / number of test cycles
cellspacing="2">
: 10/13, 10/14
    <tr>
;Errors > 1E-6 / number of test cycles
      <th style="text-align: center;" colspan="1"
: 7/1000, 3/1000, 8/1000
rowspan="2">Errors / test cycles</th>
====Results for function 2. RotBetween====
      <th style="text-align: center;">Function 1</th>
;Errors > 1E-7 / number of test cycles
      <th style="text-align: center;">Function 2</th>
: 10/18, 10/21, 10/27
      <th style="text-align: center;">Function 3</th>
;Errors > 1E-6 / number of test cycles
      <th style="text-align: center;">Function 4</th>
: 0/1000, 0/10000
    </tr>
====Results for function 3. rotV2V====
    <tr>
;Errors > 1E-7 / number of test cycles
      <th style="text-align: center;">llRotBetween</th>
: 10/15, 10/22, 10/14
      <th style="text-align: center;">RotBetween</th>
;Errors > 1E-6 / number of test cycles
      <th style="text-align: center;">rotV2V</th>
: 0/1000, 1/10000, 0/10000
      <th style="text-align: center;">rotbetween</th>
====Results for function 4. rotbetween====
    </tr>
;Errors > 1E-7 / number of test cycles
    <tr>
: 10/16, 10/23, 10/13
      <th style="text-align: center;" colspan="1"
;Errors > 1E-6 / number of test cycles
rowspan="3">abs error &gt; 1e-7</th>
: 0/1000, 0/10000
      <td style="text-align: right;"> 10 / 13</td>
      <td style="text-align: right;"> 10 / 18</td>
      <td style="text-align: right;"> 10 / 15</td>
      <td style="text-align: right;"> 10 / 16</td>
    </tr>
    <tr>
      <td style="text-align: right;"> 10 / 14</td>
      <td style="text-align: right;"> 10 / 21</td>
      <td style="text-align: right;"> 10 / 22</td>
      <td style="text-align: right;"> 10 / 23</td>
    </tr>
    <tr>
      <td style="text-align: right;"></td>
      <td style="text-align: right;"> 10 / 27</td>
      <td style="text-align: right;">10 / 14</td>
      <td style="text-align: right;"> 10 / 13</td>
    </tr>
    <tr>
      <th style="text-align: center;" colspan="1"
rowspan="3">abs error &gt; 1e-6</th>
      <td style="text-align: right;"> 7 / 1000</td>
      <td style="text-align: right;"> 0 / 1000</td>
      <td style="text-align: right;"> 0 / 1000</td>
      <td style="text-align: right;"> 0 / 1000</td>
    </tr>
    <tr>
      <td style="text-align: right;"> 3 / 1000</td>
      <td style="text-align: right;"> 0 / 10000</td>
      <td style="text-align: right;"> 1 / 10000</td>
      <td style="text-align: right;"> 0 / 10000</td>
    </tr>
    <tr>
      <td style="text-align: right;"> 8 / 1000</td>
      <td style="text-align: right;"></td>
      <td style="text-align: right;"> 0 / 10000</td>
      <td style="text-align: right;"></td>
    </tr>
</table>


== Test with close to parallel and anti parallel vectors ==
== Test with close to parallel and anti parallel vectors ==
Line 60: Line 97:
     if ( llVecDist( u*solution, v) > epsilon ) record += [cycles, u, v];
     if ( llVecDist( u*solution, v) > epsilon ) record += [cycles, u, v];
}</lsl>
}</lsl>
====Results for function 1. llRotBetween====
<table style="width: 800px;" border="1" cellpadding="2"
;Errors > 1E-3 / number of test cycles
cellspacing="2">
: 10/16, 10/15, 10/27
    <tr>
;Errors > 1E-2 / number of test cycles
      <th style="text-align: center;" colspan="1"
: 0/1000, 0/10000
rowspan="2">Errors / test cycles</th>
====Results for function 2. RotBetween====
      <th style="text-align: center;">Function 1</th>
;Errors > 1E-3 / number of test cycles
      <th style="text-align: center;">Function 2</th>
: 10/98, 10/96, 10/109
      <th style="text-align: center;">Function 3</th>
;Errors > 1E-2 / number of test cycles
      <th style="text-align: center;">Function 4</th>
: 0/1000, 0/10000
    </tr>
====Results for function 3. rotV2V====
    <tr>
;Errors > 1E-3 / number of test cycles
      <th style="text-align: center;">llRotBetween</th>
: 10/222, 10/89, 10/99
      <th style="text-align: center;">RotBetween</th>
;Errors > 1E-2 / number of test cycles
      <th style="text-align: center;">rotV2V</th>
: 0/1000, 0/10000
      <th style="text-align: center;">rotbetween</th>
====Results for function 4. rotbetween====
    </tr>
;Errors > 1E-3 / number of test cycles
    <tr>
: 10/192, 10/164, 10/75
      <th style="text-align: center;" colspan="1"
;Errors > 1E-2 / number of test cycles
rowspan="3">abs error &gt; 1e-3</th>
: 0/1000, 0/10000
      <td style="text-align: right;"> 10 / 16</td>
      <td style="text-align: right;"> 10 / 98</td>
      <td style="text-align: right;"> 10 / 222</td>
      <td style="text-align: right;"> 10 / 192</td>
    </tr>
    <tr>
      <td style="text-align: right;"> 10 / 15</td>
      <td style="text-align: right;"> 10 / 96</td>
      <td style="text-align: right;"> 10 / 89</td>
      <td style="text-align: right;"> 10 / 164</td>
    </tr>
    <tr>
      <td style="text-align: right;"> 10 / 27</td>
      <td style="text-align: right;"> 10 / 109</td>
      <td style="text-align: right;">10 / 99</td>
      <td style="text-align: right;"> 10 / 75</td>
    </tr>
    <tr>
      <th style="text-align: center;" colspan="1"
rowspan="2">abs error &gt; 1e-2</th>
      <td style="text-align: right;"> 0 / 1000</td>
      <td style="text-align: right;"> 0 / 1000</td>
      <td style="text-align: right;"> 0 / 1000</td>
      <td style="text-align: right;"> 0 / 1000</td>
    </tr>
    <tr>
      <td style="text-align: right;"> 0 / 10000</td>
      <td style="text-align: right;"> 0 / 10000</td>
      <td style="text-align: right;"> 0 / 10000</td>
      <td style="text-align: right;"> 0 / 10000</td>
    </tr>
</table>


== Conclusion ==
== Conclusion ==

Revision as of 05:49, 26 December 2012

llRotBetween, some alternatives and considerations

Scope

Four functions are covered, They are

  1. llRotBetween( vector a, vector b); // The built in function
  2. RotBetween( vector a, vector b); // The replacement outlined in the wiki
  3. rotV2V( vector a, vector b); // The shortest replacement
  4. 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 are no single solutions, but infinite numbers of solutions. All 4 functions provide valid, but different 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>

Errors / test cycles Function 1 Function 2 Function 3 Function 4
llRotBetween RotBetween rotV2V rotbetween
abs error > 1e-7 10 / 13 10 / 18 10 / 15 10 / 16
10 / 14 10 / 21 10 / 22 10 / 23
10 / 27 10 / 14 10 / 13
abs error > 1e-6 7 / 1000 0 / 1000 0 / 1000 0 / 1000
3 / 1000 0 / 10000 1 / 10000 0 / 10000
8 / 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>

Errors / test cycles Function 1 Function 2 Function 3 Function 4
llRotBetween RotBetween rotV2V rotbetween
abs error > 1e-3 10 / 16 10 / 98 10 / 222 10 / 192
10 / 15 10 / 96 10 / 89 10 / 164
10 / 27 10 / 109 10 / 99 10 / 75
abs error > 1e-2 0 / 1000 0 / 1000 0 / 1000 0 / 1000
0 / 10000 0 / 10000 0 / 10000 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>