| 1 | /* Copyright (c) 1986 Regents of the University of California */ | 
| 2 |  | 
| 3 | #ifndef lint | 
| 4 | static char SCCSid[] = "$SunId$ LBL"; | 
| 5 | #endif | 
| 6 |  | 
| 7 | /* | 
| 8 | *  fvect.c - routines for float vector calculations | 
| 9 | * | 
| 10 | *     8/14/85 | 
| 11 | */ | 
| 12 |  | 
| 13 | #include  "fvect.h" | 
| 14 |  | 
| 15 | #define  FTINY          1e-7 | 
| 16 |  | 
| 17 |  | 
| 18 | double | 
| 19 | fdot(v1, v2)                    /* return the dot product of two vectors */ | 
| 20 | register FVECT  v1, v2; | 
| 21 | { | 
| 22 | return(DOT(v1,v2)); | 
| 23 | } | 
| 24 |  | 
| 25 |  | 
| 26 | double | 
| 27 | dist2(p1, p2)                   /* return square of distance between points */ | 
| 28 | register FVECT  p1, p2; | 
| 29 | { | 
| 30 | static FVECT  delta; | 
| 31 |  | 
| 32 | delta[0] = p2[0] - p1[0]; | 
| 33 | delta[1] = p2[1] - p1[1]; | 
| 34 | delta[2] = p2[2] - p1[2]; | 
| 35 | return(DOT(delta, delta)); | 
| 36 | } | 
| 37 |  | 
| 38 |  | 
| 39 | double | 
| 40 | dist2line(p, ep1, ep2)          /* return square of distance to line */ | 
| 41 | FVECT  p;               /* the point */ | 
| 42 | FVECT  ep1, ep2;        /* points on the line */ | 
| 43 | { | 
| 44 | static double  d, d1, d2; | 
| 45 |  | 
| 46 | d = dist2(ep1, ep2); | 
| 47 | d1 = dist2(ep1, p); | 
| 48 | d2 = dist2(ep2, p); | 
| 49 |  | 
| 50 | return(d1 - (d+d1-d2)*(d+d1-d2)/d/4); | 
| 51 | } | 
| 52 |  | 
| 53 |  | 
| 54 | double | 
| 55 | dist2lseg(p, ep1, ep2)          /* return square of distance to line segment */ | 
| 56 | FVECT  p;               /* the point */ | 
| 57 | FVECT  ep1, ep2;        /* the end points */ | 
| 58 | { | 
| 59 | static double  d, d1, d2; | 
| 60 |  | 
| 61 | d = dist2(ep1, ep2); | 
| 62 | d1 = dist2(ep1, p); | 
| 63 | d2 = dist2(ep2, p); | 
| 64 |  | 
| 65 | if (d2 > d1) {                  /* check if past endpoints */ | 
| 66 | if (d2 - d1 > d) | 
| 67 | return(d1); | 
| 68 | } else { | 
| 69 | if (d1 - d2 > d) | 
| 70 | return(d2); | 
| 71 | } | 
| 72 |  | 
| 73 | return(d1 - (d+d1-d2)*(d+d1-d2)/d/4);   /* distance to line */ | 
| 74 | } | 
| 75 |  | 
| 76 |  | 
| 77 | fcross(vres, v1, v2)            /* vres = v1 X v2 */ | 
| 78 | register FVECT  vres, v1, v2; | 
| 79 | { | 
| 80 | vres[0] = v1[1]*v2[2] - v1[2]*v2[1]; | 
| 81 | vres[1] = v1[2]*v2[0] - v1[0]*v2[2]; | 
| 82 | vres[2] = v1[0]*v2[1] - v1[1]*v2[0]; | 
| 83 | } | 
| 84 |  | 
| 85 |  | 
| 86 | double | 
| 87 | normalize(v)                    /* normalize a vector, return old magnitude */ | 
| 88 | register FVECT  v; | 
| 89 | { | 
| 90 | static double  len; | 
| 91 |  | 
| 92 | len = DOT(v, v); | 
| 93 |  | 
| 94 | if (len <= 0.0) | 
| 95 | return(0.0); | 
| 96 |  | 
| 97 | /****** problematic | 
| 98 | if (len >= (1.0-FTINY)*(1.0-FTINY) && | 
| 99 | len <= (1.0+FTINY)*(1.0+FTINY)) | 
| 100 | return(1.0); | 
| 101 | ******/ | 
| 102 |  | 
| 103 | len = sqrt(len); | 
| 104 | v[0] /= len; | 
| 105 | v[1] /= len; | 
| 106 | v[2] /= len; | 
| 107 | return(len); | 
| 108 | } |