00001 // vector.cxx -- additional vector routines 00002 // 00003 // Written by Curtis Olson, started December 1997. 00004 // 00005 // Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt 00006 // 00007 // This library is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU Library General Public 00009 // License as published by the Free Software Foundation; either 00010 // version 2 of the License, or (at your option) any later version. 00011 // 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 // Library General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU General Public License 00018 // along with this program; if not, write to the Free Software 00019 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00020 // 00021 // $Id: vector_8cxx_source.html,v 1.3 2010/02/23 22:10:17 curt Exp $ 00022 00023 00024 #include <math.h> 00025 #include <stdio.h> 00026 00027 // #include <Include/fg_types.h> 00028 00029 #include "vector.hxx" 00030 00031 00032 // calculate the projection, p, of u along the direction of d. 00033 void sgProjection(sgVec3 p, const sgVec3 u, const sgVec3 d){ 00034 double denom = sgScalarProductVec3(d,d); 00035 if (denom == 0.) sgCopyVec3(p, u); 00036 else sgScaleVec3(p, d, sgScalarProductVec3(u,d) / denom); 00037 } 00038 00039 // Same thing, except using double precision 00040 void sgProjection(sgdVec3 p, const sgdVec3 u, const sgdVec3 d){ 00041 double denom = sgdScalarProductVec3(d,d); 00042 if (denom == 0.) sgdCopyVec3(p, u); 00043 else sgdScaleVec3(p, d, sgdScalarProductVec3(u,d) / denom); 00044 } 00045 00046 // Given a point p, and a line through p0 with direction vector d, 00047 // find the closest point (p1) on the line 00048 void sgClosestPointToLine( sgVec3 p1, const sgVec3 p, const sgVec3 p0, 00049 const sgVec3 d ) { 00050 00051 sgVec3 u, u1; 00052 00053 // u = p - p0 00054 sgSubVec3(u, p, p0); 00055 00056 // calculate the projection, u1, of u along d. 00057 sgProjection(u1, u, d); 00058 00059 // calculate the point p1 along the line that is closest to p 00060 // p0 = p1 + u1 00061 sgAddVec3(p1, p0, u1); 00062 } 00063 00064 00065 // Given a point p, and a line through p0 with direction vector d, 00066 // find the closest point (p1) on the line 00067 void sgdClosestPointToLine( sgdVec3 p1, const sgdVec3 p, const sgdVec3 p0, 00068 const sgdVec3 d ) { 00069 00070 sgdVec3 u, u1; 00071 00072 // u = p - p0 00073 sgdSubVec3(u, p, p0); 00074 00075 // calculate the projection, u1, of u along d. 00076 sgProjection(u1, u, d); 00077 00078 // calculate the point p1 along the line that is closest to p 00079 // p0 = p1 + u1 00080 sgdAddVec3(p1, p0, u1); 00081 } 00082 00083 00084 // Given a point p, and a line through p0 with direction vector d, 00085 // find the shortest distance (squared) from the point to the line 00086 double sgClosestPointToLineDistSquared( const sgVec3 p, const sgVec3 p0, 00087 const sgVec3 d ) { 00088 00089 sgVec3 u, u1, v; 00090 00091 // u = p - p0 00092 sgSubVec3(u, p, p0); 00093 00094 // calculate the projection, u1, of u along d. 00095 sgProjection(u1, u, d); 00096 00097 // v = u - u1 = vector from closest point on line, p1, to the 00098 // original point, p. 00099 sgSubVec3(v, u, u1); 00100 00101 return ( sgScalarProductVec3(v, v) ); 00102 } 00103 00104 00105 // Given a point p, and a line through p0 with direction vector d, 00106 // find the shortest distance (squared) from the point to the line 00107 double sgdClosestPointToLineDistSquared( const sgdVec3 p, const sgdVec3 p0, 00108 const sgdVec3 d ) { 00109 00110 sgdVec3 u, u1, v; 00111 00112 // u = p - p0 00113 sgdSubVec3(u, p, p0); 00114 00115 // calculate the projection, u1, of u along d. 00116 sgProjection(u1, u, d); 00117 00118 // v = u - u1 = vector from closest point on line, p1, to the 00119 // original point, p. 00120 sgdSubVec3(v, u, u1); 00121 00122 return ( sgdScalarProductVec3(v, v) ); 00123 } 00124 00125 00126 // This is a quicker form of 00127 // sgMakeMatTrans4( sgMat4 sgTrans, sgVec3 trans ) 00128 // sgPostMultMat4( sgMat, sgTRANS ); 00129 void sgPostMultMat4ByTransMat4( sgMat4 src, const sgVec3 trans ) 00130 { 00131 for( int i=0; i<4; i++) { 00132 for( int j=0; j<3; j++ ) { 00133 src[i][j] += (src[i][3] * trans[j]); 00134 } 00135 } 00136 } 00137 00138