[net.sources] basic ray tracing: part 4

fritzz@net1.UCSD.EDU (Friedrich Knauss) (07/26/86)

/*
 *   supportive subroutines...
 */
#include <math.h>
#include <stdio.h>
#include "rtd.h"

#include "extern.h"

double  dot (v1, v2)/* returns dot product of two vectors */
struct vector  *v1,
               *v2;
{
    double  r;
    r = v1 -> x * v2 -> x + v1 -> y * v2 -> y + v1 -> z * v2 -> z;
    return (r);
}

scamult (scal, vect)/* multiplies a vetcor by a scalar */
double  scal;
struct vector  *vect;
{
    vect -> x *= scal;
    vect -> y *= scal;
    vect -> z *= scal;
    vect -> l *= scal;
    vect -> xzl *= scal;
}

mv (x, y, z, _vp) /* loads a vector with given x,y,z values */
double  x,
        y,
        z;
struct vector  *_vp;
{
    _vp -> x = x;
    _vp -> y = y;
    _vp -> z = z;
}

sv (v1, v2, v3) /* vector subtraction: v1 = v2 - v3 */
struct vector  *v1,
               *v2,
               *v3;
{
    v1 -> x = v2 -> x - v3 -> x;
    v1 -> y = v2 -> y - v3 -> y;
    v1 -> z = v2 -> z - v3 -> z;
}

av (v1, v2, v3) /* vector addition: v1 = v2 + v3 */
struct vector  *v1,
               *v2,
               *v3;
{
    v1 -> x = v2 -> x + v3 -> x;
    v1 -> y = v2 -> y + v3 -> y;
    v1 -> z = v2 -> z + v3 -> z;
}

mt (vec, trans) 
/*  loads a transform matrix so that when vec is multiplied by it,
    the result is (1,0,0). it does so with out deforming space */
struct vector  *vec;
struct mat *trans;
{
    if (vec -> xzl == 0.0) {
	trans -> x.x = 0.0;
	trans -> x.y = 1.0;
	trans -> x.z = 0.0;
	trans -> y.x = -1.0;
	trans -> y.y = 0.0;
	trans -> y.z = 0.0;
	trans -> z.x = 0.0;
	trans -> z.y = 0.0;
	trans -> z.z = 1.0;
    }
    else {
	trans -> x.x = (vec -> x) / (vec -> l);
	trans -> x.y = (vec -> y) / (vec -> l);
	trans -> x.z = (vec -> z) / (vec -> l);
	trans -> y.x = -(vec -> x) * (vec -> y) / ((vec -> l) * (vec -> xzl));
	trans -> y.y = (vec -> xzl) / (vec -> l);
	trans -> y.z = -(vec -> z) * (vec -> y) / ((vec -> l) * (vec -> xzl));
	trans -> z.x = -(vec -> z) / (vec -> xzl);
	trans -> z.y = 0;
	trans -> z.z = (vec -> x) / (vec -> xzl);
    }
}

mt_vec (vc1, m, vc2)/* mutlipy vector by matrix: vc1 = m*vc2 */
struct vector  *vc1,
               *vc2;
struct mat *m;
{
    double  x,
            y,
            z;
    x = dot (&(m -> x), vc2);
    y = dot (&(m -> y), vc2);
    z = dot (&(m -> z), vc2);
    mv (x, y, z, vc1);
}

update (x, xmin, xmax)/* will update a file containing information on 
                         how we are coming along... useful for long runs*/
float   x,
        xmin,
        xmax;
{
    FILE * fff;
    static int  t;
    static double   size,
                    xm;
    int     tt,
            ttt,
            hr,
            min,
            sec;
    if (x == xmin) {
	fff = fopen ("time.update", "w");
	fprintf (fff, "starting...\n");
	fclose (fff);
	t = time (0);
	xm = xmin;
	size = (xmax - xmin);
    }
    else {
	x -= xm;
	tt = time (0) - t;
	ttt = (double) tt * size / x;
	tt = (double) tt * (size - x) / x;
	hr = tt / 3600;
	min = (tt % 3600) / 60;
	sec = tt % 60;
	fff = fopen ("time.update", "w");
	fprintf (fff, "%5.1f%% done.\n", 100.0 * x / size);
	fprintf (fff, "%d:%2d:%2d left.\n", hr, min, sec);
	hr = ttt / 3600;
	min = (ttt % 3600) / 60;
	sec = ttt % 60;
	fprintf (fff, "%d:%2d:%2d  total estimate.\n", hr, min, sec);
	fclose (fff);
    }
}

vecl (v) struct vector *v;
/* loads a vectors length... saves time to do this only when needed */
{
    v -> l = sqrt ((v -> x) * (v -> x) + (v -> y) * (v -> y) + (v -> z) * (v -> z));
}

vexzl (v) struct vector *v;
/* loads a vectors xz component. needed for mt */
{
    v -> xzl = sqrt ((v -> x) * (v -> x) + (v -> z) * (v -> z));
}