#include #include "rtd.h" #include "extern.h" /* find where a ray leaves a sphere */ double findo (m, s) struct mat *m; struct sphere *s; { struct vector foops; double t; /* foops is the rotated vector for the center of the sphere with respect to the beginning of the ray */ mt_vec (&foops, m, &(s->cent)); /* find out if the center of the sphere is within range. (it should be for this...)*/ t = s->rad * s->rad - foops.y * foops.y - foops.z * foops.z; /*return distance from original entry. we can find the point when we get out*/ if (t > 0) t = foops.x + sqrt (t); else t = 0; return (t); } /* find where a ray next hits (enters or exits) a sphere */ double findx (m, s) struct mat *m; struct sphere *s; { struct vector foops; double t; /* foops is the rotated vector for the center of the sphere with respect to the beginning of the ray */ mt_vec (&foops, m, &s->cent); t = s->rad*s->rad - foops.y*foops.y - foops.z*foops.z; if (t < 0) t = HUGE; /* doesn't touch, return flag */ else { t = sqrt(t); if (foops.x > t + EPSILON) t = foops.x - t; /* return distance to entering */ else if (foops.x > - t + EPSILON) t = -foops.x - t; /* return minus distance to exiting */ else t = HUGE; } return (t); } /* see above. the only difference is that the value returned is foops.x - sqrt(t) */ double find (m, s) struct mat *m; struct sphere *s; { struct vector foops; double t; mt_vec (&foops, m, &(s->cent)); t = s->rad * s->rad - foops.y * foops.y - foops.z * foops.z; if (t > 0) t = foops.x - sqrt (t); else t = 0; return (t); } /* returns value telling how much a sphere is occluding the light source */ double finds (m, s) struct mat *m; struct sphere *s; { struct vector foops; double t; mt_vec (&foops, m, &(s->cent)); t = s->rad - sqrt (foops.y * foops.y + foops.z * foops.z); if (t > 0) t = t / foops.x; else t = 0; return (t); /* radians between ray and edge of intersecting sphere*/ } /* gets amount of diffuse light hitting a point */ float shadow (p, rd, gn, blu) struct vector *p; double *rd, *gn, *blu; { struct mat trans; struct sphere ss; struct vector d; int c, i; double l, k, x, y, z, finds (); l = 0.0; c = -1; sv (&d, &(ls.cent), p); vecl (&d); /*!!*/ vexzl (&d); /*!!*/ mt (&(d), &trans); /* get maximum obscurment */ for (i = 0; i < nob; i++) { ss.rad = bl[i].s.rad; sv (&(ss.cent), &(bl[i].s.cent), p); if ((k = finds (&trans, &ss)) > l) { c = i; l = k; } } if (c == -1) k = 255.0; else { k = 1.0 - l * d.l / ls.rad; if (k < 0.0) /* l = angle to move to get ray out of sphere*/ k = 0.0; /* d.l/ls.rad = 1/angle light source subtends */ else k *= 255.0; } *rd = *gn = *blu = k; /* all colors the same for now */ }