home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
s
/
sndppr3w.zip
/
NORMAL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-26
|
3KB
|
120 lines
/* Normal.C
** 4/26/91
** mjs
*/
#include "sp.h"
/* Define these to reduce visual clutter */
#define X1 (t->p1->x)
#define Y1 (t->p1->y)
#define Z1 (t->p1->z)
#define X2 (t->p2->x)
#define Y2 (t->p2->y)
#define Z2 (t->p2->z)
#define X3 (t->p3->x)
#define Y3 (t->p3->y)
#define Z3 (t->p3->z)
/* Prototypes for local functions */
PROTO static void clear_sum(void);
PROTO static void sum(Triangle *);
PROTO static void avg_sum(Point *);
PROTO static void sum_clist(CList *);
static real sum_x, sum_y, sum_z; /* normal accumulators */
static int count; /* count of all triangles... */
/* that contain this point */
/************************************************************************/
/* From _Computer Graphics_, by Hearn & Baker, page 192
** "The equation for a plane surface can be expressed in the form:
**
** Ax + By + Cz + D = 0
**
** where (x,y,z) is any point on the plane. The coefficients A,B,C,D are
** constants that can be calculated using values of three noncollinear points
** in the plane. Typically, we use the coordinates of three successive vertices
** on a polygon boundary to find values for these cooefficients.
**
** A = y1(z2-z3) + y2(z3-z1) + y3(z1-z2)
** B = z1(x2-x3) + z2(x3-x1) + z3(x1-x2)
** C = x1(y2-y3) + x2(y3-y1) + x3(y1-y2)
** D = -x1(y2z3-y3z2) - x2(y3z1-y1z3) - x3(y1z2-y2z1)
**
** "The vector N, normal to the surface of a plance described by the equation
** Ax + By + Cz + D = 0, has Cartesian coordinates (A,B,C)"
*/
void calc_tri_normal(Triangle *t)
{
if(debug) {
printf("1: %7.4f %7.4f %7.4f\n",X1,Y1,Z1);
printf("2: %7.4f %7.4f %7.4f\n",X2,Y2,Z2);
printf("3: %7.4f %7.4f %7.4f\n",X3,Y3,Z3);
}
t->eq_a = Y1*(Z2-Z3) + Y2*(Z3-Z1) + Y3*(Z1-Z2);
t->eq_b = Z1*(X2-X3) + Z2*(X3-X1) + Z3*(X1-X2);
t->eq_c = X1*(Y2-Y3) + X2*(Y3-Y1) + X3*(Y1-Y2);
if(debug) {
printf("%7.4f %7.4f %7.4f\n",t->eq_a,t->eq_b,t->eq_c);
}
/* The D value not needed for our surface normal calc's, but
** included here since it can be useful (for other programs)
** for determining whether a point is on the "inside" or
** "outside" of a plane.
*/
/* t->pD = -X1*(Y2*Z3-Y3*Z2) - X2*(Y3*Z1-Y1*Z3) - X3*(Y1*Z2-Y2*Z1);*/
}
/************************************************************************/
void calc_pt_normals()
{
Point *p;
p = p_root;
while(p != NULL) {
clear_sum(); /* clear accumulator */
sum_clist(p->cl); /* sum normals of all... */
/* "containing" triangles */
avg_sum(p); /* average and store pt normals */
p = p->next; /* step to next point in list */
}
}
void sum_clist(CList *cl)
{
while(cl != NULL) {
sum(cl->tri); /* add this tri's normals to sum*/
cl = cl->next; /* step to next tri in list */
}
}
/************************************************************************/
void clear_sum()
{
sum_x = sum_y = sum_z = (real)0.0;
count = 0;
}
void sum(Triangle *t)
{
sum_x += t->eq_a;
sum_y += t->eq_b;
sum_z += t->eq_c;
count++;
}
void avg_sum(Point *p)
{
p->nx = sum_x / (real)count;
p->ny = sum_y / (real)count;
p->nz = sum_z / (real)count;
}
/*** eof ****************************************************************/