Main Page Class Hierarchy Compound List File List Compound Members File Members

VecUtil.cc

Go to the documentation of this file.
00001 /*
00002 File: VecUtil.cc
00003 
00004 Function: Contains a grab-bag of useful graphics
00005 vector routines.
00006 
00007 Author(s): Andrew Willmott
00008 
00009 */
00010 
00011 #include "gcl/VecUtil.h"
00012 
00013  Bool Refract(
00014 GCLReal fromIndex, 
00015 GCLReal toIndex,
00016 const Vector &v, 
00017 const Vector &n, 
00018 GCLReal cosNV, 
00019 Vector &refractDir
00020 )
00022 {
00023 GCLReal kn, cos2, k;
00024 
00025 kn = fromIndex / toIndex;
00026 cos2 = 1.0 - sqr(kn) * (1.0 - sqr(cosNV));
00027 
00028 if (cos2 < 0.0)
00029 return(1); // Total internal reflection!
00030 
00031 k = kn * cosNV - sqrt(cos2);
00032 
00033 refractDir = -kn * v + k * n;
00034 
00035  return(0);
00036 }
00037 
00038 Void CalcTriAreaNormal(
00039 const Point &a,
00040 const Point &b, 
00041 const Point &c,
00042 Vector &n
00043 )
00048 {
00049 n[0] = (a[1] - b[1]) * (a[2] + b[2]) + (b[1] - c[1]) * (b[2] + c[2])
00050 + (c[1] - a[1]) * (c[2] + a[2]);
00051 n[1] = (a[2] - b[2]) * (a[0] + b[0]) + (b[2] - c[2]) * (b[0] + c[0])
00052 + (c[2] - a[2]) * (c[0] + a[0]);
00053 n[2] = (a[0] - b[0]) * (a[1] + b[1]) + (b[0] - c[0]) * (b[1] + c[1]) 
00054  + (c[0] - a[0]) * (c[1] + a[1]);
00055 }
00056 
00057 Void UpdateBounds(const Point& pt, Point& min, Point& max)
00058 {
00059 if (min[0] > pt[0])
00060 min[0] = pt[0];
00061 else if (max[0] < pt[0])
00062 max[0] = pt[0];
00063 
00064 if (min[1] > pt[1])
00065 min[1] = pt[1];
00066 else if (max[1] < pt[1])
00067 max[1] = pt[1];
00068 
00069 if (min[2] > pt[2])
00070 min[2] = pt[2];
00071 else if (max[2] < pt[2])
00072  max[2] = pt[2];
00073 }
00074 
00075  inline Double xCross(const Vector &a, const Vector &b, const Vector &c)
00076 // returns (a - b) x (c - a) . (1, 0, 0)
00077 { return((a[1] - b[1]) * (c[2] - b[2]) - (a[2] - b[2]) * (c[1] - b[1])); }
00078  inline Double yCross(const Vector &a, const Vector &b, const Vector &c)
00079 // returns (a - b) x (c - a) . (0, 1, 0)
00080 { return((a[2] - b[2]) * (c[0] - b[0]) - (a[0] - b[0]) * (c[2] - b[2])); }
00081 inline Double zCross(const Vector &a, const Vector &b, const Vector &c)
00082  // returns (a - b) x (c - a) . (0, 0, 1)
00083 { return((a[0] - b[0]) * (c[1] - b[1]) - (a[1] - b[1]) * (c[0] - b[0])); }
00084  
00085 const GCLReal kEdgeFuzz = 0.0;
00086 
00087 Bool PointIsInsideTriangle(
00088 const Point &p0, 
00089 const Point &p1, 
00090 const Point &p2, 
00091 const Point &point,
00092 Vector *coords 
00093 )
00097 {
00098 GCLReal temp, eps, a, b, c;
00099 Vector normal;
00100 Int normMajorAxis;
00101 
00102 // Calculate face normal & other info
00103 
00104 CalcTriAreaNormal(p0, p1, p2, normal);
00105 normal[0] = abs(normal[0]);
00106 normal[1] = abs(normal[1]);
00107 normal[2] = abs(normal[2]);
00108 normMajorAxis = MaxEltIndex(normal); 
00109 temp = normal[normMajorAxis];
00110 if (temp == 0.0)
00111 // degenerate triangle... can't hit this.
00112 return(false);
00113 
00114 eps = kEdgeFuzz * temp;
00115 switch(normMajorAxis)
00116 {
00117 case 0:
00118 a = xCross(p2, p1, point);
00119 if (a < eps) return(false);
00120 
00121 b = xCross(p0, p2, point);
00122 if (b < eps) return(false);
00123 
00124 c = temp - a - b;
00125 if (c < eps) return(false);
00126 
00127 break;
00128 
00129 case 1:
00130 a = yCross(p2, p1, point);
00131 if (a < eps) return(false);
00132 
00133 b = yCross(p0, p2, point); 
00134 if (b < eps) return(false);
00135 
00136 c = temp - a - b;
00137 if (c < eps) return(false);
00138 
00139 break;
00140 
00141 case 2:
00142 a = zCross(p2, p1, point);
00143 if (a < eps) return(false);
00144 
00145 b = zCross(p0, p2, point);
00146 if (b < eps) return(false);
00147 
00148 c = temp - a - b;
00149 if (c < eps) return(false);
00150 
00151 break;
00152 }
00153 
00154 if (coords)
00155 {
00156 (*coords)[0] = a / temp;
00157 (*coords)[1] = b / temp;
00158 (*coords)[2] = c / temp;
00159 }
00160 
00161  return(true);
00162 }
00163 
00164 VecTrans ZViewMatrix3(Vector &dir)
00167 {
00168 VecTrans M;
00169 
00170 M[0] = norm(MVector(dir[0], dir[1], dir[2]));
00171 M[1] = norm(MVector(dir[1], -dir[0], 0.0));
00172 M[2] = norm(MVector(-dir[0] * dir[2], -dir[1] * dir[2], 
00173 sqr(dir[0]) + sqr(dir[1])));
00174 
00175 #ifndef VL_ROW_ORIENT
00176 M = trans(M);
00177 #endif
00178 
00179  return(M);
00180 }
00181 
00182 Void UnitSquareToUnitDisc(Coord in, Coord &out)
00207 {
00208 GCLReal phi, r;
00209 Coord a = 2.0 * in - vl_1; /* a is now on [-1,1]^2 */
00210 
00211 if (a[0] > -a[1])
00212 /* region 1 or 2 */
00213 {
00214 if (a[0] > a[1])
00215 /* region 1, also |a| > |b| */
00216 {
00217 r = a[0];
00218 phi = (vl_pi / 4.0) * (a[1] / a[0]);
00219 }
00220 else
00221 /* region 2, also |b| > |a| */
00222 {
00223 r = a[1];
00224 phi = (vl_pi / 4.0) * (2.0 - (a[0] / a[1]));
00225 }
00226 }
00227 else 
00228 /* region 3 or 4 */
00229 {
00230 if (a[0] < a[1]) 
00231 /* region 3, also |a| >= |b|, a != 0 */
00232 { 
00233 r = -a[0];
00234 phi = (vl_pi / 4.0) * (4.0 + (a[1] / a[0]));
00235 }
00236 else 
00237 /* region 4, |b| >= |a|, but a==0 and b==0 could occur. */
00238 {
00239 r = -a[1];
00240 if (a[1] != 0)
00241 phi = (vl_pi / 4.0) * (6.0 - (a[0] / a[1]));
00242 else
00243 phi = 0.0;
00244 }
00245 }
00246 
00247 out[0] = r * cos(phi);
00248  out[1] = r * sin(phi);
00249 }
00250 
00251 Void UnitDiskToUnitSquare(Coord in, Coord &out)
00257 {
00258 GCLReal r = len(in);
00259 GCLReal phi = atan2(in[0], in[1]);
00260 Coord a;
00261 
00262 if (phi < -vl_pi / 4.0) 
00263 /* in range [-pi/4,7pi/4] */
00264 phi += 2.0 * vl_pi; 
00265 if (phi < vl_pi / 4.0)
00266 /* region 1 */
00267 { 
00268 a[0] = r;
00269 a[1] = phi * a[0] / (vl_pi / 4.0);
00270 }
00271 else if (phi < 3.0 * vl_pi / 4.0)
00272 /* region 2 */
00273 {
00274 a[1] = r;
00275 a[0] = -(phi - vl_pi / 2.0) * a[1] / (vl_pi / 4.0);
00276 }
00277 else if (phi < 5.0 * vl_pi / 4.0)
00278 /* region 3 */
00279 {
00280 a[0] = -r;
00281 a[1] = (phi - vl_pi) * a[0] / (vl_pi / 4.0);
00282 }
00283 else
00284 /* region 4 */
00285 {
00286 a[1] = -r;
00287 a[0] = -(phi - 3.0 * vl_pi / 2.0) * a[1] / (vl_pi / 4.0);
00288 }
00289 
00290 out[0] = (a[0] + 1) / 2;
00291  out[1] = (a[1] + 1) / 2;
00292 }
00293 
00294 GCLReal ProjectToBox(Point &min, Point &max, Point &p, Vector &r)
00297 {
00298 Vector d;
00299 Int i;
00300 
00301 for (i = 0; i < 3; i++)
00302 if (r[i] > 0.0)
00303 d[i] = (max[i] - p[i]) / r[i];
00304 else if (r[i] < 0.0)
00305 d[i] = (min[i] - p[i]) / r[i];
00306 else
00307 d[i] = HUGE_VAL;
00308 
00309  return(MinElt(d));
00310 }
00311 
00312 Vector RandomVector()
00313 {
00314 Vector v;
00315 
00316 v[0] = vl_rand();
00317 v[1] = vl_rand();
00318 v[2] = vl_rand();
00319 
00320 return(v);
00321 }

Generated at Sat Aug 5 00:17:04 2000 for Graphics Class Library by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000

AltStyle によって変換されたページ (->オリジナル) /