/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : WWMath * * * * $Archive:: /Commando/Code/wwmath/lineseg.cpp $* * * * Author:: Greg_h * * * * $Modtime:: 3/16/00 3:16p $* * * * $Revision:: 25 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * LineSegClass::Set -- Initialize this 'lineseg' by transforming another 'lineseg' * * LineSegClass::Set_Random -- create a random linesegment within the given space * * LineSegClass::Find_Point_Closest_To -- Finds point on line closest to point supplied. * * LineSegClass::Find_Intersection -- Finds the closest points on the two lines * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "lineseg.h" //#include #include "matrix3d.h" /*********************************************************************************************** * LineSegClass::Set -- Initialize this 'lineseg' by transforming another 'lineseg' * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 6/17/98 GTH : Created. * *=============================================================================================*/ void LineSegClass::Set(const LineSegClass & that,const Matrix3D & tm) { /* ** Transform P0 and P1 */ Matrix3D::Transform_Vector(tm,that.P0,&P0); Matrix3D::Transform_Vector(tm,that.P1,&P1); /* ** Just calculate DP */ DP = P1 - P0; /* ** Rotate the direction vector */ Matrix3D::Rotate_Vector(tm,that.Dir,&Dir); /* ** Length should be un-changed */ Length = that.Length; } /*********************************************************************************************** * LineSegClass::Set_Random -- create a random linesegment within the given space * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 4/21/98 GTH : Created. * *=============================================================================================*/ void LineSegClass::Set_Random(const Vector3 & min,const Vector3 & max) { float frac; frac = WWMath::Random_Float(); P0.X = min.X + frac * (max.X - min.X); frac = WWMath::Random_Float(); P0.Y = min.Y + frac * (max.Y - min.Y); frac = WWMath::Random_Float(); P0.Z = min.Z + frac * (max.Z - min.Z); frac = WWMath::Random_Float(); P1.X = min.X + frac * (max.X - min.X); frac = WWMath::Random_Float(); P1.Y = min.Y + frac * (max.Y - min.Y); frac = WWMath::Random_Float(); P1.Z = min.Z + frac * (max.Z - min.Z); DP = P1 - P0; Dir = DP; Dir.Normalize(); Length = DP.Length(); } /*********************************************************************************************** * LineSegClass::Find_Point_Closest_To -- Finds point on line closest to point supplied. * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 07/26/1999 SKB : Created. * *=============================================================================================*/ Vector3 LineSegClass::Find_Point_Closest_To(const Vector3 &pos) const { // Get a vector from one line endpoint to point in question. Vector3 v_0_pos = (pos - P0); float dotprod = Vector3::Dot_Product(Dir, v_0_pos); // Check to see if point is past either of the endpoints. // (Unable to draw a perpendicular line from the point to the line segment.) if (dotprod <= 0.0) { return(P0); } else if (dotprod >= Length) { return(P1); } // Find point on line seg that is closest to pos passed in. Vector3 point = P0 + (dotprod * Dir); return(point); } /*********************************************************************************************** * LineSegClass::Find_Intersection -- Finds the closest points on the two lines.. * * * * INPUT: * * * * OUTPUT: * * * * WARNINGS: * * * * HISTORY: * * 03/03/2000 PDS : Created. * *=============================================================================================*/ bool LineSegClass::Find_Intersection ( const LineSegClass & other_line, Vector3 * p1, float * fraction1, Vector3 * p2, float * fraction2 ) const { bool retval = false; Vector3 cross1 = Vector3::Cross_Product (Dir, other_line.Dir); Vector3 cross2 = Vector3::Cross_Product (other_line.P0 - P0, other_line.Dir); float top1 = cross2 * cross1; float bottom1 = cross1 * cross1; Vector3 cross3 = Vector3::Cross_Product (other_line.Dir, Dir); Vector3 cross4 = Vector3::Cross_Product (P0 - other_line.P0, Dir); float top2 = cross4 * cross3; float bottom2 = cross3 * cross3; // // If either of the divisors are 0, then the lines are parallel // if (bottom1 != 0 && bottom2 != 0) { float length1 = top1 / bottom1; float length2 = top2 / bottom2; // // Calculate the closest points on both lines. // Note: If the points are the same, then the lines intersect. // (*p1) = P0 + (Dir * length1); (*p2) = other_line.P0 + (other_line.Dir * length2); // // Return the fractions if they caller wants them // if (fraction1 != NULL) { (*fraction1) = length1 / Length; } if (fraction2 != NULL) { (*fraction2) = length2 / Length; } retval = true; } return retval; }