Difference between revisions of "LlRotBetween"

From Second Life Wiki
Jump to navigation Jump to search
m
Line 5: Line 5:
|func_footnote
|func_footnote
|func_desc
|func_desc
|return_text=that is the rotation between the direction '''start''' and the direction '''end'''
|return_text=that is the shortest rotation between the direction '''start''' and the direction '''end'''
|spec='''start''' and '''end''' are directions and are relative to the origin <0.0, 0.0, 0.0>. If you have coordinates relative to a different origin, subtract that origin from the input vectors.
|spec='''start''' and '''end''' are directions and are relative to the origin <0.0, 0.0, 0.0>. If you have coordinates relative to a different origin, subtract that origin from the input vectors.
|caveats=*<code>start * llRotBetween(start, end) == end</code> is only true if '''start''' and '''end''' have the same magnitude and neither have a magnitude of zero (see [[#Notes]] for a workaround).
|caveats=*<code>start * llRotBetween(start, end) == end</code> is only true if '''start''' and '''end''' have the same magnitude and neither have a magnitude of zero (see [[#Useful Snippets]] for a workaround).
**This of course is ignoring floating point precision errors.
**This of course is ignoring floating point precision errors.
* Rotations are from -PI to +PI around each axis.
* Rotations are from -PI to +PI around each axis.
Line 23: Line 23:
|also_events
|also_events
|also_articles
|also_articles
|notes=
|helpers=This function adjusts the magnitude of the quaternion so <code>start * llRotBetween(start, end) == end</code> is true as long as neither have a magnitude of zero. They don't have to have the same magnitude.  
This function adjusts the magnitude of the quaternion so <code>start * llRotBetween(start, end) == end</code> is true as long as neither have a magnitude of zero. They don't have to have the same magnitude.  
<lsl>rotation RotBetween(vector start, vector end) //adjusts quaternion magnitude so (start * return == end)  
<lsl>rotation RotBetween(vector start, vector end) //adjusts quaternion magnitude so (start * return == end)  
{//Authors note: I have never had a use for this but it's good to know how to do it if I did.
{//Authors note: I have never had a use for this but it's good to know how to do it if I did.
Line 38: Line 37:
     return rot;
     return rot;
}//Strife Onizuka</lsl>
}//Strife Onizuka</lsl>
|notes=
Vectors that are near opposite each other in direction may lead to erroneous results.  
Vectors that are near opposite each other in direction may lead to erroneous results.  
<lsl>
<lsl>
Line 45: Line 45:
// Provides a result of <1.00000, 0.00000, 0.00000, 0.00000>.
// Provides a result of <1.00000, 0.00000, 0.00000, 0.00000>.
</lsl>
</lsl>
|deprecated
|location={{SourceLink|indra/llmath/llquaternion.cpp|line=429}}
|deepnotes=<lsl>//Loosely based on SL source code
rotation llRotBetween(vector start, vector end) {
    vector v1 = llVecNorm(start);
    vector v2 = llVecNorm(end);
    float dot = v1 * v2;
    vector axis = v1 % v2;
    if (dot < -0.9999999) {
        // 180 degrees or there abouts
        vector ortho_axis = llVecNorm(<1.f, 0.f, 0.f> - (sn * (sn.x / (sn * sn))));
        if (ortho_axis)
            return < ortho_axis.x, ortho_axis.y, ortho_axis.z, 0.f>;
        return <0.0, 0.0, 1.0, 0.0>;
    }
    else if(dot > 0.9999999) {
        //parallel
        return ZERO_ROTATION;
    }
    dot = dot + 1.0;
    float m = 1 / llSqrt((axis * axis) + (dot * dot));
    return <axis.x * m, axis.y * m, axis.z * m, dot * m>;
}</lsl>
|cat1=Math/3D
|cat1=Math/3D
|cat2=Rotation
|cat2=Rotation

Revision as of 04:49, 21 June 2009

Summary

Function: rotation llRotBetween( vector start, vector end );
0.0 Forced Delay
10.0 Energy

Returns a rotation that is the shortest rotation between the direction start and the direction end

• vector start
• vector end

Specification

start and end are directions and are relative to the origin <0.0, 0.0, 0.0>. If you have coordinates relative to a different origin, subtract that origin from the input vectors.

Caveats

  • start * llRotBetween(start, end) == end is only true if start and end have the same magnitude and neither have a magnitude of zero (see #Useful Snippets for a workaround).
    • This of course is ignoring floating point precision errors.
  • Rotations are from -PI to +PI around each axis.

Examples

<lsl>llRotBetween(<1.0, 0.0, 0.0>, <0.0, -1.0, 0.0>) // will return <0.00000, 0.00000, -0.70711, 0.70711> (which represents -45 degrees on the z axis)

llRotBetween(<0.0, 0.0, 0.0>, <0.0, -1.0, 0.0>) // will return <0.00000, 0.00000, 0.00000, 1.00000> (which represents a zero angle on all axis)

// because <0.0, 0.0, 0.0> does not convey a direction.</lsl>

Useful Snippets

This function adjusts the magnitude of the quaternion so start * llRotBetween(start, end) == end is true as long as neither have a magnitude of zero. They don't have to have the same magnitude. <lsl>rotation RotBetween(vector start, vector end) //adjusts quaternion magnitude so (start * return == end) {//Authors note: I have never had a use for this but it's good to know how to do it if I did.

   rotation rot = llRotBetween(start, end);
   if(start)
   {
       if(end)
       {
           float d = llSqrt(llVecMag(end) / llVecMag(start));
           return <rot.x * d, rot.y * d, rot.z * d, rot.s * d>;
       }
   }
   return rot;

}//Strife Onizuka</lsl>

Notes

Vectors that are near opposite each other in direction may lead to erroneous results. <lsl> // First Vector is due north second vector is ALMOST due south. rotation lRotation = llRotBetween( <0., 1., 0.>, <-0.001, -.1, 0.> ); llSay(0, lRotation ); // Provides a result of <1.00000, 0.00000, 0.00000, 0.00000>. </lsl>

See Also

Functions

•  llAngleBetween

Deep Notes

<lsl>//Loosely based on SL source code rotation llRotBetween(vector start, vector end) {

   vector v1 = llVecNorm(start);
   vector v2 = llVecNorm(end);
   float dot = v1 * v2;
   vector axis = v1 % v2;
   if (dot < -0.9999999) {
       // 180 degrees or there abouts
       vector ortho_axis = llVecNorm(<1.f, 0.f, 0.f> - (sn * (sn.x / (sn * sn))));
       if (ortho_axis)
           return < ortho_axis.x, ortho_axis.y, ortho_axis.z, 0.f>;
       return <0.0, 0.0, 1.0, 0.0>;
   }
   else if(dot > 0.9999999) {
       //parallel
       return ZERO_ROTATION;
   }
   dot = dot + 1.0;
   float m = 1 / llSqrt((axis * axis) + (dot * dot));
   return <axis.x * m, axis.y * m, axis.z * m, dot * m>;

}</lsl>

Source

Signature

function rotation llRotBetween( vector start, vector end );