Geometric
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
Documentation
Line Functions
Line Nearest Point | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Calculates the vector from a point to the closest point on a line <lsl> vector gLXdV(vector O,vector D,vector A){ return (O-A)-((O-A)*D)*D;} </lsl>
By Nexii Malthus
|
Line Nearest Point, Distance | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Calculates distance of this vector, but faster on it's own <lsl> float gLXdZ(vector O,vector D,vector A){ return llSqrt(CP((A-O),D)*CP((A-O),D));} </lsl>
By Nexii Malthus
|
Line and Line, Vector | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Shortest vector of two lines <lsl> vector gLLdV(vector O1,vector D1,vector O2,vector D2){ return Project3D( (O2-O1), CP(D1,D2) );} </lsl>
By Nexii Malthus
|
Line and Line, Distance | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Returns the distance between two lines <lsl> float gLLdZ(vector O1,vector D1,vector O2,vector D2){ vector A = CP(D1,D2);float B = llVecMag(A);A = <A.x/B,A.y/B,A.z/B>; return (O2-O1) * A;} </lsl>
By Nexii Malthus
|
Line and Line, Nearest point | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Closest point of two lines <lsl> 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;} </lsl>
By Nexii Malthus
|
Line and Line, two nearest points along both lines | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Two closest points of two lines on each line <lsl> 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 + CP(nD1,nD2);} </lsl>
By Nexii Malthus
|
Line and Line, two nearest points with vector and distance | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Computes two closest points of two lines, vector and distance <lsl> 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 = CP(nD1,nD2); Z1 = llVecMag(V1);} </lsl>
By Nexii Malthus
|
Plane Functions
Plane and Point, Distance | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Finds distance of a point from a plane <lsl> float gPXdZ(vector Pn,float Pd,vector A){ return A * Pn + Pd;} </lsl>
By Nexii Malthus
|
Plane and Point, Vector | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Finds vector that points from point to nearest on plane <lsl> vector gPXdV(vector Pn,float Pd,vector A){ return -(Pn * A + Pd)*Pn;} </lsl>
By Nexii Malthus
|
Plane and Point, Nearest point | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Finds closest point on plane given point <lsl> vector gPXnX(vector Pn,float Pd,vector A){ return A - (Pn * A + Pd) * Pn;} </lsl>
By Nexii Malthus
|
Plane and Ray, Intersection Distance | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Finds distance to intersection of plane along ray <lsl> float gPRxZ(vector Pn,float Pd,vector O,vector D){ return -( ( (Pn*D)+(Pn*O) ) / (Pn*D) );} </lsl>
By Nexii Malthus
|
Plane and Ray, Vector | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Finds distance vector along a ray to a plane <lsl> vector gPRdV(vector Pn,float Pd,vector O,vector D){ return D * gPRxZ(Pn,Pd,O,D);} </lsl>
By Nexii Malthus
|
Plane and Ray, Intersection Point | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Finds intersection point along a ray to a plane <lsl> vector gPRxX(vector Pn,float Pd,vector O,vector D){ return O + gPRdV(Pn,Pd,O,D);} </lsl>
By Nexii Malthus
|
Plane and Line, Intersection Point | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Finds interesection point of a line and a plane <lsl> vector gPLxX(vector Pn,float Pd,vector O,vector D){ return O -( (Pn*D)/(Pn*O+Pd) )*D;} </lsl>
By Nexii Malthus
|
Plane and Plane, Intersection Line | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Finds line of intersection of two planes <lsl> vector oO;vector oD; gPPxL(vector Pn,float Pd,vector Qn,float Qd){ oD = CP(Pn,Qn)/llVecMag(CP(Pn,Qn)); vector Cross = CP(CP(Pn,Qn),Pn); vector Bleh = (-Pd*Pn); oO = Bleh - (Qn*Cross)/(Qn*Bleh+Qd)*Cross/llVecMag(Cross);} </lsl>
By Nexii Malthus
|
Plane and Ray, Projection | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Projects a ray onto a plane <lsl> vector oO;vector oD; gPRpR(vector Pn,float Pd,vector O,vector D){ oO = O - (Pn * O + Pd) * Pn; vector t = llVecNorm( D - Project3D(D,Pn) );t = <1.0/t.x,1.0/t.y,1.0/t.z>; oD = CP(Pn,t);} </lsl>
By Nexii Malthus
|
Sphere Functions
Sphere and Ray, Intersection Point | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Finds intersection point of sphere and ray <lsl> vector gSRxX(vector Sp, float Sr, vector Ro, vector Rd){ float t;Ro = 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 Ro + (t * Rd); } </lsl>
By Nexii Malthus
|
Sphere and Ray, Intersection Boolean | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Finds if there is a intersection of sphere and ray <lsl> 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; } </lsl>
By Nexii Malthus
|
Ray Functions
Ray and Point, projected distance | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
Finds projected distance of a point along a ray <lsl> float gRXpZ(vector O,vector D,vector A){ return (A-O)*D;} </lsl>
By Nexii Malthus
|
Geometric Library Code
Legend
I tried to minimize the script function names to be easily readable. All the geometric function names start with a g. Please note, Nexii Malthus is no maths professor and so one or two functions might not work as expected.
Here is the legend:
Shorthand | Name | Description |
---|---|---|
X | Point | vector defining a point in space |
L | Line | A line has an origin and a direction |
R | Ray | A ray is like a line, except it is more distinct as it can define weather it points forward or back |
P | Plane | A two dimensional doubly ruled surface of infinite size |
S | Sphere | A sphere is defined by origin and radius |
d | Distance | Calculate distance |
n | Nearest | Calculate nearest |
p | Project | Calculates projection |
x | Intersection | Calculates intersection |
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 |
LSL Script
This is the script in its entirety. <lsl>//===================================================// // Geometric Library 1.0 // // "May 4 2008", "2:24:30" // // Copyright (C) 2008, Nexii Malthus (cc-by) // // http://creativecommons.org/licenses/by/3.0/ // //===================================================//
vector CP(vector A,vector B){
return A % B;}
vector Project3D(vector A,vector B){
vector proj; proj.x = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.x; proj.y = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.y; proj.z = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.z; return proj;}
// POINT // float gXXdZ(vector A,vector B){
// Distance P2P. return llVecDist(A,B);}
vector gXXdV(vector A,vector B){
// Vector to move from P2P. return A-B;}
// LINE // vector gLXdV(vector O,vector D,vector A){
// Calculates the vector from a point to the closest point on a line return (O-A)-((O-A)*D)*D;}
float gLXdZ(vector O,vector D,vector A){
// Calculates distance of this vector, but faster on it's own return llSqrt(CP((A-O),D)*CP((A-O),D));}
vector gLLdV(vector O1,vector D1,vector O2,vector D2){
// Shortest vector of two lines return Project3D( (O2-O1), CP(D1,D2) );}
float gLLdZ(vector O1,vector D1,vector O2,vector D2){
// Returns the distance between two lines vector A = CP(D1,D2);float B = llVecMag(A);A = <A.x/B,A.y/B,A.z/B>; return (O2-O1) * A;}
vector gLLnX(vector O1,vector D1,vector O2,vector D2){
// Closest point of two lines 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;}
vector X1;vector X2;vector V1;float Z1;
gLLnnXX(vector O1,vector D1,vector O2,vector D2){
// Two closest points of two lines 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);}
gLLnnXXVZ(vector O1,vector D1,vector O2,vector D2){
// Computes two closest points of two lines, vector and distance 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 = CP(nD1,nD2); Z1 = llVecMag(V1);}
// PLANE // float gPXdZ(vector Pn,float Pd,vector A){
// Finds distance of a point from a plane return A * Pn + Pd;}
vector gPXdV(vector Pn,float Pd,vector A){
// Finds vector that points from point to nearest on plane return -(Pn * A + Pd)*Pn;}
vector gPXnX(vector Pn,float Pd,vector A){
// Finds closest point on plane given point return A - (Pn * A + Pd) * Pn;}
float gPRxZ(vector Pn,float Pd,vector O,vector D){
// Finds distance to intersection of plane along ray return -( ( (Pn*D)+(Pn*O) ) / (Pn*D) );} //return -( (Pn*D)/(Pn*O+Pd) );}
vector gPRdV(vector Pn,float Pd,vector O,vector D){
// Finds distance vector along a ray to a plane return D * gPRxZ(Pn,Pd,O,D);} //return -( (Pn*D)/(Pn*O+Pd) )*D;}
vector gPRxX(vector Pn,float Pd,vector O,vector D){
// Finds intersection point along a ray to a plane return O + gPRdV(Pn,Pd,O,D);}
vector gPLxX(vector Pn,float Pd,vector O,vector D){
// Finds interesection point of a line and a plane return O -( (Pn*D)/(Pn*O+Pd) )*D;}
vector oO;vector oD;
gPPxL(vector Pn,float Pd,vector Qn,float Qd){
// Finds line of intersection of two planes oD = CP(Pn,Qn)/llVecMag(CP(Pn,Qn)); vector Cross = CP(CP(Pn,Qn),Pn); vector Bleh = (-Pd*Pn); oO = Bleh - (Qn*Cross)/(Qn*Bleh+Qd)*Cross/llVecMag(Cross);}
gPRpR(vector Pn,float Pd,vector O,vector D){
// Projects a ray onto a plane oO = O - (Pn * O + Pd) * Pn; vector t = llVecNorm( D - Project3D(D,Pn) );t = <1.0/t.x,1.0/t.y,1.0/t.z>; oD = CP(Pn,t);}
// SPHERE // vector gSRxX(vector Sp, float Sr, vector Ro, vector Rd){
float t;Ro = Ro - Sp; //vector RayOrg = llDetectedPos(x) - llGetPos(); 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 Ro + (t * Rd);
}
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;
}
// RAY // float gRXpZ(vector O,vector D,vector A){
// Finds projected distance of a point along a ray return (A-O)*D;}
vector gRZiX(vector O,vector D,float z){
return O+z*D;}
// OTHER // vector pN;float pD; gTiP(vector p1,vector p2,vector p3){
// Turns three vector points in space into a plane pN = llVecNorm( CP((p2-p1),(p3-p1)) ); pD = -p1*pN;}
integer gTXcC(vector p1,vector p2,vector p3,vector x){
// Can be used to check weather a point is inside a triangle gTiP(p1,p2,p3); vector Vn;vector En; Vn = p1 - x; En = CP((p2-p1),pN); if( ((p1-x)*CP(p2-p1,pN) >= 0)&&((p2-x)*CP(p3-p2,pN) >= 0)&&((p3-x)*CP(p1-p3,pN) >= 0) ) return TRUE; return FALSE;}
integer gTVXcC(vector p1,vector p2,vector p3,vector v,vector x){
if( ((p1-x)*CP(p2-p1,v) >= 0)&&((p2-x)*CP(p3-p2,v) >= 0)&&((p3-x)*CP(p1-p3,v) >= 0) ) return TRUE; return FALSE;}
integer gTRcC(vector p1,vector p2,vector p3,vector O,vector D){
return gTVXcC(p1,p2,p3,O,D);}
default{state_entry(){}}
</lsl>
Expanded Library
I was informed by Strife that shorthand one/two letter variable names is out of fashion these days, so it's up to the opinion of the reader if they really think this is cleaner and can now choose from two versions.
<lsl> //===================================================// // Geometric Library 1.0 // // "May 4 2008", "2:24:30" // // Copyright (C) 2008, Nexii Malthus (cc-by) // // http://creativecommons.org/licenses/by/3.0/ // //===================================================//
vector CrossProduct(vector Point1,vector Point2){
return Point1 % Point2;}
vector Project3D(vector A,vector B){
vector proj; proj.x = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.x; proj.y = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.y; proj.z = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.z; return proj;}
// POINT float gPoint2Point_Distance_Float(vector Point1,vector Point2){
// Distance P2P. return llVecDist(Point1,Point2);}
vector gPoint2Point_Distance_Vector(vector Point1,vector Point2){
// Vector to move from P2P. return Point1-Point2;}
// LINE vector gLine2Point_Distance_Vector(vector LineOrigin,vector LineDirection,vector Point){
// Calculates the vector from a point to the closest point on a line return (LineOrigin-Point)-((LineOrigin-Point)*LineDirection)*LineDirection;}
float gLine2Point_Distance_Float(vector LineOrigin,vector LineDirection,vector Point){
// Calculates distance of this vector, but faster on it's own return llSqrt(CrossProduct((Point-LineOrigin),LineDirection)*CrossProduct((Point-LineOrigin),LineDirection));}
vector gLine2Line_Distance_Vector(vector LineOrigin1,vector LineDirection1,vector LineOrigin2,vector LineDirection2){
// Shortest vector of two lines return Project3D( (LineOrigin2-LineOrigin1), CrossProduct(LineDirection1,LineDirection2) );}
float gLine2Line_Distance_Float(vector LineOrigin1,vector LineDirection1,vector LineOrigin2,vector LineDirection2){
// Returns the distance between two lines vector A = CrossProduct(LineDirection1,LineDirection2);float B = llVecMag(A);A = <A.x/B,A.y/B,A.z/B>; return (LineOrigin2-LineOrigin1) * A;}
vector gLine2Line_Nearest_Point(vector LineOrigin1,vector LineDirection1,vector LineOrigin2,vector LineDirection2){
// Closest point of two lines vector nearestOrigin1 = < LineOrigin1*LineDirection1, LineOrigin1*LineDirection2, 0>; vector nearestOrigin2 = < LineOrigin2*LineDirection1, LineOrigin2*LineDirection2, 0>; vector nearestDirection1 = < LineDirection1*LineDirection1, LineOrigin1*LineDirection2, 0>; vector nearestDirection2 = < LineOrigin2*LineDirection1, LineOrigin2*LineDirection2, 0>; float t = ( nearestDirection2.x*nearestDirection1.y - nearestDirection1.x*nearestDirection2.y ); t = ( nearestDirection2.y*(nearestOrigin1.x-nearestOrigin2.x) - nearestDirection2.x*(nearestOrigin1.y-nearestOrigin2.y) ) / t; return LineOrigin1 + LineDirection1*t;}
vector outPoint1;vector outPoint2;vector outVector1;float outFloat1;
gLine2Line_Nearest_Two_Points(vector LineOrigin1,vector LineDirection1,vector LineOrigin2,vector LineDirection2){
// Two closest points of two lines vector nearestOrigin1 = < LineOrigin1*LineDirection1, LineOrigin1*LineDirection2, 0>; vector nearestOrigin2 = < LineOrigin2*LineDirection1, LineOrigin2*LineDirection2, 0>; vector nearestDirection1 = < LineDirection1*LineDirection1, LineOrigin1*LineDirection2, 0>; vector nearestDirection2 = < LineOrigin2*LineDirection1, LineOrigin2*LineDirection2, 0>; float t = ( nearestDirection2.x*nearestDirection1.y - nearestDirection1.x*nearestDirection2.y ); t = ( nearestDirection2.y*(nearestOrigin1.x-nearestOrigin2.x) - nearestDirection2.x*(nearestOrigin1.y-nearestOrigin2.y) ) / t; outPoint1 = LineOrigin1 + LineDirection1*t; outPoint2 = outPoint1 + CrossProduct(nearestDirection1,nearestDirection2);}
gLine2Line_Nearest_Two_Points_Vector_Distance(vector LineOrigin1,vector LineDirection1,vector LineOrigin2,vector LineDirection2){
// Computes two closest points of two lines, vector and distance vector nearestOrigin1 = < LineOrigin1*LineDirection1, LineOrigin1*LineDirection2, 0>; vector nearestOrigin2 = < LineOrigin2*LineDirection1, LineOrigin2*LineDirection2, 0>; vector nearestDirection1 = < LineDirection1*LineDirection1, LineOrigin1*LineDirection2, 0>; vector nearestDirection2 = < LineOrigin2*LineDirection1, LineOrigin2*LineDirection2, 0>; float t = ( nearestDirection2.x*nearestDirection1.y - nearestDirection1.x*nearestDirection2.y ); t = ( nearestDirection2.y*(nearestOrigin1.x-nearestOrigin2.x) - nearestDirection2.x*(nearestOrigin1.y-nearestOrigin2.y) ) / t; outPoint1 = LineOrigin1 + LineDirection1*t; outPoint2 = outPoint1 + CrossProduct(nearestDirection1,nearestDirection2); outVector1 = CrossProduct(nearestDirection1,nearestDirection2); outFloat1 = llVecMag(outVector1);}
// PLANE float gPlane2Point_Distance_Float(vector PlaneNormal,float PlaneDistance,vector A){
// Finds distance of a point from a plane return A * PlaneNormal + PlaneDistance;}
vector gPlane2Point_Distance_Vector(vector PlaneNormal,float PlaneDistance,vector A){
// Finds vector that points from point to nearest on plane return -(PlaneNormal * A + PlaneDistance)*PlaneNormal;}
vector gPlane2Point_Nearest_Point(vector PlaneNormal,float PlaneDistance,vector A){
// Finds closest point on plane given point return A - (PlaneNormal * A + PlaneDistance) * PlaneNormal;}
float gPlane2Ray_Nearest_Float(vector PlaneNormal,float PlaneDistance,vector RayOrigin,vector RayDirection){
// Finds distance to intersection of plane along ray return -( ( (PlaneNormal*RayDirection)+(PlaneNormal*RayOrigin) ) / (PlaneNormal*RayDirection) );}
vector gPlane2Ray_Distance_Vector(vector PlaneNormal,float PlaneDistance,vector RayOrigin,vector RayDirection){
// Finds distance vector along a ray to a plane return RayDirection * gPlane2Ray_Nearest_Float(PlaneNormal,PlaneDistance,RayOrigin,RayDirection);}
vector gPlane2Ray_Intersection_Point(vector PlaneNormal,float PlaneDistance,vector RayOrigin,vector RayDirection){
// Finds intersection point along a ray to a plane return RayOrigin + gPlane2Ray_Distance_Vector(PlaneNormal,PlaneDistance,RayOrigin,RayDirection);}
vector gPlane2Line_Intersection_Point(vector PlaneNormal,float PlaneDistance,vector LineOrigin,vector LineDirection){
// Finds interesection point of a line and a plane return LineOrigin -( (PlaneNormal*LineDirection)/(PlaneNormal*LineOrigin+PlaneDistance) )*LineDirection;}
vector outLineOrigin;vector outLineDirection;
gPlane2Plane_Intersection_Line(vector PlaneA_Normal,float PlaneA_Distance,vector PlaneB_Normal,float PlaneB_Distance){
// Finds line of intersection of two planes outLineDirection = CrossProduct(PlaneA_Normal,PlaneB_Normal)/llVecMag(CrossProduct(PlaneA_Normal,PlaneB_Normal)); vector Cross = CrossProduct(CrossProduct(PlaneA_Normal,PlaneB_Normal),PlaneA_Normal); vector Bleh = (-PlaneA_Distance*PlaneA_Normal); outLineOrigin = Bleh - (PlaneB_Normal*Cross)/(PlaneB_Normal*Bleh+PlaneB_Distance)*Cross/llVecMag(Cross);}
float gRay2Point_Project_Float(vector RayOrigin,vector RayDirection,vector Projection){
// Finds projected distance of a point along a ray return (Projection-RayOrigin)*RayDirection;}
gPlane2Ray_Project_Ray(vector PlaneNormal,float PlaneDistance,vector RayOrigin,vector RayDirection){
// Projects a ray onto a plane outLineOrigin = RayOrigin - (PlaneNormal * RayOrigin + PlaneDistance) * PlaneNormal; vector t = llVecNorm( RayDirection - Project3D(RayDirection,PlaneNormal) );t = <1.0/t.x,1.0/t.y,1.0/t.z>; outLineDirection = CrossProduct(PlaneNormal,t);}
// SPHERE vector gSphere2Ray_Intersection_Point(vector SphereOrigin, float SphereRadius, vector RayOrigin, vector RayDirection){
float t;RayOrigin = RayOrigin - SphereOrigin; if(RayDirection == ZERO_VECTOR) return ZERO_VECTOR; float a = RayDirection * RayDirection; float b = 2 * RayDirection * RayOrigin; float c = (RayOrigin * RayOrigin) - (SphereRadius * SphereRadius); 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 RayOrigin + (t * RayDirection);
}
integer gSphere2Ray_Intersection(vector SphereOrigin, float SphereRadius, vector RayOrigin, vector RayDirection){
// IS there a intersection? float t;RayOrigin = RayOrigin - SphereOrigin; if(RayDirection == ZERO_VECTOR) return FALSE; float a = RayDirection * RayDirection; float b = 2 * RayDirection * RayOrigin; float c = (RayOrigin * RayOrigin) - (SphereRadius * SphereRadius); float disc = b * b - 4 * a * c; if(disc < 0) return FALSE; return TRUE;
}
// Other vector planeNormal;float planeDistance; gTriangle_into_Plane(vector p1,vector p2,vector p3){
planeNormal = llVecNorm( CrossProduct((p2-p1),(p3-p1)) ); planeDistance = -p1*planeNormal;}
integer gTriangle2Point_CheckCollision(vector p1,vector p2,vector p3,vector x){
gTriangle_into_Plane(p1,p2,p3); vector Vn;vector En; Vn = p1 - x; En = CrossProduct((p2-p1),planeNormal); if( ((p1-x)*CrossProduct(p2-p1,planeNormal) >= 0)&&((p2-x)*CrossProduct(p3-p2,planeNormal) >= 0)&&((p3-x)*CrossProduct(p1-p3,planeNormal) >= 0) ) return TRUE; return FALSE;}
integer gTVXcC(vector p1,vector p2,vector p3,vector v,vector x){
if( ((p1-x)*CrossProduct(p2-p1,v) >= 0)&&((p2-x)*CrossProduct(p3-p2,v) >= 0)&&((p3-x)*CrossProduct(p1-p3,v) >= 0) ) return TRUE; return FALSE;}
integer gTriangel2Ray_CheckCollision(vector p1,vector p2,vector p3,vector Origin,vector Direction){
return gTVXcC(p1,p2,p3,Origin,Direction);}
vector gRay2Float_into_Point(vector Origin,vector Direction,float Float){
return Origin+Float*Direction;}
default{state_entry(){}}
</lsl>
Optimized ESL
<lsl>//===================================================// // Geometric Library 1.0 Optimized ESL Build 1 // // "May 4 2008", "14:19:37" // // Copyright (C) 2008, Nexii Malthus (cc-by) // // Copyright (C) 2008, Strife Onizuka (cc-by) // // http://creativecommons.org/licenses/by/3.0/ // //===================================================//
- define CP(A, B) ((A) % (B))
- ifndef CP
vector CP(vector A,vector B){
return A % B;}
- endif
- if 0
vector Project3D(vector A,vector B){
vector proj; proj.x = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.x; proj.y = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.y; proj.z = ( (A*B) / (B.x*B.x + B.y*B.y + B.z*B.z) ) * B.z; return proj;}
- else
vector Project3D(vector A,vector B){
return B * ((A*B) / (B*B));}
- endif
// POINT
- define gXXdZ llVecDist
- ifndef gXXdZ
float gXXdZ(vector A,vector B){
// Distance P2P. return llVecDist(A,B);}
- endif
- define gXXdV(A,B) ((A) - (B))
- ifndef gXXdV
vector gXXdV(vector A,vector B){
// Vector to move from P2P. return A-B;}
- endif
// LINE
- if 0
vector gLXdV(vector O,vector D,vector A){
// Calculates the vector from a point to the closest point on a line return (O-A)-((O-A)*D)*D;}
- else
vector gLXdV(vector O,vector D,vector A){
// Calculates the vector from a point to the closest point on a line vector t = (O-A); return t - (t*D)*D;}
- endif
- define gLXdZ(O, D, A) llVecMag(CP((A-O),D))
- ifndef gLXdZ
float gLXdZ(vector O,vector D,vector A){
// Calculates distance of this vector, but faster on it's own return llVecMag(CP((A-O),D));}
- endif
- define gLLdV(O, D, A) Project3D( (O2-O1), CP(D1,D2) )
- ifndef gLLdV
vector gLLdV(vector O1,vector D1,vector O2,vector D2){
// Shortest vector of two lines return Project3D( (O2-O1), CP(D1,D2) );}
- endif
- define gLLdZ(O1, D1, O2, D2) ((O2-O1) * llVecNorm(CP(D1,D2)))
- ifndef gLLdZ
float gLLdZ(vector O1,vector D1,vector O2,vector D2){
// Returns the distance between two lines vector A = CP(D1,D2);float B = llVecMag(A);A = <A.x/B,A.y/B,A.z/B>; return (O2-O1) * A;}
- endif
- if 0
vector gLLnX(vector O1,vector D1,vector O2,vector D2){
// Closest point of two lines 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;}
- else
vector gLLnX(vector O1,vector D1,vector O2,vector D2){
// Closest point of two lines vector t = <O2*D1, O1*D2, O2*D2>; return O1 + D1 * (( t.z * ((O1*D1)-t.x) - t.x * (t.y-t.z) ) / ( t.x*t.y - (D1*D1)*t.z ));}
- endif
vector X1;vector X2;vector V1;float Z1;
- if 0
gLLnnXX(vector O1,vector D1,vector O2,vector D2){
// Two closest points of two lines 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);}
- else
gLLnnXX(vector O1,vector D1,vector O2,vector D2){
// Two closest points of two lines #define a (O1*D1) #define c (D1*D1) #define d (O2*D1) #define e (O1*D2) #define f (O2*D2) vector nD1 = < c, e, 0.0>; vector nD2 = < d, f, 0.0>; #undef c #undef d #undef e #undef f #define c nD1.x #define d nD2.x #define e nD1.y #define f nD2.y X2 = (X1 = (O1 + D1 * (( d*(a-d) - d*(e-f) ) / ( d*e - c*f )))) + CP(nD1,nD2);} #undef a #undef c #undef d #undef e #undef f
- endif
- if 0
gLLnnXXVZ(vector O1,vector D1,vector O2,vector D2){
// Computes two closest points of two lines, vector and distance 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 = CP(nD1,nD2); Z1 = llVecMag(V1);}
- else
gLLnnXXVZ(vector O1,vector D1,vector O2,vector D2){
// Computes two closest points of two lines, vector and distance #define a (O1*D1) #define c (D1*D1) #define d (O2*D1) #define e (O1*D2) #define f (O2*D2) vector nD1 = < c, e, 0.0>; vector nD2 = < d, f, 0.0>; #undef c #undef d #undef e #undef f #define c nD1.x #define d nD2.x #define e nD1.y #define f nD2.y X2 = (X1 = (O1 + D1 * (( f * (a-d) - d * (e-f) ) / ( d*e - c*f )))) + (V1 = (CP(nD1,nD2))); Z1 = llVecMag(V1);} #undef a #undef c #undef d #undef e #undef f
- endif
// PLANE
- define gPXdZ(Pn, Pd, A) ((A) * (Pn) + (Pd))
- ifndef gPXdZ
float gPXdZ(vector Pn,float Pd,vector A){
// Finds distance of a point from a plane return A * Pn + Pd;}
- endif
vector gPXdV(vector Pn,float Pd,vector A){
// Finds vector that points from point to nearest on plane return -(Pn * A + Pd)*Pn;}
vector gPXnX(vector Pn,float Pd,vector A){
// Finds closest point on plane given point return A - (Pn * A + Pd) * Pn;}
- if 0
float gPRxZ(vector Pn,float Pd,vector O,vector D){
// Finds distance to intersection of plane along ray return -( ( (Pn*D)+(Pn*O) ) / (Pn*D) );} //return -( (Pn*D)/(Pn*O+Pd) );}
- else
float gPRxZ(vector Pn,float Pd,vector O,vector D){
// Finds distance to intersection of plane along ray float a = (Pn*D); return -( ( a+(Pn*O) ) / a );} //return -( (Pn*D)/(Pn*O+Pd) );}
- endif
vector gPRdV(vector Pn,float Pd,vector O,vector D){
// Finds distance vector along a ray to a plane return D * gPRxZ(Pn,Pd,O,D);} //return -( (Pn*D)/(Pn*O+Pd) )*D;}
vector gPRxX(vector Pn,float Pd,vector O,vector D){
// Finds intersection point along a ray to a plane return O + gPRdV(Pn,Pd,O,D);}
vector gPLxX(vector Pn,float Pd,vector O,vector D){
// Finds interesection point of a line and a plane return O -( (Pn*D)/(Pn*O+Pd) )*D;}
vector oO;vector oD;
- if 0
gPPxL(vector Pn,float Pd,vector Qn,float Qd){
// Finds line of intersection of two planes oD = CP(Pn,Qn)/llVecMag(CP(Pn,Qn)); vector Cross = CP(CP(Pn,Qn),Pn); vector Bleh = (-Pd*Pn); oO = Bleh - (Qn*Cross)/(Qn*Bleh+Qd)*Cross/llVecMag(Cross);}
- else
gPPxL(vector Pn,float Pd,vector Qn,float Qd){
// Finds line of intersection of two planes vector a = CP(Pn,Qn); oD = llVecNorm(a); vector Cross = CP(a,Pn); vector Bleh = (-Pd*Pn); oO = Bleh - (Qn*Cross)/(Qn*Bleh+Qd)*llVecNorm(Cross);}
- endif
- define gRXpZ(O, D, A) (A-O)*D
- ifndef gRXpZ
float gRXpZ(vector O,vector D,vector A){
// Finds projected distance of a point along a ray return (A-O)*D;}
- endif
- if 0
gPRpR(vector Pn,float Pd,vector O,vector D){
// Projects a ray onto a plane oO = O - (Pn * O + Pd) * Pn; vector t = llVecNorm( D - Project3D(D,Pn) );t = <1.0/t.x,1.0/t.y,1.0/t.z>; oD = CP(Pn,t);}
- else
gPRpR(vector Pn,float Pd,vector O,vector D){
// Projects a ray onto a plane oO = O - (Pn * O + Pd) * Pn; O = llVecNorm( D - Project3D(D,Pn) ); oD = CP(Pn, (<1.0/O.x,1.0/O.y,1.0/O.z>));}
- endif
// SPHERE
- if 0
vector gSRxX(vector Sp, float Sr, vector Ro, vector Rd){
float t;Ro = Ro - Sp; //vector RayOrg = llDetectedPos(x) - llGetPos(); 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 Ro + (t * Rd);
}
- else
vector gSRxX(vector Sp, float Sr, vector Ro, vector Rd){
if(Rd) { Ro -= Sp; //vector RayOrg = llDetectedPos(x) - llGetPos(); 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) { float q = ((llSqrt(disc) * ~((b > 0) * -2)) - b) / 2.0; if(q)//avoid a divide by zero! { float t0 = q / a; float t1 = c / q; if(((t0 < t1) || (t1 < 0)) && (t0 >= 0)) return Ro + (t0 * Rd); if(t1 >= 0) return Ro + (t1 * Rd); } } } return ZERO_VECTOR;
}
- endif
- if 0
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;
}
- else
integer gSRx(vector Sp, float Sr, vector Ro, vector Rd){
if(Rd) { Ro -= Sp; //vector RayOrg = llDetectedPos(x) - llGetPos(); float a = Rd * Rd; float b = 2 * Rd * Ro; float c = (Ro * Ro) - (Sr * Sr); return (b * b - 4 * a * c) >= 0; } return FALSE;
}
- endif
// Other vector pN;float pD;
- if 0
gTiP(vector p1,vector p2,vector p3){
// Turns three vector points in space into a plane pN = llVecNorm( CP((p2-p1),(p3-p1)) ); pD = -p1*pN;}
- else
gTiP(vector p1,vector p2,vector p3){
// Turns three vector points in space into a plane pD = -p1*(pN = llVecNorm( CP((p2-p1),(p3-p1)) ));}
- endif
- if 0
integer gTXcC(vector p1,vector p2,vector p3,vector x){
gTiP(p1,p2,p3); vector Vn;vector En; Vn = p1 - x; En = CP((p2-p1),pN); if( ((p1-x)*CP(p2-p1,pN) >= 0)&&((p2-x)*CP(p3-p2,pN) >= 0)&&((p3-x)*CP(p1-p3,pN) >= 0) ) return TRUE; return FALSE;}
- else
integer gTXcC(vector p1,vector p2,vector p3,vector x){
gTiP(p1,p2,p3); vector Vn = p1 - x; vector En = CP((p2-p1),pN); return( ((p1-x)*CP(p2-p1,pN) >= 0) && ((p2-x)*CP(p3-p2,pN) >= 0) && ((p3-x)*CP(p1-p3,pN) >= 0) );}
- endif
- if 0
integer gTVXcC(vector p1,vector p2,vector p3,vector v,vector x){
if( ((p1-x)*CP(p2-p1,v) >= 0)&&((p2-x)*CP(p3-p2,v) >= 0)&&((p3-x)*CP(p1-p3,v) >= 0) ) return TRUE; return FALSE;}
- else
integer gTVXcC(vector p1,vector p2,vector p3,vector v,vector x){
// Can be used to check weather a point is inside a triangle return ( ((p1-x)*CP(p2-p1,v) >= 0)&&((p2-x)*CP(p3-p2,v) >= 0)&&((p3-x)*CP(p1-p3,v) >= 0) );}
- endif
- define gTRcC gTVXcC
- ifndef gTRcC
integer gTRcC(vector p1,vector p2,vector p3,vector O,vector D){
return gTVXcC(p1,p2,p3,O,D);}
- endif
- define gRZiX(O, D, z) ((O)+(D)*(z))
- ifndef gRZiX
vector gRZiX(vector O,vector D,float z){
return O+z*D;}
- endif</lsl>