--- ray/src/rt/srcsupp.c 1991/06/21 16:44:01 1.4 +++ ray/src/rt/srcsupp.c 1991/06/25 13:11:55 1.6 @@ -168,24 +168,27 @@ FVECT ocent; OBJREC *op; { double maxrad2; - double d2; + double d; register int i, j; register FACE *f; f = getface(op); + if (f->area == 0.) + return(0.); for (i = 0; i < 3; i++) { ocent[i] = 0.; for (j = 0; j < f->nv; j++) ocent[i] += VERTEX(f,j)[i]; ocent[i] /= (double)f->nv; } - if (f->area == 0.) - return(0.); + d = DOT(ocent,f->norm); + for (i = 0; i < 3; i++) + ocent[i] += (f->offset - d)*f->norm[i]; maxrad2 = 0.; for (j = 0; j < f->nv; j++) { - d2 = dist2(VERTEX(f,j), ocent); - if (d2 > maxrad2) - maxrad2 = d2; + d = dist2(VERTEX(f,j), ocent); + if (d > maxrad2) + maxrad2 = d; } return(maxrad2); } @@ -289,6 +292,52 @@ FVECT nrm; /* source surface normal */ /* else check horizon */ d1 = 1. - sp->siz/(2.*PI); return(1.-FTINY-d*d > d1*d1); +} + + +double +spotdisk(oc, op, sp, pos) /* intersect spot with object op */ +FVECT oc; +OBJREC *op; +register SPOT *sp; +FVECT pos; +{ + FVECT onorm; + double offs, d, dist; + register int i; + + offs = getplaneq(onorm, op); + d = -DOT(onorm, sp->aim); + if (d >= -FTINY && d <= FTINY) + return(0.); + dist = (DOT(pos, onorm) - offs)/d; + if (dist < 0.) + return(0.); + for (i = 0; i < 3; i++) + oc[i] = pos[i] + dist*sp->aim[i]; + return(sp->siz*dist*dist/PI/(d*d)); +} + + +double +beamdisk(oc, op, sp, dir) /* intersect beam with object op */ +FVECT oc; +OBJREC *op; +register SPOT *sp; +FVECT dir; +{ + FVECT onorm; + double offs, d, dist; + register int i; + + offs = getplaneq(onorm, op); + d = -DOT(onorm, dir); + if (d >= -FTINY && d <= FTINY) + return(0.); + dist = (DOT(sp->aim, onorm) - offs)/d; + for (i = 0; i < 3; i++) + oc[i] = sp->aim[i] + dist*dir[i]; + return(sp->siz/PI/(d*d)); }