00001 /* 00002 File: VecUtil.h 00003 00004 Function: Contains a grab-bag of useful graphics 00005 vector routines. 00006 00007 Author(s): Andrew Willmott 00008 00009 Copyright: (c) 1996-2000, Andrew Willmott 00010 00011 */ 00012 00013 #ifndef __VecUtil__ 00014 #define __VecUtil__ 00015 00016 #include "gcl/Geometry.h" 00017 #include "gcl/Colour.h" 00018 00019 00020 // --- Min & Max routines ----------------------------------------------------- 00021 00022 inline GCLReal MaxElt(const Vector &v); 00024 inline GCLReal MinElt(const Vector &v); 00026 00027 inline Int MaxEltIndex(const Vector &v); 00029 inline Int MinEltIndex(const Vector &v); 00031 00032 inline Void FindMaxElts(const Vector &a, const Vector &b, Vector &c); 00034 inline Void FindMinElts(const Vector &a, const Vector &b, Vector &c); 00036 00037 inline ClrReal MaxCmpt(const Colour &c); 00039 inline ClrReal MinCmpt(const Colour &c); 00040 00041 inline Int MaxCmptIndex(const Colour &c); 00042 inline Int MinCmptIndex(const Colour &c); 00043 00044 inline Void FindMaxCmpts(const Colour &a, const Colour &b, Colour &c); 00045 inline Void FindMinCmpts(const Colour &a, const Colour &b, Colour &c); 00046 00047 // --- Bounding box utility routines ------------------------------------------ 00048 00049 inline GCLReal BoxVol(const Vector &min, const Vector &max); 00051 inline GCLReal BoxArea(const Vector &min, const Vector &max); 00053 Void UpdateBounds(const Point& pt, Point& min, Point& max); 00055 00056 // --- Miscellaneous ---------------------------------------------------------- 00057 00058 Void CalcTriAreaNormal( 00059 const Point &a, 00060 const Point &b, 00061 const Point &c, 00062 Vector &n 00063 ); 00065 00066 inline Bool PlaneIntersection( 00067 const Point &start, 00068 const Vector &direction, 00069 GCLReal d, 00070 const Vector &normal, 00071 GCLReal &t 00072 ) 00078 { 00079 GCLReal normDotDirection = dot(normal, direction); 00080 00081 if (normDotDirection == 0.0) 00082 return(false); 00083 00084 t = (d + dot(normal, start)) / -normDotDirection; 00085 00086 return(true); 00087 } 00088 00089 Bool PointIsInsideTriangle( 00090 const Point &v0, 00091 const Point &v1, 00092 const Point &v2, 00093 const Point &point, 00094 Vector *coords = 0 00095 ); 00097 00098 inline Vector FindOrthoVector(const Vector &v) 00102 { 00103 Vector u; 00104 00105 // we choose the axis that is most orthogonal to v, 00106 // and return the cross product of it and v. Really! 00107 00108 if (abs(v[0]) < abs(v[1])) 00109 if (abs(v[0]) < abs(v[2])) 00110 { u[0] = 0; u[1] = v[2]; u[2] = -v[1]; } 00111 else 00112 { u[0] = v[1]; u[1] = -v[0]; u[2] = 0; } 00113 else 00114 if (abs(v[1]) < abs(v[2])) 00115 { u[0] = -v[2]; u[1] = 0; u[2] = v[0]; } 00116 else 00117 { u[0] = v[1]; u[1] = -v[0]; u[2] = 0; } 00118 00119 return(u); 00120 } 00121 00122 Vector RandomVector(); 00124 00125 Bool Refract( 00126 GCLReal fromIndex, 00127 GCLReal toIndex, 00128 const Vector &v, 00129 const Vector &n, 00130 GCLReal cosNV, 00131 Vector &refractDir 00132 ); 00134 00135 Void UnitSquareToUnitDisc(Coord in, Coord &out); 00136 Void UnitDiskToUnitSquare(Coord in, Coord &out); 00137 Void UnitSquareToUnitDisc(Coord in, Coord &out); 00138 Void UnitDiskToUnitSquare(Coord in, Coord &out); 00139 // What the names say: code from Shirley & Chiu, minimises adjacency, 00140 // fractional area and aspect ratio distortions. 00141 00142 GCLReal ProjectToBox(Point &min, Point &max, Point &p, Vector &r); 00144 00145 00146 // --- Inlines ---------------------------------------------------------------- 00147 00148 inline GCLReal MaxElt(const Vector &v) 00149 { 00150 return(Max(Max(v[0], v[1]), v[2])); 00151 } 00152 00153 inline GCLReal MinElt(const Vector &v) 00154 { 00155 return(Min(Min(v[0], v[1]), v[2])); 00156 } 00157 00158 inline Int MinEltIndex(const Vector &v) 00159 { 00160 if (v[0] < v[1]) 00161 if (v[0] < v[2]) 00162 return(0); 00163 else 00164 return(2); 00165 else 00166 if (v[1] < v[2]) 00167 return(1); 00168 else 00169 return(2); 00170 } 00171 00172 inline Int MaxEltIndex(const Vector &v) 00173 { 00174 if (v[0] > v[1]) 00175 if (v[0] > v[2]) 00176 return(0); 00177 else 00178 return(2); 00179 else 00180 if (v[1] > v[2]) 00181 return(1); 00182 else 00183 return(2); 00184 } 00185 00186 inline Int MinCmptIndex(const Colour &c) 00187 { 00188 if (c[0] < c[1]) 00189 if (c[0] < c[2]) 00190 return(0); 00191 else 00192 return(2); 00193 else 00194 if (c[1] < c[2]) 00195 return(1); 00196 else 00197 return(2); 00198 } 00199 00200 inline Int MaxCmptIndex(const Colour &c) 00201 { 00202 if (c[0] > c[1]) 00203 if (c[0] > c[2]) 00204 return(0); 00205 else 00206 return(2); 00207 else 00208 if (c[1] > c[2]) 00209 return(1); 00210 else 00211 return(2); 00212 } 00213 00214 inline Void FindMaxElts(const Vector &a, const Vector &b, Vector &c) 00215 { 00216 c[0] = Max(a[0], b[0]); 00217 c[1] = Max(a[1], b[1]); 00218 c[2] = Max(a[2], b[2]); 00219 } 00220 00221 inline Void FindMinElts(const Vector &a, const Vector &b, Vector &c) 00222 { 00223 c[0] = Min(a[0], b[0]); 00224 c[1] = Min(a[1], b[1]); 00225 c[2] = Min(a[2], b[2]); 00226 } 00227 00228 inline ClrReal MaxCmpt(const Colour &c) 00229 { 00230 return(Max(Max(c[0], c[1]), c[2])); 00231 } 00232 00233 inline ClrReal MinCmpt(const Colour &c) 00234 { 00235 return(Min(Min(c[0], c[1]), c[2])); 00236 } 00237 00238 inline Void FindMaxCmpts(const Colour &a, const Colour &b, Colour &c) 00239 { 00240 c[0] = Max(a[0], b[0]); 00241 c[1] = Max(a[1], b[1]); 00242 c[2] = Max(a[2], b[2]); 00243 } 00244 00245 inline Void FindMinCmpts(const Colour &a, const Colour &b, Colour &c) 00246 { 00247 c[0] = Min(a[0], b[0]); 00248 c[1] = Min(a[1], b[1]); 00249 c[2] = Min(a[2], b[2]); 00250 } 00251 00252 inline GCLReal BoxVol(const Vector &min, const Vector &max) 00253 { 00254 Vector t = max; 00255 00256 t -= min; 00257 00258 return(t[0] * t[1] * t[2]); 00259 } 00260 00261 inline GCLReal BoxArea(const Vector &min, const Vector &max) 00262 { 00263 Vector t = max; 00264 00265 t -= min; 00266 00267 return(2 * (t[0] * t[1] + t[1] * t[2] + t[2] * t[0])); 00268 } 00269 00270 #endif