Difference between revisions of "Geometric"

From Second Life Wiki
Jump to navigation Jump to search
m (language tags to <source>)
 
(32 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{LSL Header}}
{{LSL Header}}
{{RightToc|clear:right;}}


'''Please vote for:
'''Please vote for:
https://jira.secondlife.com/browse/WEB-235'''
https://jira.secondlife.com/browse/WEB-235'''
''So that I can expand each function into deeper detail without the page starting to fail in readability.'' --[[User:Nexii Malthus|Nexii Malthus]] 23:05, 24 October 2008 (UTC)
''So that I can expand each function into deeper detail without the page starting to fail in readability.'' --[[User:Nexii Malthus|Nexii Malthus]] 23:05, 24 October 2008 (UTC)
:Break it up so each major section has its own page... thats why hypertext was invented. -[[User:Overbrain Unplugged|Overbrain Unplugged]] 13:36, 10 October 2010 (UTC)


== Geometric Library ==
== Geometric Library ==


=== Line Functions ===
__Toc__
 
=== <div style="font-size: 120%;">[[#Geometric Library|Line Functions]]</div> ===


<!--############# LINE NEAREST POINT #############-->
<!--############# LINE NEAREST POINT #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Line Nearest Point
==== Line and Point, Vector ====
|-
|-
|
|
Calculates the vector from a point to the closest point on a line
Calculates the vector from a point ''''to'''' the closest point on a line


<lsl>
<source lang="lsl2">
vector gLXdV(vector O,vector D,vector A){
vector gLXdV(vector O,vector D,vector A){
     return (O-A)-((O-A)*D)*D;}
     return (O-A)-((O-A)*D)*D;}
</lsl>
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 42: Line 44:
| Returns origin of closest point on Line to Point
| Returns origin of closest point on Line to Point
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
Line 49: Line 53:
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Line Nearest Point, Distance
==== Line and Point, Distance ====
|-
|-
|
|
Calculates distance of this vector, but faster on it's own
Calculates distance of line to point, same as measuring magnitude of Line and Point Vector, but faster on it's own
<lsl>
<source lang="lsl2">
float gLXdZ(vector O,vector D,vector A){
float gLXdZ(vector O,vector D,vector A){
     vector k = ( A - O ) % D;
     vector k = ( A - O ) % D;
     return llSqrt( k * k );}
     return llSqrt( k * k );}
</lsl>
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 67: Line 71:
|-
|-
| vector D
| vector D
| Direction of Line
| Direction of Line (unit vector)
|-
|-
| vector A
| vector A
Line 78: Line 82:
| Returns numerical distance from Line to Point
| Returns numerical distance from Line to Point
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
Line 85: Line 91:
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Line Nearest Point, Nearest Point
 
==== Line Nearest Point, Nearest Point ====
|-
|-
|
|
Returns nearest point on line to given point
Returns nearest point on line to given point
<lsl>
<source lang="lsl2">
vector gLXnX(vector O,vector D,vector A){
vector gLXnX(vector O,vector D,vector A){
     return gLXdV(O,D,A) + A;}
     return gLXdV(O,D,A) + A;}
</lsl>
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 117: Line 124:
|style="background-color: #eed0d0" colspan="2"| function vector gLXdV(vector O,vector D,vector A)
|style="background-color: #eed0d0" colspan="2"| function vector gLXdV(vector O,vector D,vector A)
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
Line 124: Line 133:
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Line and Line, Vector
==== Line and Line, Vector ====
|-
|-
|
|
Shortest vector of two lines
Shortest vector of two lines
<lsl>
<source lang="lsl2">
vector gLLdV(vector O1,vector D1,vector O2,vector D2){
vector gLLdV(vector O1,vector D1,vector O2,vector D2){
     vector A = O2 - O1; vector B = D1 % D2;
     vector A = O2 - O1; vector B = D1 % D2;
     return B*( (A*B)/(B*B) );}
     return B*( (A*B)/(B*B) );}
</lsl>
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 156: Line 165:
| Returns shortest vector between the two lines
| Returns shortest vector between the two lines
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
Line 163: Line 174:
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Line and Line, Distance
==== Line and Line, Distance ====
|-
|-
|
|
Returns the distance between two lines
Returns the distance between two lines
<lsl>
<source lang="lsl2">
float gLLdZ(vector O1,vector D1,vector O2,vector D2){
float gLLdZ(vector O1,vector D1,vector O2,vector D2){
     vector A = D1%D2;float B = llVecMag(A);A = <A.x/B,A.y/B,A.z/B>;
     vector A = D1%D2;float B = llVecMag(A);A = <A.x/B,A.y/B,A.z/B>;
     return (O2-O1) * A;}
     return (O2-O1) * A;}
</lsl>
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 195: Line 206:
| Returns numerical distance between the two lines
| Returns numerical distance between the two lines
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
Line 202: Line 215:
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Line and Line, Nearest point
==== Line and Line, Nearest point ====
|-
|-
|
|


Closest point of two lines
Closest point of two lines
<lsl>
<source lang="lsl2">
vector gLLnX(vector O1,vector D1,vector O2,vector D2){
vector gLLnX(vector O1,vector D1,vector O2,vector D2){
     vector nO1 = < O1*D1, O1*D2, 0>;
     vector nO1 = < O1*D1, O1*D2, 0>;
Line 219: Line 232:
      
      
     return O1 + D1*t;}
     return O1 + D1*t;}
</lsl>
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 243: Line 256:
| Returns closest point between the two lines
| Returns closest point between the two lines
|}
|}
<div style="float:left;font-size: 80%;">
'''2D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
Line 250: Line 265:
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Line and Line, intersection point
==== Line and Line, intersection point ====
|-
|-
|
|
Computes intersection point of two lines, if there is any, else <-1,-1,-1> if none.
Computes intersection point of two lines, if there is any, else <-1,-1,-1> if none.
<lsl>
<source lang="lsl2">
vector gLLxX( vector A, vector B, vector C, vector D ){
vector gLLxX( vector A, vector B, vector C, vector D ){
     vector V = <-1,-1,-1>;
     vector b = B-A; vector d = D-C;
    if ( A == B || C == D ) return V;
     float dotperp = b.x*d.y - b.y*d.x;
    B -= A; C -= A; D -= A;
     if (dotperp == 0) return <-1,-1,-1>;
     float distAB = llSqrt( B.x*B.x + B.y*B.y );
     vector c = C-A;
     float c = B.x / distAB;float s = B.y / distAB;
     float t = (c.x*d.y - c.y*d.x) / dotperp;
     float t = C.x * c + C.y * s;
     return <A.x + t*b.x, A.y + t*b.y, 0>;}
    C.y = C.y * c - C.x * s; C.x = t;
</source>
     t = D.x * c + D.y * s;
    D.y = D.y * c - D.x * s; D.y = t;
    if( C.y == D.y ) return V;
    t = D.x + ( C.x - D.x ) * D.y / ( D.y - C.y );
     return <A.x + t*c, A.y + t*s, A.y>;}
</lsl>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 292: Line 301:
| The intersection point of the two lines, else <-1,-1,-1> if none
| The intersection point of the two lines, else <-1,-1,-1> if none
|}
|}
<div style="float:left;font-size: 80%;">
'''2D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
Line 299: Line 310:
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Line and Line, two nearest points along both lines
 
==== Line and Line, two nearest points of lines ====
|-
|-
|
|
Two closest points of two lines on each line
Two closest points of two lines on each line
<lsl>
<source lang="lsl2">
vector X1;vector X2;
vector X1;vector X2;
gLLnnXX(vector O1,vector D1,vector O2,vector D2){
gLLnnXX(vector O1,vector D1,vector O2,vector D2){
Line 317: Line 329:
     X1 = O1 + D1*t;
     X1 = O1 + D1*t;
     X2 = X1 + nD1%nD2;}
     X2 = X1 + nD1%nD2;}
</lsl>
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 350: Line 362:
|style="background-color: #eed0d0" colspan="2"| global vector X2
|style="background-color: #eed0d0" colspan="2"| global vector X2
|}
|}
<div style="float:left;font-size: 80%;">
'''2D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


<!--############# LINE AND LINE, TWO NEAREST POINTS, VECTOR AND DISTANCE #############-->
<!--############# LINE AND LINE, NEAREST LINE #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Line and Line, two nearest points with vector and distance
 
==== Line and Line, nearest line ====
|-
|-
|
|
Computes two closest points of two lines, vector and distance
Input two lines, the function will return a list containing two vectors responding to the line nearest between them. As well as two floats corresponding to the scalar value on the two line of where the line has an end located at.
<lsl>
<source lang="lsl2">
vector X1;vector X2;vector V1;float Z1;
list gLLnL( vector v0, vector v1, vector v2, vector v3 ) {
gLLnnXXVZ(vector O1,vector D1,vector O2,vector D2){
     float Eps = 0.000001; vector vx; vector vy; vector va; vector vb; vector vc;
     vector nO1 = < O1*D1, O1*D2, 0>;
    float x; float y; float d0; float d1; float d2; float d3; float d4;
     vector nO2 = < O2*D1, O2*D2, 0>;
    va = v0-v2; vb = v3-v2; if(llVecMag(vb)<Eps) return [];
     vector nD1 = < D1*D1, O1*D2, 0>;
     vc = v1-v0; if(llVecMag(vc)<Eps) return [];
    vector nD2 = < O2*D1, O2*D2, 0>;
     d0 = va*vb; d1 = vb*vc; d2 = va*vc; d3 = vb*vb; d4 = vc*vc;
   
     float den = d4*d3-d1*d1; if( llFabs(den) < Eps ) return [];
     float t = ( nD2.x*nD1.y - nD1.x*nD2.y );
     float num = d0*d1-d2*d3; x = num/den; y = (d0+d1*x)/d3;
      
     vx = v0+vc*x; vy = v2+vb*y; return [vx,vy,x,y]; }
    t = ( nD2.y*(nO1.x-nO2.x) - nD2.x*(nO1.y-nO2.y) ) / t;
</source>
      
    X1 = O1 + D1*t;
    X2 = X1 + CP(nD1,nD2);
    V1 = nD1%nD2;
    Z1 = llVecMag(V1);}
</lsl>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 383: Line 392:
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| vector O1
| vector v0
| Origin of Line 1
| Point on Line 1
|-
|-
| vector D1
| vector v1
| Direction of Line 1
| Point on Line 1
|-
|-
| vector O2
| vector v2
| Origin of Line 2
| Point on Line 2
|-
|-
| vector D2
| vector v3
| Direction of Line 2
| Point on Line 2
|-
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| vector X1
| [vx]
| Closest point on line 1 to line 2
| Nearest point on Line 1 to Line 2
|-
| vector X2
| Closest point on line 2 to line 1
|-
| vector V1
| Direction vector of line 1 to line 2
|-
| float Z1
| Numerical distance of line 1 to line 2
|-
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
| [vy]
| Nearest point on Line 2 to Line 1
|-
|-
|style="background-color: #eed0d0" colspan="2"| global vector X1
| [x]
| Scalar value representing location of vx on line 1 (range [v0,v1])
|-
|-
|style="background-color: #eed0d0" colspan="2"| global vector X2
| [y]
|-
| Scalar value representing location of vy on line 2 (range [v2,v3])
|style="background-color: #eed0d0" colspan="2"| global vector V1
|-
|style="background-color: #eed0d0" colspan="2"| global float Z1
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


=== Plane Functions ===
<!--############# LINE AND LINE SEGMENTS, NEAREST LINE #############-->
 
<!--############# PLANE AND POINT, DISTANCE #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Plane and Point, Distance
 
==== Line and Line Segments, nearest line segment ====
|-
|-
|
|
Finds distance of a point from a plane
Input two line segments, the function will return a list containing two vectors responding to the line segment nearest between them. As well as two floats corresponding to the scalar value on the two line segments of where the line segment has an end located at.
<lsl>
<source lang="lsl2">
float gPXdZ(vector Pn,float Pd,vector A){
list gLSLSnLS( vector v0, vector v1, vector v2, vector v3 ) {
     return A * Pn + Pd;}
     float Eps = 0.000001; vector vx; vector vy; vector va; vector vb; vector vc;
</lsl>
    float x; float y; float d0; float d1; float d2; float d3; float d4;
 
    va = v0-v2; vb = v3-v2; if(llVecMag(vb)<Eps) return [];
    vc = v1-v0; if(llVecMag(vc)<Eps) return [];
    if( llFabs(vc.x + vc.y + vc.z) < Eps ) return [];
    d0 = va*vb; d1 = vb*vc; d2 = va*vc; d3 = vb*vb; d4 = vc*vc;
    float den = d4*d3-d1*d1; if( llFabs(den) < Eps ) return [];
    float num = d0*d1-d2*d3; x = num/den; y = (d0+d1*x)/d3;
    if(x<0)x=0; else if(x>1)x=1; if(y<0)y=0; else if(y>1)y=1;
    vx = v0+vc*x; vy = v2+vb*y; return [vx,vy,x,y]; }
</source>
 
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| vector Pn
| vector v0
| Normal of Plane
| Start of Line Segment 1
|-
| vector v1
| End of Line Segment 1
|-
|-
| float Pd
| vector v2
| Distance of Plane
| Start of Line Segment 2
|-
|-
| vector A
| vector v3
| Origin of Point
| End of Line Segment 2
|-
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| return float gPXdZ
| [vx]
| Returns Distance between plane and point
| Nearest point on Line Segment 1 to Line Segment 2
|-
| [vy]
| Nearest point on Line Segment 2 to Line Segment 1
|-
| [x]
| Scalar value representing location of vx on Line Segment 1 (range [v0,v1])
|-
| [y]
| Scalar value representing location of vy on Line Segment 2 (range [v2,v3])
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


<!--############# PLANE AND POINT, VECTOR #############-->
<!--############# LINE AND LINE, TWO NEAREST POINTS, VECTOR AND DISTANCE #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Plane and Point, Vector
 
==== Line and Line, two nearest points with vector and distance ====
|-
|-
|
|
Finds vector that points from point to nearest on plane
Computes two closest points of two lines, vector and distance
<lsl>
<source lang="lsl2">
vector gPXdV(vector Pn,float Pd,vector A){
vector X1;vector X2;vector V1;float Z1;
     return -(Pn * A + Pd)*Pn;}
gLLnnXXVZ(vector O1,vector D1,vector O2,vector D2){
</lsl>
     vector nO1 = < O1*D1, O1*D2, 0>;
 
    vector nO2 = < O2*D1, O2*D2, 0>;
    vector nD1 = < D1*D1, O1*D2, 0>;
    vector nD2 = < O2*D1, O2*D2, 0>;
   
    float t = ( nD2.x*nD1.y - nD1.x*nD2.y );
   
    t = ( nD2.y*(nO1.x-nO2.x) - nD2.x*(nO1.y-nO2.y) ) / t;
   
    X1 = O1 + D1*t;
    X2 = X1 + CP(nD1,nD2);
    V1 = nD1%nD2;
    Z1 = llVecMag(V1);}
</source>
 
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| vector Pn
| vector O1
| Normal of Plane
| Origin of Line 1
|-
|-
| float Pd
| vector D1
| Distance of Plane
| Direction of Line 1
|-
|-
| vector A
| vector O2
| Origin of Point
| Origin of Line 2
|-
|-
!style="background-color: #d0d0ee" | Output
| vector D2
| Direction of Line 2
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| return vector gPXdV
| vector X1
| Returns vector from point to closest point on plane
| Closest point on line 1 to line 2
|-
| vector X2
| Closest point on line 2 to line 1
|-
| vector V1
| Direction vector of line 1 to line 2
|-
| float Z1
| Numerical distance of line 1 to line 2
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
|-
|style="background-color: #eed0d0" colspan="2"| global vector X1
|-
|style="background-color: #eed0d0" colspan="2"| global vector X2
|-
|style="background-color: #eed0d0" colspan="2"| global vector V1
|-
|style="background-color: #eed0d0" colspan="2"| global float Z1
|}
|}
<div style="float:left;font-size: 80%;">
'''2D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


