ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/fvect.c
Revision: 2.5
Committed: Wed Nov 25 16:56:33 1998 UTC (25 years, 5 months ago) by gwlarson
Content type: text/plain
Branch: MAIN
Changes since 2.4: +16 -14 lines
Log Message:
modest efficiency improvements

File Contents

# Content
1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ SGI";
5 #endif
6
7 /*
8 * fvect.c - routines for float vector calculations
9 *
10 * 8/14/85
11 */
12
13 #include <math.h>
14 #include "fvect.h"
15
16
17 double
18 fdot(v1, v2) /* return the dot product of two vectors */
19 register FVECT v1, v2;
20 {
21 return(DOT(v1,v2));
22 }
23
24
25 double
26 dist2(p1, p2) /* return square of distance between points */
27 register FVECT p1, p2;
28 {
29 FVECT delta;
30
31 delta[0] = p2[0] - p1[0];
32 delta[1] = p2[1] - p1[1];
33 delta[2] = p2[2] - p1[2];
34
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 register double d, d1, d2;
45
46 d = dist2(ep1, ep2);
47 d1 = dist2(ep1, p);
48 d2 = d + d1 - dist2(ep2, p);
49
50 return(d1 - 0.25*d2*d2/d);
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 register 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 d2 = d + d1 - d2;
73
74 return(d1 - 0.25*d2*d2/d); /* distance to line */
75 }
76
77
78 fcross(vres, v1, v2) /* vres = v1 X v2 */
79 register FVECT vres, v1, v2;
80 {
81 vres[0] = v1[1]*v2[2] - v1[2]*v2[1];
82 vres[1] = v1[2]*v2[0] - v1[0]*v2[2];
83 vres[2] = v1[0]*v2[1] - v1[1]*v2[0];
84 }
85
86
87 fvsum(vres, v0, v1, f) /* vres = v0 + f*v1 */
88 register FVECT vres, v0, v1;
89 register double f;
90 {
91 vres[0] = v0[0] + f*v1[0];
92 vres[1] = v0[1] + f*v1[1];
93 vres[2] = v0[2] + f*v1[2];
94 }
95
96
97 double
98 normalize(v) /* normalize a vector, return old magnitude */
99 register FVECT v;
100 {
101 register double len, d;
102
103 d = DOT(v, v);
104
105 if (d <= 0.0)
106 return(0.0);
107
108 if (d <= 1.0+FTINY && d >= 1.0-FTINY)
109 len = 0.5 + 0.5*d; /* first order approximation */
110 else
111 len = sqrt(d);
112
113 v[0] *= d = 1.0/len;
114 v[1] *= d;
115 v[2] *= d;
116
117 return(len);
118 }
119
120
121 spinvector(vres, vorig, vnorm, theta) /* rotate vector around normal */
122 FVECT vres, vorig, vnorm;
123 double theta;
124 {
125 double sint, cost, normprod;
126 FVECT vperp;
127 register int i;
128
129 if (theta == 0.0) {
130 if (vres != vorig)
131 VCOPY(vres, vorig);
132 return;
133 }
134 cost = cos(theta);
135 sint = sin(theta);
136 normprod = DOT(vorig, vnorm)*(1.-cost);
137 fcross(vperp, vnorm, vorig);
138 for (i = 0; i < 3; i++)
139 vres[i] = vorig[i]*cost + vnorm[i]*normprod + vperp[i]*sint;
140 }