User:Nexii Malthus/Geometric

From Second Life Wiki
Jump to navigation Jump to search

Geometric Library

Line Functions

Line Nearest Point, Nearest Point

Returns nearest point on line to given point <lsl> vector gLXnX(vector O,vector D,vector A){

   return gLXdV(O,D,A) + A;}

</lsl>

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)
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/ // //===================================================//

  1. define CP(A, B) ((A) % (B))
  2. ifndef CP

vector CP(vector A,vector B){

   return A % B;}
  1. endif
  1. 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;}
  1. else

vector Project3D(vector A,vector B){

   return B * ((A*B) / (B*B));}
  1. endif

// POINT

  1. define gXXdZ llVecDist
  2. ifndef gXXdZ

float gXXdZ(vector A,vector B){

   // Distance P2P.
   return llVecDist(A,B);}
  1. endif
  1. define gXXdV(A,B) ((A) - (B))
  2. ifndef gXXdV

vector gXXdV(vector A,vector B){

   // Vector to move from P2P.
   return A-B;}
  1. endif

// LINE

  1. 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;}
  1. 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;}
  1. endif
  1. define gLXdZ(O, D, A) llVecMag(CP((A-O),D))
  2. 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));}
  1. endif
  1. define gLLdV(O, D, A) Project3D( (O2-O1), CP(D1,D2) )
  2. ifndef gLLdV

vector gLLdV(vector O1,vector D1,vector O2,vector D2){

   // Shortest vector of two lines
   return Project3D( (O2-O1), CP(D1,D2) );}
  1. endif
  1. define gLLdZ(O1, D1, O2, D2) ((O2-O1) * llVecNorm(CP(D1,D2)))
  2. 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;}
  1. endif
  1. 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;}
  1. 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 ));}
  1. endif

vector X1;vector X2;vector V1;float Z1;

  1. 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);}
  1. 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
  1. endif
  1. 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);}
  1. 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
  1. endif

// PLANE

  1. define gPXdZ(Pn, Pd, A) ((A) * (Pn) + (Pd))
  2. ifndef gPXdZ

float gPXdZ(vector Pn,float Pd,vector A){

   // Finds distance of a point from a plane
   return A * Pn + Pd;}
  1. 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;}
  1. 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) );}
  1. 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) );}
  1. 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;

  1. 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);}
  1. 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);}
  1. endif
  1. define gRXpZ(O, D, A) (A-O)*D
  2. ifndef gRXpZ

float gRXpZ(vector O,vector D,vector A){

   // Finds projected distance of a point along a ray
   return (A-O)*D;}
  1. endif
  1. 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);}
  1. 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>));}
  1. endif

// SPHERE

  1. 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);

}

  1. 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;

}

  1. endif
  1. 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;

}

  1. 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;

}

  1. endif

// Other vector pN;float pD;

  1. 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;}
  1. 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)) ));}
  1. endif
  1. 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;}
  1. 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) );}
  1. endif
  1. 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;}
  1. 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) );}
  1. endif
  1. define gTRcC gTVXcC
  2. ifndef gTRcC

integer gTRcC(vector p1,vector p2,vector p3,vector O,vector D){

   return gTVXcC(p1,p2,p3,O,D);}
  1. endif
  1. define gRZiX(O, D, z) ((O)+(D)*(z))
  2. ifndef gRZiX

vector gRZiX(vector O,vector D,float z){

   return O+z*D;}
  1. endif</lsl>