Difference between revisions of "LlAngleBetween"

From Second Life Wiki
Jump to navigation Jump to search
m (I've re-arranged the math)
m
 
(8 intermediate revisions by 3 users not shown)
Line 7: Line 7:
|p2_type=rotation|p2_name=b|p2_desc=end rotation
|p2_type=rotation|p2_name=b|p2_desc=end rotation
|func_footnote
|func_footnote
|return_text=that is the angle between rotation {{LSLP|a}} and {{LSLP|b}}.
|return_text=that is the angle in radians between rotation {{LSLP|a}} and rotation {{LSLP|b}}.
|spec
|spec
|caveats
|caveats
|examples
|examples=
<source lang="lsl2">
default
{
    touch_start(integer num_detected)
    {
        rotation currentRootRotation = llGetRootRotation();
        float angle = llAngleBetween(ZERO_ROTATION, currentRootRotation);
 
        // PUBLIC_CHANNEL has the integer value 0
        llSay(PUBLIC_CHANNEL,
            "llAngleBetween(ZERO_ROTATION, " + (string)currentRootRotation + ") = " + (string)angle);
    }
}
</source>
|helpers
|helpers
|also_functions={{LSL DefineRow||[[llRotBetween]]}}
|also_functions={{LSL DefineRow||[[llRotBetween]]}}
Line 19: Line 33:
|notes
|notes
|deepnotes= ===Reference===
|deepnotes= ===Reference===
<lsl>float AngleBetween(rotation a, rotation b)//simple but turns out to not be very accurate.
<source lang="lsl2">float AngleBetween(rotation a, rotation b)//simple but turns out to not be very accurate.
{
{
     return 2.0 * llAcos((a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s)
     return 2.0 * llAcos( llFabs(a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s)
              / llSqrt((a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s)
                      / llSqrt((a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s)
                      * (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s)));
                            * (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s)));
}</lsl>
}</source>


<lsl>float AngleBetween(rotation a, rotation b)//more complex implementation but very accurate, and reasonably fast.
<source lang="lsl2">float AngleBetween(rotation a, rotation b)//more complex implementation but more accurate, and reasonably fast.
{
{
     rotation r = b / a; // calculate the rotation between the two arguments as quaternion
     rotation r = b / a; // calculate the rotation between the two arguments as quaternion
Line 33: Line 47:


     if (s2 < v2) // compare the s-component to the v-component
     if (s2 < v2) // compare the s-component to the v-component
         return 2 * llAcos(llSqrt(s2 / (s2 + v2))); // use arccos if the v-component is dominant
         return 2.0 * llAcos(llSqrt(s2 / (s2 + v2))); // use arccos if the v-component is dominant
     else if (v2)
     if (v2) // make sure the v-component is non-zero
         return 2 * llAsin(llSqrt(v2 / (s2 + v2))); // use arcsin if the s-component is dominant
         return 2.0 * llAsin(llSqrt(v2 / (s2 + v2))); // use arcsin if the s-component is dominant


     return 0; // one or both arguments are scaled too small to be meaningful, or the values are the same, so return zero
     return 0.0; // one or both arguments are scaled too small to be meaningful, or the values are the same, so return zero
}//Written by Moon Metty, Miranda Umino. Minor optimizations by Strife Onizuka</lsl>
}//Written by Moon Metty & Miranda Umino. Minor optimizations by Strife Onizuka</source>


Watch for developments on this function with {{Jira|SVC-2424}}
Watch for developments on this function with {{Jira|SVC-2424}}

Latest revision as of 22:20, 21 January 2015

Summary

Function: float llAngleBetween( rotation a, rotation b );
0.0 Forced Delay
10.0 Energy

Returns a float that is the angle in radians between rotation a and rotation b.

• rotation a start rotation
• rotation b end rotation

Examples

default
{
    touch_start(integer num_detected)
    {
        rotation currentRootRotation = llGetRootRotation();
        float angle = llAngleBetween(ZERO_ROTATION, currentRootRotation);

        // PUBLIC_CHANNEL has the integer value 0
        llSay(PUBLIC_CHANNEL,
            "llAngleBetween(ZERO_ROTATION, " + (string)currentRootRotation + ") = " + (string)angle);
    }
}

See Also

Functions

•  llRotBetween
•  llRot2Angle Similar functionality used for the Axis-Angle format

Deep Notes

Reference

float AngleBetween(rotation a, rotation b)//simple but turns out to not be very accurate.
{
    return 2.0 * llAcos( llFabs(a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s)
                      / llSqrt((a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s)
                             * (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s)));
}
float AngleBetween(rotation a, rotation b)//more complex implementation but more accurate, and reasonably fast.
{
    rotation r = b / a; // calculate the rotation between the two arguments as quaternion
    float s2 = r.s * r.s; // square of the s-element
    float v2 = r.x * r.x + r.y * r.y + r.z * r.z; // sum of the squares of the v-elements

    if (s2 < v2) // compare the s-component to the v-component
        return 2.0 * llAcos(llSqrt(s2 / (s2 + v2))); // use arccos if the v-component is dominant
    if (v2) // make sure the v-component is non-zero
        return 2.0 * llAsin(llSqrt(v2 / (s2 + v2))); // use arcsin if the s-component is dominant

    return 0.0; // one or both arguments are scaled too small to be meaningful, or the values are the same, so return zero
}//Written by Moon Metty & Miranda Umino. Minor optimizations by Strife Onizuka

Watch for developments on this function with SVC-2424

Signature

function float llAngleBetween( rotation a, rotation b );