<!--############# PLANE AND POINT, NEAREST POINT #############-->
<!--############# Line and Point, Direction #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Plane and Point, Nearest point
==== Line and Point, Direction ====
|-
|-
|
|
Finds closest point on plane given point
Works out where point (X) is relative to the line of the segment (L0, L1).
<lsl>
<source lang="lsl2">
vector gPXnX(vector Pn,float Pd,vector A){
float gLSPdir( vector L0, vector L1, vector X ){
     return A - (Pn * A + Pd) * Pn;}
     return (L1.x - L0.x)*(X.y - L0.y) - (X.x - L0.x)*(L1.y - L0.y);
</lsl>
}
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 512: Line 574:
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| vector Pn
| vector L0, vector L1
| Normal of Plane
| Start and End of line segment
|-
|-
| float Pd
| vector X
| Distance of Plane
|-
| vector A
| Origin of Point
| Origin of Point
|-
|-
Line 524: Line 583:
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| return vector gPXnX
| float isLeft( vector L0, vector L1, vector X )
| Returns vector of a point from closest of point to plane
| Returns float, >0 is Left, 0 on Line, <0 is Right, according to line angle
|}
|}
<div style="float:left;font-size: 80%;">
'''2D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
Copyright 2001, softSurfer (www.softsurfer.com) (Must accept License #2), LSL-Port By Nexii Malthus</div>
|}
|}


<!--############# PLANE AND RAY, INTERSECTION DISTANCE #############-->
=== <div style="font-size: 120%;">[[#Geometric Library|Plane Functions]]</div> ===
 
<!--############# PLANE AND POINT, DISTANCE #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Plane and Ray, Intersection Distance
==== Plane and Point, Distance ====
|-
|-
|
|
Finds distance to intersection of plane along ray
Finds distance of a point from a plane
<lsl>
<source lang="lsl2">
float gPRxZ(vector Pn,float Pd,vector O,vector D){
float gPXdZ(vector Pn,float Pd,vector A){
     return -((Pn*O+Pd)/(Pn*D));}
     return A * Pn + Pd;}
</lsl>
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 548: Line 611:
|-
|-
| vector Pn
| vector Pn
| Normal of Plane
| Normal of Plane (unit vector)
|-
|-
| float Pd
| float Pd
| Distance of Plane
| Distance of Plane
|-
|-
| vector O
| vector A
| Origin of Ray
| Origin of Point
|-
| vector D
| Direction of Ray
|-
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| return float gPRxZ
| return float gPXdZ
| Returns float distance of intersection between ray and plane
| Returns Distance between plane and point
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


<!--############# PLANE AND RAY, VECTOR #############-->
<!--############# PLANE AND POINT, VECTOR #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Plane and Ray, Vector
==== Plane and Point, Vector ====
|-
|-
|
|
Finds distance vector along a ray to a plane
Finds vector that points from point to nearest on plane
<lsl>
<source lang="lsl2">
vector gPRdV(vector Pn,float Pd,vector O,vector D){
vector gPXdV(vector Pn,float Pd,vector A){
     return D * gPRxZ(Pn,Pd,O,D);}
     return -(Pn * A + Pd)*Pn;}
</lsl>
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 586: Line 648:
|-
|-
| vector Pn
| vector Pn
| Normal of Plane
| Normal of Plane (unit vector)
|-
|-
| float Pd
| float Pd
| Distance of Plane
| Distance of Plane
|-
|-
| vector O
| vector A
| Origin of Ray
| Origin of Point
|-
| vector D
| Direction of Ray
|-
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| return vector gPRdV
| return vector gPXdV
| Returns vector along a ray to a plane
| Returns vector from point to closest point on plane
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
|-
|style="background-color: #eed0d0" colspan="2"| function float gPRxZ(vector Pn,float Pd,vector O,vector D)
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


<!--############# PLANE AND RAY, INTERSECTION POINT #############-->
<!--############# PLANE AND POINT, NEAREST POINT #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Plane and Ray, Intersection Point
==== Plane and Point, Nearest point ====
|-
|-
|
|
Finds intersection point along a ray to a plane
Finds closest point on plane given point
<lsl>
<source lang="lsl2">
vector gPRxX(vector Pn,float Pd,vector O,vector D){
vector gPXnX(vector Pn,float Pd,vector A){
     return O + gPRdV(Pn,Pd,O,D);}
     return A - (Pn * A + Pd) * Pn;}
</lsl>
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 628: Line 685:
|-
|-
| vector Pn
| vector Pn
| Normal of Plane
| Normal of Plane (unit vector)
|-
|-
| float Pd
| float Pd
| Distance of Plane
| Distance of Plane
|-
|-
| vector O
| vector A
| Origin of Ray
| Origin of Point
|-
| vector D
| Direction of Ray
|-
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| return vector gPRxX
| return vector gPXnX
| Returns vector point of intersection between ray and plane
| Returns vector of a point from closest of point to plane
|-
|}
!style="background-color: #eed0d0" colspan="2"| Requirement
<div style="float:left;font-size: 80%;">
|-
'''3D'''</div>
|style="background-color: #eed0d0" colspan="2"| function vector gPRdV(vector Pn,float Pd,vector O,vector D)
|}
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


<!--############# PLANE AND LINE, INTERSECTION POINT #############-->
<!--############# PLANE AND RAY, INTERSECTION DISTANCE #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Plane and Line, Intersection Point
==== Plane and Ray, Intersection Distance ====
|-
|-
|
|
Finds interesection point of a line and a plane
Finds distance to intersection of plane along ray
<lsl>
<source lang="lsl2">
vector gPLxX(vector Pn,float Pd,vector O,vector D){
float gPRxZ(vector Pn,float Pd,vector O,vector D){
     return O -( (Pn*D)/(Pn*O+Pd) )*D;}
     return -((Pn*O+Pd)/(Pn*D));}
</lsl>
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 670: Line 722:
|-
|-
| vector Pn
| vector Pn
| Normal of Plane
| Normal of Plane (unit vector)
|-
|-
| float Pd
| float Pd
Line 676: Line 728:
|-
|-
| vector O
| vector O
| Origin of Line
| Origin of Ray
|-
|-
| vector D
| vector D
| Direction of Line
| Direction of Ray
|-
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| return vector gPLxX
| return float gPRxZ
| Returns vector point of intersection between line and plane
| Returns float distance of intersection between ray and plane
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


<!--############# PLANE AND PLANE, INTERSECTION LINE #############-->
<!--############# PLANE AND RAY, VECTOR #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Plane and Plane, Intersection Line
==== Plane and Ray, Vector ====
|-
|-
|
|
Finds line of intersection of two planes
Finds distance vector along a ray to a plane
<lsl>
<source lang="lsl2">
vector oO;vector oD;
vector gPRdV(vector Pn,float Pd,vector O,vector D){
 
     return D * gPRxZ(Pn,Pd,O,D);}
gPPxL(vector Pn,float Pd,vector Qn,float Qd){
</source>
     oD = (Pn%Qn)/llVecMag(Pn%Qn);
    vector Cross = (Pn%Qn)%Pn;
    vector Bleh = (-Pd*Pn);
    oO = Bleh - (Qn*Cross)/(Qn*Bleh+Qd)*Cross/llVecMag(Cross);}
</lsl>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 713: Line 762:
|-
|-
| vector Pn
| vector Pn
| Normal of Plane 1
| Normal of Plane (unit vector)
|-
|-
| float Pd
| float Pd
| Distance of Plane 1
| Distance of Plane
|-
|-
| vector Qn
| vector O
| Origin of Plane 2
| Origin of Ray
|-
|-
| float Qd
| vector D
| Distance of Plane 2
| Direction of Ray
|-
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| vector oO
| return vector gPRdV
| Intersection Line's origin
| Returns vector along a ray to a plane
|-
| vector oD
| Intersection Line's direction
|-
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
!style="background-color: #eed0d0" colspan="2"| Requirement
|-
|-
|style="background-color: #eed0d0" colspan="2"| global vector oO
|style="background-color: #eed0d0" colspan="2"| function float gPRxZ(vector Pn,float Pd,vector O,vector D)
|-
|}
|style="background-color: #eed0d0" colspan="2"| global vector oD
<div style="float:left;font-size: 80%;">
|}
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


<!--############# PLANE AND RAY, PROJECTION #############-->
<!--############# PLANE AND RAY, INTERSECTION POINT #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Plane and Ray, Projection
==== Plane and Ray, Intersection Point ====
|-
|-
|
|
Projects a ray onto a plane
Finds intersection point along a ray to a plane
<lsl>
<source lang="lsl2">
vector oO;vector oD;
vector gPRxX(vector Pn,float Pd,vector O,vector D){
 
     return O + gPRdV(Pn,Pd,O,D);}
gPRpR(vector Pn,float Pd,vector O,vector D){
</source>
     oO = O - (Pn * O + Pd) * Pn;
    vector t = llVecNorm( D - (Pn*((D*Pn)/(Pn*Pn))) );t = <1.0/t.x,1.0/t.y,1.0/t.z>;
    oD = Pn%t;}
</lsl>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 764: Line 806:
|-
|-
| vector Pn
| vector Pn
| Normal of Plane
| Normal of Plane (unit vector)
|-
|-
| float Pd
| float Pd
Line 778: Line 820:
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| vector oO
| return vector gPRxX
| Projected Ray Origin
| Returns vector point of intersection between ray and plane
|-
| vector oD
| Projected Ray Direction
|-
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
!style="background-color: #eed0d0" colspan="2"| Requirement
|-
|-
|style="background-color: #eed0d0" colspan="2"| global vector oO
|style="background-color: #eed0d0" colspan="2"| function vector gPRdV(vector Pn,float Pd,vector O,vector D)
|-
|style="background-color: #eed0d0" colspan="2"| global vector oD
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


=== Sphere Functions ===
<!--############# PLANE AND LINE, INTERSECTION POINT #############-->
 
<!--############# SPHERE AND RAY, INTERSECTION POINT #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Sphere and Ray, Intersection Point
==== Plane and Line, Intersection Point ====
|-
|-
|
|
Finds intersection point of sphere and ray
Finds interesection point of a line and a plane
<lsl>
<source lang="lsl2">
vector gSRxX(vector Sp, float Sr, vector Ro, vector Rd){
vector gPLxX(vector Pn,float Pd,vector O,vector D){
     float t;Ro = Ro - Sp;
     return O + D*-( (Pn*O-Pd)/(Pn*D) );}
    if(Rd == ZERO_VECTOR) return ZERO_VECTOR;
</source>
   
 
    float a = Rd * Rd;
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
    float b = 2 * Rd * Ro;
!style="background-color: #d0d0ee" | Input
    float c = (Ro * Ro) - (Sr * Sr);
!style="background-color: #d0d0ee" | Description
   
|-
    float disc = b * b - 4 * a * c;
| vector Pn
   
| Normal of Plane (unit vector)
    if(disc < 0) return ZERO_VECTOR;
|-
   
| float Pd
    float distSqrt = llSqrt(disc);
| Distance of Plane
    float q;
|-
   
| vector O
    if(b < 0)
| Origin of Line
        q = (-b - distSqrt)/2.0;
|-
    else
| vector D
        q = (-b + distSqrt)/2.0;
| Direction of Line
   
|-
    float t0 = q / a;
!style="background-color: #d0d0ee" | Output
    float t1 = c / q;
!style="background-color: #d0d0ee" | Description
   
|-
    if(t0 > t1){
| return vector gPLxX
        float temp = t0;
| Returns vector point of intersection between line and plane
        t0 = t1;
|}
        t1 = temp;
<div style="float:left;font-size: 80%;">
    }
'''3D'''</div>
   
<div style="float:right;font-size: 80%;">
    if(t1 < 0) return ZERO_VECTOR;
By Nexii Malthus</div>
   
|}
    if(t0 < 0)
        t = t1;
    else
        t = t0;
   
    return Ro + (t * Rd);
}
</lsl>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
<!--############# PLANE AND PLANE, INTERSECTION LINE #############-->
!style="background-color: #d0d0ee" | Input
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="background-color: #d0d0ee" | Description
!style="color: #000000; background-color: #aaaaff;" height="20px"|
==== Plane and Plane, Intersection Line ====
|-
|-
| vector Sp
|
| Origin of Sphere
Finds line of intersection of two planes
<source lang="lsl2">
vector oO;vector oD;
 
gPPxL(vector Pn,float Pd,vector Qn,float Qd){
    oD = (Pn%Qn)/llVecMag(Pn%Qn);
    vector Cross = (Pn%Qn)%Pn;
    vector Bleh = (-Pd*Pn);
    oO = Bleh - (Qn*Cross)/(Qn*Bleh+Qd)*Cross/llVecMag(Cross);}
</source>
 
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
|-
| vector Pn
| Normal of Plane 1 (unit vector)
|-
|-
| float Sr
| float Pd
| Radius of Sphere
| Distance of Plane 1
|-
|-
| vector Ro
| vector Qn
| Origin of Ray
| Normal of Plane 2 (unit vector)
|-
|-
| vector Rd
| float Qd
| Direction of Ray
| Distance of Plane 2
|-
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| vector gSRxX
| vector oO
| Returns intersection point of sphere and ray otherwise ZERO_VECTOR
| Intersection Line's origin
|-
| vector oD
| Intersection Line's direction
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
|-
|style="background-color: #eed0d0" colspan="2"| global vector oO
|-
|style="background-color: #eed0d0" colspan="2"| global vector oD
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


<!--############# SPHERE AND RAY, INTERSECTION BOOLEAN #############-->
<!--############# PLANE AND RAY, PROJECTION #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Sphere and Ray, Intersection Boolean
==== Plane and Ray, Projection ====
|-
|-
|
|
Finds if there is a intersection of sphere and ray
Projects a ray onto a plane
<lsl>
<source lang="lsl2">
integer gSRx(vector Sp, float Sr, vector Ro, vector Rd){
vector oO;vector oD;
     float t;Ro = Ro - Sp;
 
     //vector RayOrg = llDetectedPos(x) - llGetPos();
gPRpR(vector Pn,float Pd,vector O,vector D){
    if(Rd == ZERO_VECTOR) return FALSE;
     oO = O - (Pn * O + Pd) * Pn;
   
     vector t = llVecNorm( D - (Pn*((D*Pn)/(Pn*Pn))) );t = <1.0/t.x,1.0/t.y,1.0/t.z>;
    float a = Rd * Rd;
     oD = Pn%t;}
    float b = 2 * Rd * Ro;
</source>
    float c = (Ro * Ro) - (Sr * Sr);
   
    float disc = b * b - 4 * a * c;
   
    if(disc < 0) return FALSE;
     return TRUE;
}
</lsl>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
Line 898: Line 947:
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| vector Sp
| vector Pn
| Origin of Sphere
| Normal of Plane (unit vector)
|-
|-
| float Sr
| float Pd
| Radius of Sphere
| Distance of Plane
|-
|-
| vector Ro
| vector O
| Origin of Ray
| Origin of Ray
|-
|-
| vector Rd
| vector D
| Direction of Ray
| Direction of Ray
|-
|-
Line 913: Line 962:
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| integer gSRx
| vector oO
| Returns a boolean indicating if there is a valid intersection
| Projected Ray Origin
|}
|-
| vector oD
| Projected Ray Direction
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
|-
|style="background-color: #eed0d0" colspan="2"| global vector oO
|-
|style="background-color: #eed0d0" colspan="2"| global vector oD
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


=== Ray Functions ===
=== <div style="font-size: 120%;">[[#Geometric Library|Sphere Functions]]</div> ===


<!--############# RAY AND POINT, PROJECTED DISTANCE #############-->
<!--############# SPHERE AND RAY, INTERSECTION POINT #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Ray and Point, projected distance
==== Sphere and Ray, Intersection Point ====
|-
|-
|
|
Finds projected distance of a point along a ray
Finds intersection point of sphere and ray
<lsl>
<source lang="lsl2">
float gRXpZ(vector O,vector D,vector A){
vector gSRxX(vector Sp, float Sr, vector Ro, vector Rd){
     return (A-O)*D;}
     float t; Ro -= Sp;
</lsl>
    if(Rd == ZERO_VECTOR) return ZERO_VECTOR;
 
   
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
    float a = Rd * Rd;
!style="background-color: #d0d0ee" | Input
    float b = 2 * Rd * Ro;
!style="background-color: #d0d0ee" | Description
    float c = (Ro * Ro)  - (Sr * Sr);
|-
   
| vector O
    float disc = b * b - 4 * a * c;
| Origin of Ray
   
|-
    if(disc < 0) return ZERO_VECTOR;
| vector D
   
| Direction of Ray
    float distSqrt = llSqrt(disc);
|-
    float q;
| vector A
   
| Origin of Point
    if(b < 0)
|-
        q = (-b - distSqrt)/2.0;
!style="background-color: #d0d0ee" | Output
     else
!style="background-color: #d0d0ee" | Description
        q = (-b + distSqrt)/2.0;
|-
   
| float gRXpZ
    float t0 = q / a;
| Returns projected distance of a point along a ray
    float t1 = c / q;
|}
      
<div style="float:right;font-size: 80%;">
    if(t0 > t1){
By Nexii Malthus</div>
        float temp = t0;
|}
        t0 = t1;
 
        t1 = temp;
=== Box Functions ===
    }
 
<!--############# BOX AND RAY, INTERSECTION DISTANCE #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Box and Ray, Intersection Distance
|-
|
Finds intersection of a Ray to a Box and returns intersection distance, otherwise -1 if there is no legal intersection.
<lsl>
float gBRxZ(vector Ro,vector Rd, vector Bo, vector Bs, rotation Br){
     vector oB = (Ro-Bo)/Br;   vector dB = Rd/Br;   vector eB = 0.5*Bs;
     float mD = -1.0;   float D;   vector X;
      
      
     if(llFabs(dB.x) > 0.000001){
     if(t1 < 0) return ZERO_VECTOR;
        D = (-eB.x - oB.x ) / dB.x;
   
        if(D >= 0.0){
    if(t0 < 0)
            X = oB + D * dB;
        t = t1;
            if(X.y >= -eB.y && X.y <= eB.y && X.z >= -eB.z && X.z <= eB.z)
    else
                mD = D;
         t = t0;
        }
        D = ( eB.x - oB.x ) / dB.x;
         if (D >= 0.0){
            X = oB + D * dB;
            if(X.y >= -eB.y && X.y <= eB.y && X.z >= -eB.z && X.z <= eB.z)
                if (mD < 0.0 || mD > D)
                    mD = D;
        }
    }
      
      
     if(llFabs(dB.y) > 0.000001){
     return Sp + Ro + (t * Rd);
        D = (-eB.y - oB.y ) / dB.y;
}
        if(D >= 0.0){
</source>
            X = oB + D * dB;
 
            if(X.x >= -eB.x && X.x <= eB.x && X.z >= -eB.z && X.z <= eB.z)
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
                if (mD < 0.0 || mD > D)
!style="background-color: #d0d0ee" | Input
                    mD = D;
!style="background-color: #d0d0ee" | Description
        }
|-
        D = ( eB.y - oB.y ) / dB.y;
| vector Sp
        if (D >= 0.0){
| Origin of Sphere
            X = oB + D * dB;
|-
            if(X.x >= -eB.x && X.x <= eB.x && X.z >= -eB.z && X.z <= eB.z)
| float Sr
                if (mD < 0.0 || mD > D)
| Radius of Sphere
                    mD = D;
|-
        }
| vector Ro
    }
| Origin of Ray
   
    if(llFabs(dB.z) > 0.000001){
        D = (-eB.z - oB.z ) / dB.z;
        if(D >= 0.0){
            X = oB + D * dB;
            if(X.x >= -eB.x && X.x <= eB.x && X.y >= -eB.y && X.y <= eB.y)
                if (mD < 0.0 || mD > D)
                    mD = D;
        }
        D = ( eB.z - oB.z ) / dB.z;
        if (D >= 0.0){
            X = oB + D * dB;
            if(X.x >= -eB.x && X.x <= eB.x && X.y >= -eB.y && X.y <= eB.y)
                if (mD < 0.0 || mD > D)
                    mD = D;
        }
    }
   
    return mD;
}
</lsl>
 
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
|-
| vector Ro
| Origin of Ray
|-
|-
| vector Rd
| vector Rd
| Direction of Ray
| Direction of Ray
|-
|-
| vector Bo
!style="background-color: #d0d0ee" | Output
| Origin of Box
|-
| vector Bs
| Size of Box
|-
| rotation Br
| Rotation of Box
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| float gBRxZ
| vector gSRxX
| Returns distance to intersection of a ray and a box
| Returns intersection point of sphere and ray otherwise ZERO_VECTOR
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By [http://forums.secondlife.com/showpost.php?p=1984100&postcount=7 Hewee Zetkin]</div>
By Nexii Malthus</div>
|}
|}


<!--############# BOX AND RAY, INTERSECTION POINT #############-->
<!--############# SPHERE AND RAY, INTERSECTION BOOLEAN #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Box and Ray, Intersection Point
 
==== Sphere and Ray, Intersection Boolean ====
|-
|-
|
|
Finds intersection of a Ray to a Box and returns intersection point, otherwise ZERO_VECTOR if there is no legal intersection.
Finds if there is a intersection of sphere and ray
<lsl>
<source lang="lsl2">
vector gBRxX( vector Ro, vector Rd, vector Bo, vector Bs, rotation Br){
integer gSRx(vector Sp, float Sr, vector Ro, vector Rd){
     float k = gBRxZ(Ro,Rd,Bo,Bs,Br);
     float t;Ro = Ro - Sp;
     if( ~k ) return Ro + Rd * k;
    //vector RayOrg = llDetectedPos(x) - llGetPos();
     else return ZERO_VECTOR;}
     if(Rd == ZERO_VECTOR) return FALSE;
</lsl>
   
    float a = Rd * Rd;
    float b = 2 * Rd * Ro;
    float c = (Ro * Ro)  - (Sr * Sr);
   
    float disc = b * b - 4 * a * c;
   
    if(disc < 0) return FALSE;
     return TRUE;
}
</source>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
| vector Sp
| Origin of Sphere
|-
| float Sr
| Radius of Sphere
|-
|-
| vector Ro
| vector Ro
Line 1,077: Line 1,098:
| vector Rd
| vector Rd
| Direction of Ray
| Direction of Ray
|-
| vector Bo
| Origin of Box
|-
| vector Bs
| Size of Box
|-
| rotation Br
| Rotation of Box
|-
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| vector gBRxX
| integer gSRx
| Returns point of intersection of a ray and a box
| Returns a boolean indicating if there is a valid intersection
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
|-
|style="background-color: #eed0d0" colspan="2"| float gBRxZ(vector Ro,vector Rd, vector Bo, vector Bs, rotation Br)
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By [http://forums.secondlife.com/showpost.php?p=1984100&postcount=7 Hewee Zetkin]</div>
By Nexii Malthus</div>
|}
|}


<!--############# BOX AND POINT, INTERSECTION BOOLEAN #############-->
=== <div style="font-size: 120%;">[[#Geometric Library|Ray Functions]]</div> ===
 
<!--############# RAY AND POINT, PROJECTED DISTANCE #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Box and Point, Intersection Boolean
==== Ray and Point, projected distance ====
|-
|-
|
|
Finds if there is an intersection of a Point and a Box and returns boolean
Finds projected distance of a point along a ray
<lsl>
<source lang="lsl2">
integer gBXx(vector A, vector Bo, vector Bs, rotation Br){
float gRXpZ(vector O,vector D,vector A){
     vector eB = 0.5*Bs;
     return (A-O)*D;}
    vector rA = (A-Bo)/Br;
</source>
    if( rA.x < eB.x && rA.x > -eB.x &&
        rA.y < eB.y && rA.y > -eB.y &&
        rA.z < eB.z && rA.z > -eB.z ) return TRUE;
    else return FALSE;}
</lsl>


{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
| vector O
| Origin of Ray
|-
| vector D
| Direction of Ray
|-
|-
| vector A
| vector A
| Origin of Point
| Origin of Point
|-
|-
| vector Bo
!style="background-color: #d0d0ee" | Output
| Origin of Box
|-
| vector Bs
| Size of Box
|-
| rotation Br
| Rotation of Box
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| integer gBXx(vector A, vector Bo, vector Bs, rotation Br)
| float gRXpZ
| Returns boolean check of intersection of a point and a box if there is one, otherwise FALSE
| Returns projected distance of a point along a ray
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


<!--############# BOX AND POINT, NEAREST POINT ON EDGE #############-->
=== <div style="font-size: 120%;">[[#Geometric Library|Box Functions]]</div> ===
 
<!--############# BOX AND RAY, INTERSECTION DISTANCE #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Box and Point, Nearest Point on Edge
==== Box and Ray, Intersection Distance ====
|-
|-
|
|
Processes point on nearest edge of box to given point
Finds intersection of a Ray to a Box and returns intersection distance, otherwise -1 if there is no legal intersection.
<lsl>
<source lang="lsl2">
vector gBXnEX(vector A, vector Bo, vector Bs, rotation Br){
float gBRxZ(vector Ro,vector Rd, vector Bo, vector Bs, rotation Br){
     vector eB = 0.5*<llFabs(Bs.x),llFabs(Bs.y),llFabs(Bs.z)>;
     vector oB = (Ro-Bo)/Br;    vector dB = Rd/Br;    vector eB = 0.5*Bs;
     vector rA = (A-Bo)/Br;
     float mD = -1.0;    float D;    vector X;
      
      
     float mD = 3.402823466E+38;
     if(llFabs(dB.x) > 0.000001){
    vector X;
        D = (-eB.x - oB.x ) / dB.x;
    list EdgesX = [< 0, eB.y, eB.z>, < 0,-eB.y, eB.z>, < 0,-eB.y,-eB.z>, < 0, eB.y,-eB.z>];
        if(D >= 0.0){
    list EdgesY = [< eB.x, 0, eB.z>, <-eB.x, 0, eB.z>, <-eB.x, 0,-eB.z>, < eB.x, 0,-eB.z>];
            X = oB + D * dB;
    list EdgesZ = [< eB.x, eB.y, 0>, <-eB.x, eB.y, 0>, <-eB.x,-eB.y, 0>, < eB.x,-eB.y, 0>];
            if(X.y >= -eB.y && X.y <= eB.y && X.z >= -eB.z && X.z <= eB.z)
                mD = D;
        }
        D = ( eB.x - oB.x ) / dB.x;
        if (D >= 0.0){
            X = oB + D * dB;
            if(X.y >= -eB.y && X.y <= eB.y && X.z >= -eB.z && X.z <= eB.z)
                if (mD < 0.0 || mD > D)
                    mD = D;
        }
    }
      
      
     integer x = (EdgesX != []);
     if(llFabs(dB.y) > 0.000001){
    while( --x + 1 ){
        D = (-eB.y - oB.y ) / dB.y;
         float y = gLXdZ( llList2Vector( EdgesX, x ), <1,0,0>, rA );
         if(D >= 0.0){
       
            X = oB + D * dB;
        if( rA.x > eB.x ) y += rA.x - eB.x;
            if(X.x >= -eB.x && X.x <= eB.x && X.z >= -eB.z && X.z <= eB.z)
         else if( rA.x < -eB.x ) y -= rA.x - -eB.x;
                if (mD < 0.0 || mD > D)
       
                    mD = D;
         if( y < mD ){ mD = y; X = gLXnX( llList2Vector( EdgesX, x ), <1,0,0>, rA ); }
         }
        D = ( eB.y - oB.y ) / dB.y;
         if (D >= 0.0){
            X = oB + D * dB;
            if(X.x >= -eB.x && X.x <= eB.x && X.z >= -eB.z && X.z <= eB.z)
                if (mD < 0.0 || mD > D)
                    mD = D;
        }
     }
     }
     x = (EdgesY != []);
      
    while( --x + 1 ){
    if(llFabs(dB.z) > 0.000001){
         float y = gLXdZ( llList2Vector( EdgesY, x ), <0,1,0>, rA );
        D = (-eB.z - oB.z ) / dB.z;
       
         if(D >= 0.0){
        if( rA.y > eB.y ) y += rA.y - eB.y;
            X = oB + D * dB;
        else if( rA.y < -eB.y ) y -= rA.y - -eB.y;
            if(X.x >= -eB.x && X.x <= eB.x && X.y >= -eB.y && X.y <= eB.y)
       
                if (mD < 0.0 || mD > D)
        if( y < mD ){ mD = y; X = gLXnX( llList2Vector( EdgesY, x ), <0,1,0>, rA ); }
                    mD = D;
    }
        }
    x = (EdgesZ != []);
        D = ( eB.z - oB.z ) / dB.z;
    while( --x + 1 ){
        if (D >= 0.0){
        float y = gLXdZ( llList2Vector( EdgesZ, x ), <0,0,1>, rA );
            X = oB + D * dB;
       
            if(X.x >= -eB.x && X.x <= eB.x && X.y >= -eB.y && X.y <= eB.y)
        if( rA.z > eB.z ) y += rA.z - eB.z;
                if (mD < 0.0 || mD > D)
        else if( rA.z < -eB.z ) y -= rA.z - -eB.z;
                    mD = D;
       
        }
        if( y < mD ){ mD = y; X = gLXnX( llList2Vector( EdgesZ, x ), <0,0,1>, rA ); }
     }
     }
      
      
     if( mD < 0.000001 ) return <-1,-1,-1>;
     return mD;
    if(      X.x >  eB.x ) X.x =  eB.x;
}
    else if( X.x < -eB.x ) X.x = -eB.x;
</source>
    if(      X.y >  eB.y ) X.y =  eB.y;
 
    else if( X.y < -eB.y ) X.y = -eB.y;
    if(      X.z >  eB.z ) X.z =  eB.z;
    else if( X.z < -eB.z ) X.z = -eB.z;
   
    return Bo + ( X * Br );}
</lsl>
 
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| vector A
| vector Ro
| Origin of Point
| Origin of Ray
|-
| vector Rd
| Direction of Ray
|-
|-
| vector Bo
| vector Bo
Line 1,220: Line 1,240:
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| vector gBXnEX(vector A, vector Bo, vector Bs, rotation Br)
| float gBRxZ
| Returns nearest point on edge of box B closest to point A. Returns <-1,-1,-1> if already on closest point.
| Returns distance to intersection of a ray and a box
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
|-
|style="background-color: #eed0d0" colspan="2"| float gLXdZ(vector O,vector D,vector A)
|-
|style="background-color: #eed0d0" colspan="2"| vector gLXdV(vector O,vector D,vector A)
|-
|style="background-color: #eed0d0" colspan="2"| vector gLXnX(vector O,vector D,vector A)
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
By [http://forums.secondlife.com/showpost.php?p=1984100&postcount=7 Hewee Zetkin]</div>
|}
|}


=== Polygon ===
<!--############# BOX AND RAY, INTERSECTION POINT #############-->
 
<!--############# Polygon and Point, Intersection Boolean #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Polygon and Point, Intersection Boolean
==== Box and Ray, Intersection Point ====
|-
|-
|
|
Figures out if point is inside of polygon or otherwise.
Finds intersection of a Ray to a Box and returns intersection point, otherwise ZERO_VECTOR if there is no legal intersection.
<lsl>
<source lang="lsl2">
integer gCPXx( list CP, vector X )
vector gBRxX( vector Ro, vector Rd, vector Bo, vector Bs, rotation Br){
{//Copyright (c) 1970-2003, Wm. Randolph Franklin; 2008, Strife Onizuka
    float k = gBRxZ(Ro,Rd,Bo,Bs,Br);
    integer i = ~(CP != []);
    if( k != -1.0 ) return Ro + Rd * k;
    integer c = 0;
     else return ZERO_VECTOR;}
    if(i < -2){
</source>
        vector vi = llList2Vector(CP, -1);
 
        do {
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
            vector vj = vi;
!style="background-color: #d0d0ee" | Input
            vi = llList2Vector(CP, i);
!style="background-color: #d0d0ee" | Description
            if((vi.y > X.y) ^ (vj.y > X.y)){
|-
                if(vj.y != vi.y)
| vector Ro
                    c = c ^ (X.x < (((vj.x - vi.x) * (X.y - vi.y) / (vj.y - vi.y)) + vi.x));
| Origin of Ray
                else c = c ^ (0 < ((vj.x-vi.x) * (X.y-vi.y)));
            }
        } while (++i);
     }
    return c;
}
</lsl>
 
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
|-
|-
| list CP
| vector Rd
| Vertices of Concave Polygon
| Direction of Ray
|-
|-
| vector X
| vector Bo
| Origin of Point
| Origin of Box
|-
|-
!style="background-color: #d0d0ee" | Output
| vector Bs
!style="background-color: #d0d0ee" | Description
| Size of Box
|-
|-
| integer gCPXx( list CP, vector X )
| rotation Br
| Returns TRUE if point (X) intersects concave polygon (CP), otherwise FALSE
| Rotation of Box
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
|-
| vector gBRxX
| Returns point of intersection of a ray and a box
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
|-
|style="background-color: #eed0d0" colspan="2"| float gBRxZ(vector Ro,vector Rd, vector Bo, vector Bs, rotation Br)
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
Copyright (c) 1970-2003, Wm. Randolph Franklin (Must accept License #1), LSL-Port By Strife Onizuka</div>
By [http://forums.secondlife.com/showpost.php?p=1984100&postcount=7 Hewee Zetkin]</div>
|}
|}


<!--############# Polygon and Line Segment, Intersection Boolean #############-->
<!--############# BOX AND POINT, INTERSECTION BOOLEAN #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
Polygon and Line Segment, Intersection Boolean
 
==== Box and Point, Intersection Boolean ====
|-
|-
|
|
Figures out if line segment intersects with polygon.
Finds if there is an intersection of a Point and a Box and returns boolean
<lsl>
<source lang="lsl2">
integer gVPLSx( vector P0, vector P1, list VP ){
integer gBXx(vector A, vector Bo, vector Bs, rotation Br){
     //Copyright 2001, softSurfer (www.softsurfer.com); 2008, Nexii Malthus
     vector eB = 0.5*Bs; vector rA = (A-Bo)/Br;
    if( P0 == P1 ) return isPointInPolygon2D( VP, P0 );
     return (rA.x<eB.x && rA.x>-eB.x && rA.y<eB.y && rA.y>-eB.y && rA.z<eB.z && rA.z>-eB.z); }
    float tE = 0; float tL = 1;
</source>
    float t; float N; float D;
 
    vector dS = P1 - P0;
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
     vector e; integer x; integer y = VP!=[];
!style="background-color: #d0d0ee" | Input
    @start;
    for( x = 0; x < y; ++x ){
        e = llList2Vector( VP, x+1 ) - llList2Vector( VP, x );
        N = Perp( e, P0 - llList2Vector( VP, x ) );
        D = -Perp( e, dS );
        if( llFabs(D) < 0.00000001 )
            if( N < 0 ) return FALSE;
            else jump start;
        t = N / D;
        if( D < 0 ){
            if( t > tE ){  tE = t; if( tE > tL ) return FALSE;    }
        } else {
            if( t < tL ){  tL = t; if( tL < tE ) return FALSE;    }
    }  }
    // PointOfEntrance = P0 + tE * dS;
    // PointOfExit = P0 + tL * dS;
    return TRUE;
}
</lsl>
 
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| list VP
| vector A
| Vertices of Convex Polygon
| Origin of Point
|-
| vector Bo
| Origin of Box
|-
| vector Bs
| Size of Box
|-
|-
| vector P0, vector P1
| rotation Br
| Start and End of Line Segment
| Rotation of Box
|-
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
!style="background-color: #d0d0ee" | Description
|-
|-
| integer gVPLSx( vector P0, vector P1, list VP )
| integer gBXx(vector A, vector Bo, vector Bs, rotation Br)
| Returns TRUE if line segment (P0,P1) intersects convex polygon (VP), otherwise FALSE
| Returns boolean check of intersection of a point and a box if there is one, otherwise FALSE
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
|-
|style="background-color: #eed0d0" colspan="2"| <lsl>float Perp( vector U, vector V ){ return U.x*V.y - U.y*V.x; }</lsl>
|}
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
<div style="float:right;font-size: 80%;">
Copyright 2001, softSurfer (www.softsurfer.com) (Must accept License #2), LSL-Port By Nexii Malthus</div>
By Nexii Malthus</div>
|}
|}


 
<!--############# BOX AND POINT, NEAREST POINT ON EDGE #############-->
=== Other Functions ===
 
<!--############# 3D PROJECTION #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
!style="color: #000000; background-color: #aaaaff;" height="20px"|
3D Projection
 
==== Box and Point, Nearest Point on Edge ====
|-
|-
|
|
Projects a vector A by vector B.
Processes point on nearest edge of box to given point
<lsl>
<source lang="lsl2">
vector Project3D(vector A,vector B){
vector gBXnEX(vector A, vector Bo, vector Bs, rotation Br){
     return B * ( ( A * B ) / ( B * B ) );}
     vector eB = 0.5*<llFabs(Bs.x),llFabs(Bs.y),llFabs(Bs.z)>;
</lsl>
    vector rA = (A-Bo)/Br;
 
   
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
    float mD = 3.402823466E+38;
!style="background-color: #d0d0ee" | Input
    vector X;
!style="background-color: #d0d0ee" | Description
    list EdgesX = [< 0, eB.y, eB.z>, < 0,-eB.y, eB.z>, < 0,-eB.y,-eB.z>, < 0, eB.y,-eB.z>];
|-
    list EdgesY = [< eB.x, 0, eB.z>, <-eB.x, 0, eB.z>, <-eB.x, 0,-eB.z>, < eB.x, 0,-eB.z>];
| vector A
    list EdgesZ = [< eB.x, eB.y, 0>, <-eB.x, eB.y, 0>, <-eB.x,-eB.y, 0>, < eB.x,-eB.y, 0>];
| First Vector
   
|-
    integer x = (EdgesX != []);
| vector B
    while( x-- ){
| Second Vector
        float y = gLXdZ( llList2Vector( EdgesX, x ), <1,0,0>, rA );
|-
       
!style="background-color: #d0d0ee" | Output
        if( rA.x > eB.x ) y += rA.x - eB.x;
!style="background-color: #d0d0ee" | Description
        else if( rA.x < -eB.x ) y -= rA.x - -eB.x;
|-
       
| return Project3D(vector A, vector B)
        if( y < mD ){ mD = y; X = gLXnX( llList2Vector( EdgesX, x ), <1,0,0>, rA ); }
| Returns result of projection
    }
|}
    x = (EdgesY != []);
<div style="float:right;font-size: 80%;">
    while( x-- ){
By Nexii Malthus</div>
        float y = gLXdZ( llList2Vector( EdgesY, x ), <0,1,0>, rA );
|}
       
 
        if( rA.y > eB.y ) y += rA.y - eB.y;
 
        else if( rA.y < -eB.y ) y -= rA.y - -eB.y;
 
       
=== Legend ===
        if( y < mD ){ mD = y; X = gLXnX( llList2Vector( EdgesY, x ), <0,1,0>, rA ); }
For anyone curious to the shorthand used and who wish to use a lookup table can use this as a reference. Or anyone who wishes to add a new function to the library is welcome to but it would be recommended to keep consistency.
    }
I tried to minimize the script function names to be easily readable. All the geometric function names start with a g.
    x = (EdgesZ != []);
Here is the legend:
    while( x-- ){
        float y = gLXdZ( llList2Vector( EdgesZ, x ), <0,0,1>, rA );
       
        if( rA.z > eB.z ) y += rA.z - eB.z;
        else if( rA.z < -eB.z ) y -= rA.z - -eB.z;
       
        if( y < mD ){ mD = y; X = gLXnX( llList2Vector( EdgesZ, x ), <0,0,1>, rA ); }
    }
   
    if( mD < 0.000001 ) return <-1,-1,-1>;
    if(      X.x >  eB.x ) X.x =  eB.x;
    else if( X.x < -eB.x ) X.x = -eB.x;
    if(      X.y >  eB.y ) X.y = eB.y;
    else if( X.y < -eB.y ) X.y = -eB.y;
    if(      X.z >  eB.z ) X.z = eB.z;
    else if( X.z < -eB.z ) X.z = -eB.z;
   
    return Bo + ( X * Br );}
</source>


{| class="sortable" {{Prettytable}}
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
|-{{Hl2}}
!style="background-color: #d0d0ee" | Input
! '''Shorthand'''
!style="background-color: #d0d0ee" | Description
! '''Name'''
! class="unsortable" | '''Description'''
|-
|-
! colspan="3" height="50%" | Geometric Types, all the shapes in the library
| vector A
| Origin of Point
|-
|-
||X
| vector Bo
||Point
| Origin of Box
||vector defining a point in space
|-
|-
||L
| vector Bs
||'''L'''ine
| Size of Box
||A line has an origin and a direction and is infinitely long
|-
|-
||LS
| rotation Br
||'''L'''ine '''S'''egment
| Rotation of Box
||A line segment is a finite line and therefore consists of a start and end position
|-
|-
||R
!style="background-color: #d0d0ee" | Output
||'''R'''ay
!style="background-color: #d0d0ee" | Description
||A ray is like a line, except it is more distinct as it defines wether it points forward or back
|-
| vector gBXnEX(vector A, vector Bo, vector Bs, rotation Br)
| Returns nearest point on edge of box B closest to point A. Returns <-1,-1,-1> if already on closest point.
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
|-
|style="background-color: #eed0d0" colspan="2"| float gLXdZ(vector O,vector D,vector A)
|-
|-
||P
|style="background-color: #eed0d0" colspan="2"| vector gLXdV(vector O,vector D,vector A)
||'''P'''lane
||A 2D doubly ruled surface of infinite size
|-
|-
||S
|style="background-color: #eed0d0" colspan="2"| vector gLXnX(vector O,vector D,vector A)
||'''S'''phere
|}
||A sphere is defined by origin and radius
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
|}
 
=== <div style="font-size: 120%;">[[#Geometric Library|Cylinder]]</div> ===
 
<!--############# CYLINDER AND POINT, INTERSECTION BOOLEAN #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
 
==== Cylinder and Point, Intersection Boolean ====
|-
|-
||B
|
Finds if there is an intersection of a Point and a Cylinder and returns boolean
<source lang="lsl2">
integer gCXx( vector A, vector O, rotation R, vector S ) {
    A = ( A - O ) / R;// Converts to local object frame
    return (llPow(A.x/S.x*2,2) + llPow(A.y/S.y*2,2)) <= 1. // Test radius
        && llFabs(A.z/S.z*2) <= 1.;// Test top/bottom
}
</source>
 
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
|-
| vector A
| Origin of Point
|-
| vector Bo
| Origin of Cylinder
|-
| vector Bs
| Size of Cylinder
|-
| rotation Br
| Rotation of Cylinder
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
|-
| integer gCXx( vector A, vector O, rotation R, vector S )
| Returns boolean check of intersection of a point and a cylinder if there is one, otherwise FALSE
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
|}
 
 
 
=== <div style="font-size: 120%;">[[#Geometric Library|Polygon]]</div> ===
 
<!--############# Polygon and Point, Intersection Boolean #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
==== Polygon and Point, Intersection Boolean ====
|-
|
Figures out if point is inside of polygon or otherwise.
<source lang="lsl2">
integer gCPXx( list CP, vector X )
{//Copyright (c) 1970-2003, Wm. Randolph Franklin; 2008, Strife Onizuka
    integer i = ~(CP != []);
    integer c = 0;
    if(i < -2){
        vector vi = llList2Vector(CP, -1);
        do {
            vector vj = vi;
            vi = llList2Vector(CP, i);
            if((vi.y > X.y) ^ (vj.y > X.y)){
                if(vj.y != vi.y)
                    c = c ^ (X.x < (((vj.x - vi.x) * (X.y - vi.y) / (vj.y - vi.y)) + vi.x));
                else c = c ^ (0 < ((vj.x-vi.x) * (X.y-vi.y)));
            }
        } while (++i);
    }
    return c;
}
</source>
 
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
|-
| list CP
| Vertices of Concave Polygon
|-
| vector X
| Origin of Point
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
|-
| integer gCPXx( list CP, vector X )
| Returns TRUE if point (X) intersects concave polygon (CP), otherwise FALSE
|}
<div style="float:left;font-size: 80%;">
'''2D'''</div>
<div style="float:right;font-size: 80%;">
Copyright (c) 1970-2003, Wm. Randolph Franklin (Must accept [[#.231|License #1]]), LSL-Port By Strife Onizuka</div>
|}
 
<!--############# Polygon and Line Segment, Intersection Boolean #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
==== Polygon and Line Segment, Intersection Boolean ====
|-
|
Figures out if line segment intersects with polygon.
<source lang="lsl2">
integer gVPLSx( vector P0, vector P1, list VP ){
    //Copyright 2001, softSurfer (www.softsurfer.com); 2008, Nexii Malthus
    if( P0 == P1 ) return gCPXx( VP, P0 );
    float tE = 0; float tL = 1;
    float t; float N; float D;
    vector dS = P1 - P0;
    vector e; integer x; integer y = VP!=[];
    @start;
    for( x = 0; x < y; ++x ){
        e = llList2Vector( VP, x+1 ) - llList2Vector( VP, x );
        N = Perp( e, P0 - llList2Vector( VP, x ) );
        D = -Perp( e, dS );
        if( llFabs(D) < 0.00000001 )
            if( N < 0 ) return FALSE;
            else jump start;
        t = N / D;
        if( D < 0 ){
            if( t > tE ){  tE = t; if( tE > tL ) return FALSE;    }
        } else {
            if( t < tL ){  tL = t; if( tL < tE ) return FALSE;    }
    }  }
    // PointOfEntrance = P0 + tE * dS;
    // PointOfExit = P0 + tL * dS;
    return TRUE;
}
</source>
 
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
|-
| list VP
| Vertices of Convex Polygon
|-
| vector P0, vector P1
| Start and End of Line Segment
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
|-
| integer gVPLSx( vector P0, vector P1, list VP )
| Returns TRUE if line segment (P0,P1) intersects convex polygon (VP), otherwise FALSE
|-
!style="background-color: #eed0d0" colspan="2"| Requirement
|-
|style="background-color: #eed0d0" | <source lang="lsl2">float Perp( vector U, vector V ){ return U.x*V.y - U.y*V.x; }</source>
| Perpendicular dot product
|-
|style="background-color: #eed0d0" | integer gCPXx( list CP, vector X )
| Only needed for (P0 == P1) safety catch check, so optional
|}
<div style="float:left;font-size: 80%;">
'''2D'''</div>
<div style="float:right;font-size: 80%;">
Copyright 2001, softSurfer (www.softsurfer.com) (Must accept [[#.232|License #2]]), LSL-Port By Nexii Malthus</div>
|}
 
=== <div style="font-size: 120%;">[[#Geometric Library|Other Functions]]</div> ===
 
<!--############# 3D PROJECTION #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
==== 3D Projection ====
|-
|
Projects a vector A by vector B.
<source lang="lsl2">
vector Project3D(vector A,vector B){
    return B * ( ( A * B ) / ( B * B ) );}
</source>
 
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
|-
| vector A
| First Vector
|-
| vector B
| Second Vector
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
|-
| return Project3D(vector A, vector B)
| Returns result of projection
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
|}
 
<!--############# REFLECTION #############-->
{|cellspacing="0" cellpadding="3" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #ffffff; border-collapse: collapse" width="80%"
!style="color: #000000; background-color: #aaaaff;" height="20px"|
==== Reflection ====
|-
|
Reflects Ray R with surface normal N
<source lang="lsl2">
vector Reflect(vector R,vector N){
    return R - 2 * N * ( R * N );}
</source>
 
{|cellspacing="0" cellpadding="6" border="1" style="border: 1px solid #aaaaaa; margin: 1em 1em 1em 0pt; background-color: #e0e0ff; border-collapse: collapse"
!style="background-color: #d0d0ee" | Input
!style="background-color: #d0d0ee" | Description
|-
| vector R
| Ray Normal
|-
| vector N
| Surface Normal
|-
!style="background-color: #d0d0ee" | Output
!style="background-color: #d0d0ee" | Description
|-
| return Reflect(vector R, vector N)
| Returns result of reflection
|}
<div style="float:left;font-size: 80%;">
'''3D'''</div>
<div style="float:right;font-size: 80%;">
By Nexii Malthus</div>
|}
 
=== <div style="font-size: 120%;">[[#Geometric Library|Glossary]]</div> ===
For anyone curious to the shorthand used and who wish to use a lookup table can use this as a reference. Or anyone who wishes to add a new function to the library is welcome to but it would be recommended to keep consistency.
I tried to minimize the script function names to be easily readable. All the geometric function names start with a g.
 
''g'' ('''Shape1''') ('''Shape2''') ('''Process''') ('''Return''' (''Only needed if other than integer''))
 
Here is the legend:
 
{| class="sortable" {{Prettytable}}
|-{{Hl2}}
! '''Shorthand'''
! '''Name'''
! class="unsortable" | '''Description'''
|-
! colspan="3" height="50%" | Geometric Types, all the shapes in the library
|-
||X
||Point
||vector defining a point in space
|-
||L
||'''L'''ine
||A line has an origin and a direction and is infinitely long
|-
||LS
||'''L'''ine '''S'''egment
||A line segment is a finite line and therefore consists of a start and end position
|-
||R
||'''R'''ay
||A ray is like a line, except it is more distinct as it defines wether it points forward or back
|-
||P
||'''P'''lane
||A 2D doubly ruled surface of infinite size
|-
||S
||'''S'''phere
||A sphere is defined by origin and radius (No ellipsoid functions available yet)
|-
||B
||'''B'''ox
||'''B'''ox
||A box is six sided and defined by origin, size as well as a rotation.
||A box primitive is six sided and defined by origin, size as well as a rotation.
|-
|-
||VP
||C
||Con'''v'''ex '''P'''olygon
||'''C'''ylinder
||Convex Polygon defined by list of vertices.
||An elliptic cylinder primitive .
|-
|-
||CP
||VP
||Con'''c'''ave '''P'''olygon
||Con'''v'''ex '''P'''olygon
||Concave Polygon defined by list of vertices. Automatic backward compatibility with Convex Polygons.
||Convex Polygon defined by list of vertices.
|-
|-
! colspan="3" height="50%" | The Process, What does it do?
||CP
|-
||Con'''c'''ave '''P'''olygon
||d
||Concave Polygon defined by list of vertices. Automatic backward compatibility with Convex Polygons.
||'''d'''istance
|-
||Calculate distance
! colspan="3" height="50%" | The Process, What does it do?
|-
||d
||'''d'''istance
||Calculate distance
|-
||n
||'''n'''earest
||Calculate nearest
|-
||p
||'''p'''roject
||Calculates projection
|-
||x
||Intersection
||Calculates intersection
|-
|-
||n
||dir
||'''n'''earest
||'''dir'''ection
||Calculate nearest
||Calculates direction
|-
||p
||'''p'''roject
||Calculates projection
|-
||x
||Intersection
||Calculates intersection
|-
|-
! colspan="3" height="50%" | Return, What kind of data do I get out of it?
! colspan="3" height="50%" | Return, What kind of data do I get out of it?
Line 1,471: Line 1,770:
|}
|}


=== <div style="font-size: 120%;">[[#Geometric Library|Licenses]]</div> ===


=== Licenses ===
==== #1 ====
 
<source lang="lsl2">
== #1 ==
<lsl>
//Copyright (c) 1970-2003, Wm. Randolph Franklin
//Copyright (c) 1970-2003, Wm. Randolph Franklin
//Copyright (c) 2008, Strife Onizuka (porting to LSL)
//Copyright (c) 2008, Strife Onizuka (porting to LSL)
Line 1,502: Line 1,800:
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.  
//SOFTWARE.  
</lsl>
</source>


== #2 ==
==== #2 ====
<lsl>
<source lang="lsl2">
// Copyright 2001, softSurfer (www.softsurfer.com); 2008, LSL-port by Nexii Malthus
// Copyright 2001, softSurfer (www.softsurfer.com); 2008, LSL-port by Nexii Malthus
// This code may be freely used and modified for any purpose
// This code may be freely used and modified for any purpose
Line 1,512: Line 1,810:
// liable for any real or imagined damage resulting from its use.
// liable for any real or imagined damage resulting from its use.
// Users of this code must verify correctness for their application.
// Users of this code must verify correctness for their application.
</lsl>
</source>

Latest revision as of 20:00, 24 January 2015

Please vote for: https://jira.secondlife.com/browse/WEB-235 So that I can expand each function into deeper detail without the page starting to fail in readability. --Nexii Malthus 23:05, 24 October 2008 (UTC)

:Break it up so each major section has its own page... thats why hypertext was invented. -Overbrain Unplugged 13:36, 10 October 2010 (UTC)

Geometric Library

Line and Point, Vector

Calculates the vector from a point 'to' the closest point on a line

vector gLXdV(vector O,vector D,vector A){
    return (O-A)-((O-A)*D)*D;}
Input Description
vector O Origin of Line
vector D Direction of Line
vector A Origin of Point
Output Description
return vector gLXdV Returns origin of closest point on Line to Point
3D
By Nexii Malthus

Line and Point, Distance

Calculates distance of line to point, same as measuring magnitude of Line and Point Vector, but faster on it's own

float gLXdZ(vector O,vector D,vector A){
    vector k = ( A - O ) % D;
    return llSqrt( k * k );}
Input Description
vector O Origin of Line
vector D Direction of Line (unit vector)
vector A Origin of Point
Output Description
return float gLXdZ Returns numerical distance from Line to Point
3D
By Nexii Malthus

Line Nearest Point, Nearest Point

Returns nearest point on line to given point

vector gLXnX(vector O,vector D,vector A){
    return gLXdV(O,D,A) + A;}
Input Description
vector O Origin of Line
vector D Direction of Line
vector A Origin of Point
Output Description
return vector gLXnX Returns nearest point on line given point
Requirement
function vector gLXdV(vector O,vector D,vector A)
3D
By Nexii Malthus

Line and Line, Vector

Shortest vector of two lines

vector gLLdV(vector O1,vector D1,vector O2,vector D2){
    vector A = O2 - O1; vector B = D1 % D2;
    return B*( (A*B)/(B*B) );}
Input Description
vector O1 Origin of Line 1
vector D1 Direction of Line 1
vector O2 Origin of Line 2
vector D2 Direction of Line 2
Output Description
return vector gLLdV Returns shortest vector between the two lines
3D
By Nexii Malthus

Line and Line, Distance

Returns the distance between two lines

float gLLdZ(vector O1,vector D1,vector O2,vector D2){
    vector A = D1%D2;float B = llVecMag(A);A = <A.x/B,A.y/B,A.z/B>;
    return (O2-O1) * A;}
Input Description
vector O1 Origin of Line 1
vector D1 Direction of Line 1
vector O2 Origin of Line 2
vector D2 Direction of Line 2
Output Description
return float gLLdZ Returns numerical distance between the two lines
3D
By Nexii Malthus

Line and Line, Nearest point

Closest point of two lines

vector gLLnX(vector O1,vector D1,vector O2,vector D2){
    vector nO1 = < O1*D1, O1*D2, 0>;
    vector nO2 = < O2*D1, O2*D2, 0>;
    vector nD1 = < D1*D1, O1*D2, 0>;
    vector nD2 = < O2*D1, O2*D2, 0>;
    
    float t = ( nD2.x*nD1.y - nD1.x*nD2.y );
    
    t = ( nD2.y*(nO1.x-nO2.x) - nD2.x*(nO1.y-nO2.y) ) / t;
    
    return O1 + D1*t;}
Input Description
vector O1 Origin of Line 1
vector D1 Direction of Line 1
vector O2 Origin of Line 2
vector D2 Direction of Line 2
Output Description
return vector gLLnX Returns closest point between the two lines
2D
By Nexii Malthus

Line and Line, intersection point

Computes intersection point of two lines, if there is any, else <-1,-1,-1> if none.

vector gLLxX( vector A, vector B, vector C, vector D ){
    vector b = B-A; vector d = D-C;
    float dotperp = b.x*d.y - b.y*d.x;
    if (dotperp == 0) return <-1,-1,-1>;
    vector c = C-A;
    float t = (c.x*d.y - c.y*d.x) / dotperp;
    return <A.x + t*b.x, A.y + t*b.y, 0>;}
Input Description
vector A Start of Line 1
vector B End of Line 1
vector C Start of Line 2
vector D End of Line 2
Output Description
return vector gLLxX The intersection point of the two lines, else <-1,-1,-1> if none
2D
By Nexii Malthus

Line and Line, two nearest points of lines

Two closest points of two lines on each line

vector X1;vector X2;
gLLnnXX(vector O1,vector D1,vector O2,vector D2){
    vector nO1 = < O1*D1, O1*D2, 0>;
    vector nO2 = < O2*D1, O2*D2, 0>;
    vector nD1 = < D1*D1, O1*D2, 0>;
    vector nD2 = < O2*D1, O2*D2, 0>;
    
    float t = ( nD2.x*nD1.y - nD1.x*nD2.y );
    
    t = ( nD2.y*(nO1.x-nO2.x) - nD2.x*(nO1.y-nO2.y) ) / t;
    
    X1 = O1 + D1*t;
    X2 = X1 + nD1%nD2;}
Input Description
vector O1 Origin of Line 1
vector D1 Direction of Line 1
vector O2 Origin of Line 2
vector D2 Direction of Line 2
Output Description
vector X1 Closest point on line 1 to line 2
vector X2 Closest point on line 2 to line 1
Requirement
global vector X1
global vector X2
2D
By Nexii Malthus

Line and Line, nearest line

Input two lines, the function will return a list containing two vectors responding to the line nearest between them. As well as two floats corresponding to the scalar value on the two line of where the line has an end located at.

list gLLnL( vector v0, vector v1, vector v2, vector v3 ) {
    float Eps = 0.000001; vector vx; vector vy; vector va; vector vb; vector vc;
    float x; float y; float d0; float d1; float d2; float d3; float d4;
    va = v0-v2; vb = v3-v2; if(llVecMag(vb)<Eps) return [];
    vc = v1-v0; if(llVecMag(vc)<Eps) return [];
    d0 = va*vb; d1 = vb*vc; d2 = va*vc; d3 = vb*vb; d4 = vc*vc;
    float den = d4*d3-d1*d1; if( llFabs(den) < Eps ) return [];
    float num = d0*d1-d2*d3; x = num/den; y = (d0+d1*x)/d3;
    vx = v0+vc*x; vy = v2+vb*y; return [vx,vy,x,y]; }
Input Description
vector v0 Point on Line 1
vector v1 Point on Line 1
vector v2 Point on Line 2
vector v3 Point on Line 2
Output Description
[vx] Nearest point on Line 1 to Line 2
[vy] Nearest point on Line 2 to Line 1
[x] Scalar value representing location of vx on line 1 (range [v0,v1])
[y] Scalar value representing location of vy on line 2 (range [v2,v3])
3D
By Nexii Malthus

Line and Line Segments, nearest line segment

Input two line segments, the function will return a list containing two vectors responding to the line segment nearest between them. As well as two floats corresponding to the scalar value on the two line segments of where the line segment has an end located at.

list gLSLSnLS( vector v0, vector v1, vector v2, vector v3 ) {
    float Eps = 0.000001; vector vx; vector vy; vector va; vector vb; vector vc;
    float x; float y; float d0; float d1; float d2; float d3; float d4;
    va = v0-v2; vb = v3-v2; if(llVecMag(vb)<Eps) return [];
    vc = v1-v0; if(llVecMag(vc)<Eps) return [];
    if( llFabs(vc.x + vc.y + vc.z) < Eps ) return [];
    d0 = va*vb; d1 = vb*vc; d2 = va*vc; d3 = vb*vb; d4 = vc*vc;
    float den = d4*d3-d1*d1; if( llFabs(den) < Eps ) return [];
    float num = d0*d1-d2*d3; x = num/den; y = (d0+d1*x)/d3;
    if(x<0)x=0; else if(x>1)x=1; if(y<0)y=0; else if(y>1)y=1;
    vx = v0+vc*x; vy = v2+vb*y; return [vx,vy,x,y]; }
Input Description
vector v0 Start of Line Segment 1
vector v1 End of Line Segment 1
vector v2 Start of Line Segment 2
vector v3 End of Line Segment 2
Output Description
[vx] Nearest point on Line Segment 1 to Line Segment 2
[vy] Nearest point on Line Segment 2 to Line Segment 1
[x] Scalar value representing location of vx on Line Segment 1 (range [v0,v1])
[y] Scalar value representing location of vy on Line Segment 2 (range [v2,v3])
3D
By Nexii Malthus

Line and Line, two nearest points with vector and distance

Computes two closest points of two lines, vector and distance

vector X1;vector X2;vector V1;float Z1;
gLLnnXXVZ(vector O1,vector D1,vector O2,vector D2){
    vector nO1 = < O1*D1, O1*D2, 0>;
    vector nO2 = < O2*D1, O2*D2, 0>;
    vector nD1 = < D1*D1, O1*D2, 0>;
    vector nD2 = < O2*D1, O2*D2, 0>;
    
    float t = ( nD2.x*nD1.y - nD1.x*nD2.y );
    
    t = ( nD2.y*(nO1.x-nO2.x) - nD2.x*(nO1.y-nO2.y) ) / t;
    
    X1 = O1 + D1*t;
    X2 = X1 + CP(nD1,nD2);
    V1 = nD1%nD2;
    Z1 = llVecMag(V1);}
Input Description
vector O1 Origin of Line 1
vector D1 Direction of Line 1
vector O2 Origin of Line 2
vector D2 Direction of Line 2
Output Description
vector X1 Closest point on line 1 to line 2
vector X2 Closest point on line 2 to line 1
vector V1 Direction vector of line 1 to line 2
float Z1 Numerical distance of line 1 to line 2
Requirement
global vector X1
global vector X2
global vector V1
global float Z1
2D
By Nexii Malthus

Line and Point, Direction

Works out where point (X) is relative to the line of the segment (L0, L1).

float gLSPdir( vector L0, vector L1, vector X ){
    return (L1.x - L0.x)*(X.y - L0.y) - (X.x - L0.x)*(L1.y - L0.y);
}
Input Description
vector L0, vector L1 Start and End of line segment
vector X Origin of Point
Output Description
float isLeft( vector L0, vector L1, vector X ) Returns float, >0 is Left, 0 on Line, <0 is Right, according to line angle
2D
Copyright 2001, softSurfer (www.softsurfer.com) (Must accept License #2), LSL-Port By Nexii Malthus

Plane and Point, Distance

Finds distance of a point from a plane

float gPXdZ(vector Pn,float Pd,vector A){
    return A * Pn + Pd;}
Input Description
vector Pn Normal of Plane (unit vector)
float Pd Distance of Plane
vector A Origin of Point
Output Description
return float gPXdZ Returns Distance between plane and point
3D
By Nexii Malthus

Plane and Point, Vector

Finds vector that points from point to nearest on plane

vector gPXdV(vector Pn,float Pd,vector A){
    return -(Pn * A + Pd)*Pn;}
Input Description
vector Pn Normal of Plane (unit vector)
float Pd Distance of Plane
vector A Origin of Point
Output Description
return vector gPXdV Returns vector from point to closest point on plane
3D
By Nexii Malthus

Plane and Point, Nearest point

Finds closest point on plane given point

vector gPXnX(vector Pn,float Pd,vector A){
    return A - (Pn * A + Pd) * Pn;}
Input Description
vector Pn Normal of Plane (unit vector)
float Pd Distance of Plane
vector A Origin of Point
Output Description
return vector gPXnX Returns vector of a point from closest of point to plane
3D
By Nexii Malthus

Plane and Ray, Intersection Distance

Finds distance to intersection of plane along ray

float gPRxZ(vector Pn,float Pd,vector O,vector D){
    return -((Pn*O+Pd)/(Pn*D));}
Input Description
vector Pn Normal of Plane (unit vector)
float Pd Distance of Plane
vector O Origin of Ray
vector D Direction of Ray
Output Description
return float gPRxZ Returns float distance of intersection between ray and plane
3D
By Nexii Malthus

Plane and Ray, Vector

Finds distance vector along a ray to a plane

vector gPRdV(vector Pn,float Pd,vector O,vector D){
    return D * gPRxZ(Pn,Pd,O,D);}
Input Description
vector Pn Normal of Plane (unit vector)
float Pd Distance of Plane
vector O Origin of Ray
vector D Direction of Ray
Output Description
return vector gPRdV Returns vector along a ray to a plane
Requirement
function float gPRxZ(vector Pn,float Pd,vector O,vector D)
3D
By Nexii Malthus

Plane and Ray, Intersection Point

Finds intersection point along a ray to a plane

vector gPRxX(vector Pn,float Pd,vector O,vector D){
    return O + gPRdV(Pn,Pd,O,D);}
Input Description
vector Pn Normal of Plane (unit vector)
float Pd Distance of Plane
vector O Origin of Ray
vector D Direction of Ray
Output Description
return vector gPRxX Returns vector point of intersection between ray and plane
Requirement
function vector gPRdV(vector Pn,float Pd,vector O,vector D)
3D
By Nexii Malthus

Plane and Line, Intersection Point

Finds interesection point of a line and a plane

vector gPLxX(vector Pn,float Pd,vector O,vector D){
    return O + D*-( (Pn*O-Pd)/(Pn*D) );}
Input Description
vector Pn Normal of Plane (unit vector)
float Pd Distance of Plane
vector O Origin of Line
vector D Direction of Line
Output Description
return vector gPLxX Returns vector point of intersection between line and plane
3D
By Nexii Malthus

Plane and Plane, Intersection Line

Finds line of intersection of two planes

vector oO;vector oD;

gPPxL(vector Pn,float Pd,vector Qn,float Qd){
    oD = (Pn%Qn)/llVecMag(Pn%Qn);
    vector Cross = (Pn%Qn)%Pn;
    vector Bleh = (-Pd*Pn);
    oO = Bleh - (Qn*Cross)/(Qn*Bleh+Qd)*Cross/llVecMag(Cross);}
Input Description
vector Pn Normal of Plane 1 (unit vector)
float Pd Distance of Plane 1
vector Qn Normal of Plane 2 (unit vector)
float Qd Distance of Plane 2
Output Description
vector oO Intersection Line's origin
vector oD Intersection Line's direction
Requirement
global vector oO
global vector oD
3D
By Nexii Malthus

Plane and Ray, Projection

Projects a ray onto a plane

vector oO;vector oD;

gPRpR(vector Pn,float Pd,vector O,vector D){
    oO = O - (Pn * O + Pd) * Pn;
    vector t = llVecNorm( D - (Pn*((D*Pn)/(Pn*Pn))) );t = <1.0/t.x,1.0/t.y,1.0/t.z>;
    oD = Pn%t;}
Input Description
vector Pn Normal of Plane (unit vector)
float Pd Distance of Plane
vector O Origin of Ray
vector D Direction of Ray
Output Description
vector oO Projected Ray Origin
vector oD Projected Ray Direction
Requirement
global vector oO
global vector oD
3D
By Nexii Malthus

Sphere and Ray, Intersection Point

Finds intersection point of sphere and ray

vector gSRxX(vector Sp, float Sr, vector Ro, vector Rd){
    float t; Ro -= Sp;
    if(Rd == ZERO_VECTOR) return ZERO_VECTOR;
    
    float a = Rd * Rd;
    float b = 2 * Rd * Ro;
    float c = (Ro * Ro)  - (Sr * Sr);
    
    float disc = b * b - 4 * a * c;
    
    if(disc < 0) return ZERO_VECTOR;
    
    float distSqrt = llSqrt(disc);
    float q;
    
    if(b < 0)
        q = (-b - distSqrt)/2.0;
    else 
        q = (-b + distSqrt)/2.0;
    
    float t0 = q / a;
    float t1 = c / q;
    
    if(t0 > t1){
        float temp = t0;
        t0 = t1;
        t1 = temp;
    }
    
    if(t1 < 0) return ZERO_VECTOR;
    
    if(t0 < 0)
        t = t1;
    else
        t = t0;
    
    return Sp + Ro + (t * Rd);
}
Input Description
vector Sp Origin of Sphere
float Sr Radius of Sphere
vector Ro Origin of Ray
vector Rd Direction of Ray
Output Description
vector gSRxX Returns intersection point of sphere and ray otherwise ZERO_VECTOR
3D
By Nexii Malthus

Sphere and Ray, Intersection Boolean

Finds if there is a intersection of sphere and ray

integer gSRx(vector Sp, float Sr, vector Ro, vector Rd){
    float t;Ro = Ro - Sp;
    //vector RayOrg = llDetectedPos(x) - llGetPos();
    if(Rd == ZERO_VECTOR) return FALSE;
    
    float a = Rd * Rd;
    float b = 2 * Rd * Ro;
    float c = (Ro * Ro)  - (Sr * Sr);
    
    float disc = b * b - 4 * a * c;
    
    if(disc < 0) return FALSE;
    return TRUE;
}
Input Description
vector Sp Origin of Sphere
float Sr Radius of Sphere
vector Ro Origin of Ray
vector Rd Direction of Ray
Output Description
integer gSRx Returns a boolean indicating if there is a valid intersection
3D
By Nexii Malthus

Ray and Point, projected distance

Finds projected distance of a point along a ray

float gRXpZ(vector O,vector D,vector A){
    return (A-O)*D;}
Input Description
vector O Origin of Ray
vector D Direction of Ray
vector A Origin of Point
Output Description
float gRXpZ Returns projected distance of a point along a ray
3D
By Nexii Malthus

Box and Ray, Intersection Distance

Finds intersection of a Ray to a Box and returns intersection distance, otherwise -1 if there is no legal intersection.

float gBRxZ(vector Ro,vector Rd, vector Bo, vector Bs, rotation Br){
    vector oB = (Ro-Bo)/Br;    vector dB = Rd/Br;    vector eB = 0.5*Bs;
    float mD = -1.0;    float D;    vector X;
    
    if(llFabs(dB.x) > 0.000001){
        D = (-eB.x - oB.x ) / dB.x;
        if(D >= 0.0){
            X = oB + D * dB;
            if(X.y >= -eB.y && X.y <= eB.y && X.z >= -eB.z && X.z <= eB.z)
                mD = D;
        }
        D = ( eB.x - oB.x ) / dB.x;
        if (D >= 0.0){
            X = oB + D * dB;
            if(X.y >= -eB.y && X.y <= eB.y && X.z >= -eB.z && X.z <= eB.z) 
                if (mD < 0.0 || mD > D)
                    mD = D;
        }
    }
    
    if(llFabs(dB.y) > 0.000001){
        D = (-eB.y - oB.y ) / dB.y;
        if(D >= 0.0){
            X = oB + D * dB;
            if(X.x >= -eB.x && X.x <= eB.x && X.z >= -eB.z && X.z <= eB.z)
                if (mD < 0.0 || mD > D)
                    mD = D;
        }
        D = ( eB.y - oB.y ) / dB.y;
        if (D >= 0.0){
            X = oB + D * dB;
            if(X.x >= -eB.x && X.x <= eB.x && X.z >= -eB.z && X.z <= eB.z)
                if (mD < 0.0 || mD > D)
                    mD = D;
        }
    }
    
    if(llFabs(dB.z) > 0.000001){
        D = (-eB.z - oB.z ) / dB.z;
        if(D >= 0.0){
            X = oB + D * dB;
            if(X.x >= -eB.x && X.x <= eB.x && X.y >= -eB.y && X.y <= eB.y)
                if (mD < 0.0 || mD > D)
                    mD = D;
        }
        D = ( eB.z - oB.z ) / dB.z;
        if (D >= 0.0){
            X = oB + D * dB;
            if(X.x >= -eB.x && X.x <= eB.x && X.y >= -eB.y && X.y <= eB.y)
                if (mD < 0.0 || mD > D)
                    mD = D;
        }
    }
    
    return mD;
}
Input Description
vector Ro Origin of Ray
vector Rd Direction of Ray
vector Bo Origin of Box
vector Bs Size of Box
rotation Br Rotation of Box
Output Description
float gBRxZ Returns distance to intersection of a ray and a box
3D

Box and Ray, Intersection Point

Finds intersection of a Ray to a Box and returns intersection point, otherwise ZERO_VECTOR if there is no legal intersection.

vector gBRxX( vector Ro, vector Rd, vector Bo, vector Bs, rotation Br){
    float k = gBRxZ(Ro,Rd,Bo,Bs,Br);
    if( k != -1.0 ) return Ro + Rd * k;
    else return ZERO_VECTOR;}
Input Description
vector Ro Origin of Ray
vector Rd Direction of Ray
vector Bo Origin of Box
vector Bs Size of Box
rotation Br Rotation of Box
Output Description
vector gBRxX Returns point of intersection of a ray and a box
Requirement
float gBRxZ(vector Ro,vector Rd, vector Bo, vector Bs, rotation Br)
3D

Box and Point, Intersection Boolean

Finds if there is an intersection of a Point and a Box and returns boolean

integer gBXx(vector A, vector Bo, vector Bs, rotation Br){
    vector eB = 0.5*Bs; vector rA = (A-Bo)/Br;
    return (rA.x<eB.x && rA.x>-eB.x && rA.y<eB.y && rA.y>-eB.y && rA.z<eB.z && rA.z>-eB.z); }
Input Description
vector A Origin of Point
vector Bo Origin of Box
vector Bs Size of Box
rotation Br Rotation of Box
Output Description
integer gBXx(vector A, vector Bo, vector Bs, rotation Br) Returns boolean check of intersection of a point and a box if there is one, otherwise FALSE
3D
By Nexii Malthus

Box and Point, Nearest Point on Edge

Processes point on nearest edge of box to given point

vector gBXnEX(vector A, vector Bo, vector Bs, rotation Br){
    vector eB = 0.5*<llFabs(Bs.x),llFabs(Bs.y),llFabs(Bs.z)>;
    vector rA = (A-Bo)/Br;
    
    float mD = 3.402823466E+38;
    vector X;
    list EdgesX = [< 0, eB.y, eB.z>, < 0,-eB.y, eB.z>, < 0,-eB.y,-eB.z>, < 0, eB.y,-eB.z>];
    list EdgesY = [< eB.x, 0, eB.z>, <-eB.x, 0, eB.z>, <-eB.x, 0,-eB.z>, < eB.x, 0,-eB.z>];
    list EdgesZ = [< eB.x, eB.y, 0>, <-eB.x, eB.y, 0>, <-eB.x,-eB.y, 0>, < eB.x,-eB.y, 0>];
    
    integer x = (EdgesX != []);
    while( x-- ){
        float y = gLXdZ( llList2Vector( EdgesX, x ), <1,0,0>, rA );
        
        if( rA.x > eB.x ) y += rA.x - eB.x;
        else if( rA.x < -eB.x ) y -= rA.x - -eB.x;
        
        if( y < mD ){ mD = y; X = gLXnX( llList2Vector( EdgesX, x ), <1,0,0>, rA ); }
    }
    x = (EdgesY != []);
    while( x-- ){
        float y = gLXdZ( llList2Vector( EdgesY, x ), <0,1,0>, rA );
        
        if( rA.y > eB.y ) y += rA.y - eB.y;
        else if( rA.y < -eB.y ) y -= rA.y - -eB.y;
        
        if( y < mD ){ mD = y; X = gLXnX( llList2Vector( EdgesY, x ), <0,1,0>, rA ); }
    }
    x = (EdgesZ != []);
    while( x-- ){
        float y = gLXdZ( llList2Vector( EdgesZ, x ), <0,0,1>, rA );
        
        if( rA.z > eB.z ) y += rA.z - eB.z;
        else if( rA.z < -eB.z ) y -= rA.z - -eB.z;
        
        if( y < mD ){ mD = y; X = gLXnX( llList2Vector( EdgesZ, x ), <0,0,1>, rA ); }
    }
    
    if( mD < 0.000001 ) return <-1,-1,-1>;
    if(      X.x >  eB.x ) X.x =  eB.x;
    else if( X.x < -eB.x ) X.x = -eB.x;
    if(      X.y >  eB.y ) X.y =  eB.y;
    else if( X.y < -eB.y ) X.y = -eB.y;
    if(      X.z >  eB.z ) X.z =  eB.z;
    else if( X.z < -eB.z ) X.z = -eB.z;
    
    return Bo + ( X * Br );}
Input Description
vector A Origin of Point
vector Bo Origin of Box
vector Bs Size of Box
rotation Br Rotation of Box
Output Description
vector gBXnEX(vector A, vector Bo, vector Bs, rotation Br) Returns nearest point on edge of box B closest to point A. Returns <-1,-1,-1> if already on closest point.
Requirement
float gLXdZ(vector O,vector D,vector A)
vector gLXdV(vector O,vector D,vector A)
vector gLXnX(vector O,vector D,vector A)
3D
By Nexii Malthus

Cylinder and Point, Intersection Boolean

Finds if there is an intersection of a Point and a Cylinder and returns boolean

integer gCXx( vector A, vector O, rotation R, vector S ) {
    A = ( A - O ) / R;// Converts to local object frame
    return (llPow(A.x/S.x*2,2) + llPow(A.y/S.y*2,2)) <= 1. // Test radius
        && llFabs(A.z/S.z*2) <= 1.;// Test top/bottom
}
Input Description
vector A Origin of Point
vector Bo Origin of Cylinder
vector Bs Size of Cylinder
rotation Br Rotation of Cylinder
Output Description
integer gCXx( vector A, vector O, rotation R, vector S ) Returns boolean check of intersection of a point and a cylinder if there is one, otherwise FALSE
3D
By Nexii Malthus


Polygon and Point, Intersection Boolean

Figures out if point is inside of polygon or otherwise.

integer gCPXx( list CP, vector X )
{//Copyright (c) 1970-2003, Wm. Randolph Franklin; 2008, Strife Onizuka
    integer i = ~(CP != []);
    integer c = 0;
    if(i < -2){
        vector vi = llList2Vector(CP, -1);
        do {
            vector vj = vi;
            vi = llList2Vector(CP, i);
            if((vi.y > X.y) ^ (vj.y > X.y)){
                if(vj.y != vi.y)
                    c = c ^ (X.x < (((vj.x - vi.x) * (X.y - vi.y) / (vj.y - vi.y)) + vi.x));
                else c = c ^ (0 < ((vj.x-vi.x) * (X.y-vi.y)));
            }
        } while (++i);
    }
    return c;
}
Input Description
list CP Vertices of Concave Polygon
vector X Origin of Point
Output Description
integer gCPXx( list CP, vector X ) Returns TRUE if point (X) intersects concave polygon (CP), otherwise FALSE
2D
Copyright (c) 1970-2003, Wm. Randolph Franklin (Must accept License #1), LSL-Port By Strife Onizuka

Polygon and Line Segment, Intersection Boolean

Figures out if line segment intersects with polygon.

integer gVPLSx( vector P0, vector P1, list VP ){
    //Copyright 2001, softSurfer (www.softsurfer.com); 2008, Nexii Malthus
    if( P0 == P1 ) return gCPXx( VP, P0 );
    float tE = 0; float tL = 1;
    float t; float N; float D;
    vector dS = P1 - P0;
    vector e; integer x; integer y = VP!=[];
    @start;
    for( x = 0; x < y; ++x ){
        e = llList2Vector( VP, x+1 ) - llList2Vector( VP, x );
        N = Perp( e, P0 - llList2Vector( VP, x ) );
        D = -Perp( e, dS );
        if( llFabs(D) < 0.00000001 )
            if( N < 0 ) return FALSE;
            else jump start;
        t = N / D;
        if( D < 0 ){
            if( t > tE ){   tE = t; if( tE > tL ) return FALSE;     }
        } else {
            if( t < tL ){   tL = t; if( tL < tE ) return FALSE;     }
    }   }
    // PointOfEntrance = P0 + tE * dS;
    // PointOfExit = P0 + tL * dS;
    return TRUE;
}
Input Description
list VP Vertices of Convex Polygon
vector P0, vector P1 Start and End of Line Segment
Output Description
integer gVPLSx( vector P0, vector P1, list VP ) Returns TRUE if line segment (P0,P1) intersects convex polygon (VP), otherwise FALSE
Requirement
float Perp( vector U, vector V ){ return U.x*V.y - U.y*V.x; }
Perpendicular dot product
integer gCPXx( list CP, vector X ) Only needed for (P0 == P1) safety catch check, so optional
2D
Copyright 2001, softSurfer (www.softsurfer.com) (Must accept License #2), LSL-Port By Nexii Malthus

3D Projection

Projects a vector A by vector B.

vector Project3D(vector A,vector B){
    return B * ( ( A * B ) / ( B * B ) );}
Input Description
vector A First Vector
vector B Second Vector
Output Description
return Project3D(vector A, vector B) Returns result of projection
3D
By Nexii Malthus

Reflection

Reflects Ray R with surface normal N

vector Reflect(vector R,vector N){
    return R - 2 * N * ( R * N );}
Input Description
vector R Ray Normal
vector N Surface Normal
Output Description
return Reflect(vector R, vector N) Returns result of reflection
3D
By Nexii Malthus

For anyone curious to the shorthand used and who wish to use a lookup table can use this as a reference. Or anyone who wishes to add a new function to the library is welcome to but it would be recommended to keep consistency. I tried to minimize the script function names to be easily readable. All the geometric function names start with a g.

g (Shape1) (Shape2) (Process) (Return (Only needed if other than integer))

Here is the legend:

Shorthand Name Description
Geometric Types, all the shapes in the library
X Point vector defining a point in space
L Line A line has an origin and a direction and is infinitely long
LS Line Segment A line segment is a finite line and therefore consists of a start and end position
R Ray A ray is like a line, except it is more distinct as it defines wether it points forward or back
P Plane A 2D doubly ruled surface of infinite size
S Sphere A sphere is defined by origin and radius (No ellipsoid functions available yet)
B Box A box primitive is six sided and defined by origin, size as well as a rotation.
C Cylinder An elliptic cylinder primitive .
VP Convex Polygon Convex Polygon defined by list of vertices.
CP Concave Polygon Concave Polygon defined by list of vertices. Automatic backward compatibility with Convex Polygons.
The Process, What does it do?
d distance Calculate distance
n nearest Calculate nearest
p project Calculates projection
x Intersection Calculates intersection
dir direction Calculates direction
Return, What kind of data do I get out of it?
Z Float Represents that a float is returned
V Vector Represents that a vector is returned
O Origin Represents the Origin of the ray or line
D Direction Direction from the Origin
E Edge Edge of a shape, such as an edge on a box, suffix may mark special case return type

#1

//Copyright (c) 1970-2003, Wm. Randolph Franklin
//Copyright (c) 2008, Strife Onizuka (porting to LSL)
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimers.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice in the documentation and/or other materials provided with the
//    distribution.
// 3. The name of W. Randolph Franklin may not be used to endorse or promote
//    products derived from this Software without specific prior written
//    permission. 
 
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.

#2

// Copyright 2001, softSurfer (www.softsurfer.com); 2008, LSL-port by Nexii Malthus
// This code may be freely used and modified for any purpose
// providing that this copyright notice is included with it.
// SoftSurfer makes no warranty for this code, and cannot be held
// liable for any real or imagined damage resulting from its use.
// Users of this code must verify correctness for their application.