The only difference between visibility and illumination, in the scheme of parallel projection used by GEOM, lies in the direction of view. Therefore maintaining a double calculation, one for each direction, yields criteria for suppressing (or changing the color of) the picture elements representing the spherical surface.
/* shadsf - present a family of spheres in color */ /* s[n][7] - family of spheres */ /* u[3][3] - direction of shadow */ /* t[n] - color codes */ void shadsf(s,t,u,n) double s[][7], u[3][3]; int *t, n; { int i, j, k, m, mi; double b1, b2, g, th, dh, ri; double emi, p[3], q[3], a[3], b[3], o[3][3]; g=(double)sspch; for (i=0; i<n; i++) { ri=s[i][3]; emi=((double)sslen)*ri; mi=(int)emi; dh=3.14159/emi; th=0.0; spheu(o,&s[i][4]); for (k=0; k<mi; k++) { th+=dh; sphrv(a,ri,th,g*th); sphmv(p,o,a); if (p[1]>0.0) continue; sphmv(q,u,p); if (q[1]>0.0) continue; sphvs(p,p,&s[i][0]); sphmv(b,u,p); m=1; for (j=0; j<n; j++) { if (i==j) continue; sphdj(&b1,&b2,p,&s[j][0],s[j][3]); if (b1<0.0) {m=0; break;} if (p[1]<=s[j][1]) continue; if (b2<=0.0) {m=0; break;} sphmv(q,u,&s[j][0]); sphdj(&b1,&b2,b,q,s[j][3]); if (b1<0.0) {m=0; break;} if (b[1]<=q[1]) continue; if (b2<=0.0) {m=0; break;} } /* end for j */ // geomms(p[0],p[2],m,t[i]); pltms(p[0],p[2],m); } /* end for k */ // if (kbdst()) {kbdin(); break;} } /* end for i */ }