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