home *** CD-ROM | disk | FTP | other *** search
- /*
- name: algebra.c
-
- Linear algebra
- --------------
-
- These functions simplify vector algebra etc.
-
- */
-
- #include "defs.h"
-
-
-
- void CreateVector(VECTOR *v, double vx, double vy, double vz)
- {
- v->x=vx;
- v->y=vy;
- v->z=vz;
- }
-
-
-
- /* v2 = v1 */
-
- void CopyVector(VECTOR *v2, VECTOR *v1)
- {
- v2->x=v1->x;
- v2->y=v1->y;
- v2->z=v1->z;
- }
-
-
-
- /* v3 = v1 + v2 */
-
- void AddVector(VECTOR *v3, VECTOR *v1, VECTOR *v2)
- {
- v3->x=(v1->x)+(v2->x);
- v3->y=(v1->y)+(v2->y);
- v3->z=(v1->z)+(v2->z);
- }
-
-
-
- /* v3 = v1 - v2 */
-
- void SubVector(VECTOR *v3, VECTOR *v1, VECTOR *v2)
- {
- v3->x=(v1->x)-(v2->x);
- v3->y=(v1->y)-(v2->y);
- v3->z=(v1->z)-(v2->z);
- }
-
-
-
- /* v2 = -v1 */
-
- void NegVector(VECTOR *v2, VECTOR *v1)
- {
- v2->x=-(v1->x);
- v2->y=-(v1->y);
- v2->z=-(v1->z);
- }
-
-
-
- /* v3 = v1 x v2 */
-
- void CrossProduct(VECTOR *v3, VECTOR *v1, VECTOR *v2)
- {
- v3->x=(v1->y)*(v2->z)-(v1->z)*(v2->y);
- v3->y=(v1->z)*(v2->x)-(v1->x)*(v2->z);
- v3->z=(v1->x)*(v2->y)-(v1->y)*(v2->x);
- }
-
-
-
- /* Returns v1 ยท v2 */
-
- double DotProduct(VECTOR *v1, VECTOR *v2)
- {
- return((v1->x)*(v2->x)+(v1->y)*(v2->y)+(v1->z)*(v2->z));
- }
-
-
-
- /* v2 = t * v1 */
-
- void ScaleVector(VECTOR *v2, double t, VECTOR *v1)
- {
- v2->x=t*(v1->x);
- v2->y=t*(v1->y);
- v2->z=t*(v1->z);
- }
-
-
-
- /* Returns |v| */
-
- double VectorLength(VECTOR *v)
- {
- return(sqrt((v->x)*(v->x)+(v->y)*(v->y)+(v->z)*(v->z)));
- }
-
-
-
- /* Returns the (smallest) angle between v1 and v2 */
-
- double VectorsAngle(VECTOR *v1, VECTOR *v2)
- {
- return(acos(DotProduct(v1,v2)/(VectorLength(v1)*VectorLength(v2))));
- }
-
-
-
- void CreatePoint(POINT *p, double px, double py, double pz)
- {
- p->x=px;
- p->y=py;
- p->z=pz;
- }
-
-
-
- /* p2 = p1 */
-
- void CopyPoint(POINT *p2, POINT *p1)
- {
- p2->x=p1->x;
- p2->y=p1->y;
- p2->z=p1->z;
- }
-
-
-
- /* This routine creates a line from two given points */
-
- void MakeLine(LINE *l, POINT *p1, POINT *p2)
- {
- CopyPoint(&(l->Origin),p1);
- CreateVector(&(l->Direction),(p2->x)-(p1->x),(p2->y)-(p1->y),(p2->z)-(p1->z));
- }
-
-
-
- /* This routine creates a reflected vector v2, given a vector v1 and a normal n */
-
- void ReflectVector(VECTOR *v2, VECTOR *v1, VECTOR *n)
- {
- double k,a;
- VECTOR vtemp,vtemp2;
-
- CopyVector(&vtemp2,n);
- a=PI-VectorsAngle(v1,n);
- if((a<0.0)&&(a>-EPSILON)) a+=EPSILON;
- if(a>PID2) {
- NegVector(&vtemp2,n);
- a=PI-a;
- }
- k=VectorLength(&vtemp2)/(2*cos(a)*VectorLength(v1));
- ScaleVector(&vtemp,k,v1);
- AddVector(v2,&vtemp,&vtemp2);
- /*
- if(k<0) NegVector(v2,v2); k<0 <=> from "inside" of object
- */
- }
-
-
- /* This routine rotates a 2D point in a 2D system */
- /* I.e. (x,y) rotates (ar) radians counter clockwise around (0,0) */
-
- void Rotate2D(double *x, double *y, double ar)
- {
- double x1,y1;
-
- x1=(*x)*cos(ar)-(*y)*sin(ar);
- y1=(*x)*sin(ar)+(*y)*cos(ar);
- *x=x1; *y=y1;
- }
-
-
- /* This routine rotates a 3D point in 3D space. The point (x,y,z) */
- /* is rotated around the x, the y and the z axis (in that order). */
- /* The vector RotV gives the degrees to rotate around each axis */
-
- void RotatePoint(POINT *p, VECTOR *RotV)
- {
- double x1,y1,z1;
-
- x1=p->x; y1=p->y; z1=p->z;
- if(RotV->x!=0.0) Rotate2D(&y1,&z1,RotV->x);
- if(RotV->y!=0.0) Rotate2D(&z1,&x1,RotV->y);
- if(RotV->z!=0.0) Rotate2D(&x1,&y1,RotV->z);
- p->x=x1; p->y=y1; p->z=z1;
- }
-
-
- /* This is the same thing, but with a vector instead of a point. */
-
- void RotateVector(VECTOR *v, VECTOR *RotV)
- {
- double x1,y1,z1;
-
- x1=v->x; y1=v->y; z1=v->z;
- if(RotV->x!=0.0) Rotate2D(&y1,&z1,RotV->x);
- if(RotV->y!=0.0) Rotate2D(&z1,&x1,RotV->y);
- if(RotV->z!=0.0) Rotate2D(&x1,&y1,RotV->z);
- v->x=x1; v->y=y1; v->z=z1;
- }
-
-
- /* These routines will rotate in the reversed order (z,y,x). */
-
- void RevRotatePoint(POINT *p, VECTOR *RotV)
- {
- double x1,y1,z1;
-
- x1=p->x; y1=p->y; z1=p->z;
- if(RotV->z!=0.0) Rotate2D(&x1,&y1,RotV->z);
- if(RotV->y!=0.0) Rotate2D(&z1,&x1,RotV->y);
- if(RotV->x!=0.0) Rotate2D(&y1,&z1,RotV->x);
- p->x=x1; p->y=y1; p->z=z1;
- }
-
- void RevRotateVector(VECTOR *v, VECTOR *RotV)
- {
- double x1,y1,z1;
-
- x1=v->x; y1=v->y; z1=v->z;
- if(RotV->z!=0.0) Rotate2D(&x1,&y1,RotV->z);
- if(RotV->y!=0.0) Rotate2D(&z1,&x1,RotV->y);
- if(RotV->x!=0.0) Rotate2D(&y1,&z1,RotV->x);
- v->x=x1; v->y=y1; v->z=z1;
- }
-