home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_300
/
302_01
/
norm.c
< prev
next >
Wrap
Text File
|
1990-02-14
|
4KB
|
107 lines
/* Calculate normal to face
Copyright (c) 1988 by Gus O'Donnell
Revision history:
Version 1.00 February 29, 1988 As released.
Version 1.01 March 20, 1988 Created libraries for all
memory models
*/
#include <3d.h>
#include <float.h>
#include <stdio.h>
#include <math.h>
int normal (FACE *this_face, VECTOR norm)
/* Calculate the normal to the face. The normal is calculated as the
cross product of two sides of the face. The face must have at least
three corners. The first three corners must not be colinear. Since
each corner added to the face using add_corner is checked for colinearity,
this check is not performed here. The function also assumes that the
face is a convex polygon; if the first two sides of the face are at an
angle greater than 180 degrees (i.e., the face is a concave polygon), the
normal will have the wrong sign. Finally, the function assumes that the
corners are listed in clockwise order, viewing the face from the outside
of the solid.
Given two vectors
q = [Ai + Bj + Ck],
r = [Di + Ej + Fk]
where i, j, and k are orthogonal unit vectors, the cross product p = q X r
is given by:
p = [(B*F) - (C*E)]i
+ [(C*D) - (A*F)]j
+ [(A*E) - (B*D)]k
If the first three corners of the face are a, b, and c, the components of
the vectors forming the first two sides q and r are
A = a [0] - b [0]
B = a [1] - b [1]
C = a [2] - b [2]
D = c [0] - b [1]
E = c [1] - b [2]
F = c [2] - b [2]
Note that the components are calculated such that corner b corresponds
to the tail of the two vectors. This yields a normal vector p = q X r
with a direction away from the interior of the solid. Substituting
the expressions for A through F into the expression for the cross product
gives:
p = [(a [1] - b [1])*(c [2] - b [2])
- (a [2] - b [2])*(c [1] - b [1])]i
+ [(a [2] - b [2])*(c [0] - b [0])
- (a [0] - b [0])*(c [2] - b [2])]j
+ [(a [0] - b [0])*(c [1] - b [1])
- (a [1] - b [1])*(c [0] - b [0])]k
This is the result returned in norm. The function returns an integer
status corresponding to:
0 - Operation successful.
1 - Face has less than three corners.
*/
{
VECTOR p [3]; /* Temporary storage for the first three corners. */
CORNER *chandle;
int index,count;
chandle = this_face -> first -> next;
for (count = 2; count >= 0; count--) /* Copy the first three corners
of the face to temporary
storage. */
{
if (chandle -> next == NULL) return (1); /* Face has less than three
corners. */
for (index = 0; index < DIM; index++)
p [count] [index] = chandle -> this -> coord [index];
chandle = chandle -> next;
}
/* In the following expression,
p[0] = a
p[1] = b
p[2] = c
*/
norm [0] = ((p[2][1] - p[1][1]) * (p[0][2] - p[1][2]))
- ((p[2][2] - p[1][2]) * (p[0][1] - p[1][1]));
norm [1] = ((p[2][2] - p[1][2]) * (p[0][0] - p[1][0]))
- ((p[2][0] - p[1][0]) * (p[0][2] - p[1][2]));
norm [2] = ((p[2][0] - p[1][0]) * (p[0][1] - p[1][1]))
- ((p[2][1] - p[1][1]) * (p[0][0] - p[1][0]));
return (0);
}