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