00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 static char *id="@(#) $Id: shdopg.c,v 1.2 2006/08/17 19:28:17 mhender Exp $";
00018
00019 #include <shInternal.h>
00020 #include <math.h>
00021 #include <stdio.h>
00022
00025 int SHmaxpol=0;
00026 float *SHx=(float*)NULL;
00027 float *SHy=(float*)NULL;
00028 float *SHz=(float*)NULL;
00029 int *SHi=(int*)NULL;
00030 int *SHj=(int*)NULL;
00031 int *SHk0=(int*)NULL;
00032 int *SHk1=(int*)NULL;
00033 int *SHke=(int*)NULL;
00034 float *SHo=(float*)NULL;
00035 float *SHs=(float*)NULL;
00036 float *SHxo=(float*)NULL;
00037 float *SHyo=(float*)NULL;
00038 float *SHzo=(float*)NULL;
00039 float *SHno=(float*)NULL;
00040 float *SHxs=(float*)NULL;
00041 float *SHys=(float*)NULL;
00042 float *SHzs=(float*)NULL;
00043 float *SHns=(float*)NULL;
00044 int *SHi0=(int*)NULL;
00045 float *SHx0=(float*)NULL;
00046 float *SHy0=(float*)NULL;
00047 float *SHz0=(float*)NULL;
00048 float *SHn0=(float*)NULL;
00049 float *SHs0=(float*)NULL;
00050 int *SHiflg=(int*)NULL;
00051
00063 void shdopg(int *nt,float *xt,float *yt,float *zt,float *n)
00064 {
00065
00066
00067
00068
00069 float nn[3]={1.,0.,0.};
00070 float t;
00071 float de0,de1;
00072
00073 float xx,yy,zz;
00074 float xxx=0.;
00075 float yyy=0.;
00076 float zzz=0.;
00077 float zbuf=0.;
00078
00079 int r=0;
00080 int g=0;
00081 int b=0;
00082 int nv,imax,jmax,imin,jmin;
00083 int m,mi,mj;
00084 int mleft,mright;
00085 int kt;
00086 int nedges;
00087 float an;
00088 int imask=0;
00089 int ipix,jpix;
00090
00091
00092
00093
00094
00095
00096 #ifdef VERBOSE
00097 printf(" shdopg n=%d\n",*nt);
00098 for(m=0;m<*nt;m++)
00099 {
00100 printf(" %d (%f,%f,%f) (%f,%f,%f)\n",m,xt[m],yt[m],zt[m],n[3*m],n[1+3*m],n[2+3*m]);
00101 fflush(stdout);
00102 }
00103 #endif
00104
00105 if(*nt>SHmaxpol)
00106 {
00107 SHmaxpol+=1000;
00108 SHx=(float*)realloc((void*)SHx,SHmaxpol*sizeof(float));
00109 if(SHx==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00110 SHy=(float*)realloc((void*)SHy,SHmaxpol*sizeof(float));
00111 if(SHy==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00112 SHz=(float*)realloc((void*)SHz,SHmaxpol*sizeof(float));
00113 if(SHz==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00114 SHi=(int*)realloc((void*)SHi,SHmaxpol*sizeof(int));
00115 if(SHi==(int*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00116 SHj=(int*)realloc((void*)SHj,SHmaxpol*sizeof(int));
00117 if(SHj==(int*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00118 SHk0=(int*)realloc((void*)SHk0,SHmaxpol*sizeof(int));
00119 if(SHk0==(int*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00120 SHk1=(int*)realloc((void*)SHk1,SHmaxpol*sizeof(int));
00121 if(SHk1==(int*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00122 SHke=(int*)realloc((void*)SHke,SHmaxpol*sizeof(int));
00123 if(SHke==(int*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00124 SHo=(float*)realloc((void*)SHo,SHmaxpol*sizeof(float));
00125 if(SHo==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00126 SHs=(float*)realloc((void*)SHs,SHmaxpol*sizeof(float));
00127 if(SHs==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00128 SHxo=(float*)realloc((void*)SHxo,SHmaxpol*sizeof(float));
00129 if(SHxo==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00130 SHyo=(float*)realloc((void*)SHyo,SHmaxpol*sizeof(float));
00131 if(SHyo==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00132 SHzo=(float*)realloc((void*)SHzo,SHmaxpol*sizeof(float));
00133 if(SHzo==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00134 SHno=(float*)realloc((void*)SHno,(2+3*SHmaxpol)*sizeof(float));
00135 if(SHno==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00136 SHxs=(float*)realloc((void*)SHxs,SHmaxpol*sizeof(float));
00137 if(SHxs==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00138 SHys=(float*)realloc((void*)SHys,SHmaxpol*sizeof(float));
00139 if(SHys==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00140 SHzs=(float*)realloc((void*)SHzs,SHmaxpol*sizeof(float));
00141 if(SHzs==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00142 SHns=(float*)realloc((void*)SHns,(2+3*SHmaxpol)*sizeof(float));
00143 if(SHns==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00144 SHi0=(int*)realloc((void*)SHi0,SHmaxpol*sizeof(int));
00145 if(SHi0==(int*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00146 SHx0=(float*)realloc((void*)SHx0,SHmaxpol*sizeof(float));
00147 if(SHx0==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00148 SHy0=(float*)realloc((void*)SHy0,SHmaxpol*sizeof(float));
00149 if(SHy0==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00150 SHz0=(float*)realloc((void*)SHz0,SHmaxpol*sizeof(float));
00151 if(SHz0==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00152 SHn0=(float*)realloc((void*)SHn0,(2+3*SHmaxpol)*sizeof(float));
00153 if(SHn0==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00154 SHs0=(float*)realloc((void*)SHs0,SHmaxpol*sizeof(float));
00155 if(SHs0==(float*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00156 SHiflg=(int*)realloc((void*)SHiflg,SHmaxpol*sizeof(int));
00157 if(SHiflg==(int*)NULL){fprintf(stderr,"shdopg: out of memory!");fflush(stderr);return;}
00158 }
00159
00160 nv=*nt;
00161 if(fabs(xt[0]-xt[nv-1])+fabs(yt[0]-yt[nv-1])+fabs(zt[0]-zt[nv-1])<3.e-7)nv--;
00162
00163 imax=0;
00164 jmax=0;
00165 imin=shIMax;
00166 jmin=shJMax;
00167 for(m=0;m<nv;m++)
00168 {
00169 shpers(xt+m,yt+m,zt+m,SHx+m,SHy+m,SHz+m);
00170 SHi[m]=SHx[m]*shMax+.5;
00171 SHj[m]=SHy[m]*shMax+.5;
00172 SHk0[m]=m;
00173 SHk1[m]=m+1;
00174 if(m==nv-1)SHk1[m]=0;
00175 if(SHi[m]>imax)imax=SHi[m];
00176 if(SHj[m]>jmax)jmax=SHj[m];
00177 if(SHi[m]<imin)imin=SHi[m];
00178 if(SHj[m]<jmin)jmin=SHj[m];
00179 }
00180
00181 #ifdef VERBOSE
00182 printf(" shdopg n=%d\n",nv);
00183 for(m=0;m<nv;m++)
00184 {
00185 printf(" %d (%d,%d)\n",m,SHi[m],SHj[m]);
00186 fflush(stdout);
00187 }
00188 #endif
00189
00190
00191
00192 if((imax<0||imin>=shIMax||jmax<0||jmin>=shJMax))
00193 {
00194 #ifdef VERBOSE
00195 printf(" done shdopg -- polygon out of range (%d,%d)->(%d,%d), (0,0)->(%d,%d)\n",imin,jmin,imax,jmax,shIMax,shJMax);
00196 #endif
00197 return;
00198 }
00199
00200 if(jmax==jmin||nv<3)
00201 {
00202 shpl(&nv,xt,yt,zt);
00203 #ifdef VERBOSE
00204 printf(" done shdopg -- too few vertices, or horiSHzontal line, nv=%d, j in (%d,%d)\n",nv,jmin,jmax);
00205 #endif
00206 return;
00207 }
00208
00209
00210
00211 for(m=0;m<nv;m++)
00212 {
00213 if(SHj[SHk0[m]]>SHj[SHk1[m]])
00214 {
00215 kt=SHk0[m];
00216 SHk0[m]=SHk1[m];
00217 SHk1[m]=kt;
00218 }
00219 }
00220
00221
00222
00223 for(mi=0;mi<nv-1;mi++)
00224 {
00225 for(mj=mi+1;mj<nv;mj++)
00226 {
00227 if(SHj[SHk0[mj]]<SHj[SHk0[mi]])
00228 {
00229 kt=SHk0[mi];
00230 SHk0[mi]=SHk0[mj];
00231 SHk0[mj]=kt;
00232 kt=SHk1[mi];
00233 SHk1[mi]=SHk1[mj];
00234 SHk1[mj]=kt;
00235 }
00236 }
00237 }
00238
00239 #ifdef VERBOSE
00240 printf(" shdopg edges\n");
00241 for(m=0;m<nv;m++)
00242 {
00243 printf(" %d (%d,%d) (%f,%f,%f)->(%f,%f,%f)\n",m,SHk0[m],SHk1[m],SHx[SHk0[m]],SHy[SHk0[m]],SHz[SHk0[m]],SHx[SHk1[m]],SHy[SHk1[m]],SHz[SHk1[m]]);
00244 fflush(stdout);
00245 }
00246 #endif
00247
00248
00249
00250 for(m=0;m<nv;m++)
00251 {
00252 an=sqrt(n[3*m]*n[3*m]+n[1+3*m]*n[1+3*m]+n[2+3*m]*n[2+3*m]);
00253 if(fabs(an)<1.e-6)
00254 {
00255 shpl(&nv,xt,yt,zt);
00256 #ifdef VERBOSE
00257 printf(" done shdopg -- flat line m=%d, n=(%f,%f,%f), |n|=%f\n",m,n[3*m],n[1+3*m],n[2+3*m],an);
00258 #endif
00259 return;
00260 }else{
00261 an=1./an;
00262 n[3*m]=n[3*m]*an;
00263 n[1+3*m]=n[1+3*m]*an;
00264 n[2+3*m]=n[2+3*m]*an;
00265 }
00266
00267
00268
00269
00270
00271
00272 if(SHj[SHk1[m]]==SHj[SHk0[m]])
00273 {
00274 SHs[m]=0.;
00275 SHxs[m]=0.;
00276 SHys[m]=0.;
00277 SHzs[m]=0.;
00278 SHns[3*m]=0;
00279 SHns[1+3*m]=0;
00280 SHns[2+3*m]=0;
00281 }else{
00282 t=1./(float)(SHj[SHk1[m]]-SHj[SHk0[m]]);
00283 SHs[m]= (SHi[SHk1[m]]-SHi[SHk0[m]])*t;
00284 SHxs[m]= (SHx[SHk1[m]]-SHx[SHk0[m]])*t;
00285 SHys[m]= (SHy[SHk1[m]]-SHy[SHk0[m]])*t;
00286 SHzs[m]= (SHz[SHk1[m]]-SHz[SHk0[m]])*t;
00287 SHns[3*m]= (n[ 3*SHk1[m]]-n[ 3*SHk0[m]])*t;
00288 SHns[1+3*m]=(n[1+3*SHk1[m]]-n[1+3*SHk0[m]])*t;
00289 SHns[2+3*m]=(n[2+3*SHk1[m]]-n[2+3*SHk0[m]])*t;
00290 }
00291 SHo[m]= SHi[SHk0[m]]-SHj[SHk0[m]]*SHs[m];
00292 SHxo[m]= SHx[SHk0[m]]-SHj[SHk0[m]]*SHxs[m];
00293 SHyo[m]= SHy[SHk0[m]]-SHj[SHk0[m]]*SHys[m];
00294 SHzo[m]= SHz[SHk0[m]]-SHj[SHk0[m]]*SHzs[m];
00295 SHno[3*m]= n[ 3*SHk0[m]]-SHj[SHk0[m]]*SHns[3*m];
00296 SHno[1+3*m]=n[1+3*SHk0[m]]-SHj[SHk0[m]]*SHns[1+3*m];
00297 SHno[2+3*m]=n[2+3*SHk0[m]]-SHj[SHk0[m]]*SHns[2+3*m];
00298 }
00299
00300 #ifdef VERBOSE
00301 printf(" shdopg equations\n");
00302 for(m=0;m<nv;m++)
00303 {
00304 printf(" %4.4d s %f, SHxs (%f,%f,%f), SHns (%f,%f,%f)\n",m,SHs[m],SHxs[m],SHys[m],SHzs[m],SHns[3*m],SHns[1+3*m],SHns[2+3*m]);
00305 printf(" o %f, SHxo (%f,%f,%f), SHno (%f,%f,%f)\n",SHo[m],SHxo[m],SHyo[m],SHzo[m],SHno[3*m],SHno[1+3*m],SHno[2+3*m]);
00306 fflush(stdout);
00307 }
00308 #endif
00309
00310
00311
00312 for(jpix=jmin;jpix<=jmax;jpix++)
00313 {
00314
00315
00316
00317 mleft=0;
00318 mright=nv-1;
00319 for(m=0;m<nv;m++)
00320 {
00321 if(SHj[SHk1[mleft]]<jpix)mleft++;
00322 if(SHj[SHk0[mright]]>jpix)mright--;
00323 }
00324
00325
00326
00327 #ifdef VERBOSE
00328 printf("scan line %d, left %d, right %d\n",jpix,mleft,mright);
00329 fflush(stdout);
00330 #endif
00331
00332 nedges=0;
00333 for(m=mleft;m<=mright;m++)
00334 {
00335 if(SHj[SHk1[m]]>=jpix)
00336 {
00337 if(SHj[SHk1[m]]==jpix&&SHj[SHk0[m]]==jpix)
00338 {
00339 SHi0[nedges]= SHi[SHk0[m]];
00340 SHiflg[nedges]=3;
00341 SHs0[nedges]=fabs( SHi[SHk1[m]] - SHi[SHk0[m]] )+.5;
00342 SHx0[nedges]=SHx[SHk0[m]];
00343 SHy0[nedges]=SHy[SHk0[m]];
00344 SHz0[nedges]=SHz[SHk0[m]];
00345 SHn0[3*nedges]=n[3*SHk0[m]];
00346 SHn0[1+3*nedges]=n[1+3*SHk0[m]];
00347 SHn0[2+3*nedges]=n[2+3*SHk0[m]];
00348 SHke[nedges]=nedges;
00349 nedges++;
00350
00351 SHi0[nedges]= SHi[SHk1[m]];
00352 SHiflg[nedges]=3;
00353 SHs0[nedges]=fabs( SHi[SHk1[m]] - SHi[SHk0[m]] )+.5;
00354 SHx0[nedges]=SHx[SHk1[m]];
00355 SHy0[nedges]=SHy[SHk1[m]];
00356 SHz0[nedges]=SHz[SHk1[m]];
00357 SHn0[3*nedges]=n[3*SHk1[m]];
00358 SHn0[1+3*nedges]=n[1+3*SHk1[m]];
00359 SHn0[2+3*nedges]=n[2+3*SHk1[m]];
00360 SHke[nedges]=nedges;
00361 nedges++;
00362 }else{
00363 SHiflg[nedges]=0;
00364 if(SHj[SHk1[m]]==jpix)SHiflg[nedges]=1;
00365 if(SHj[SHk0[m]]==jpix)SHiflg[nedges]=2;
00366 if(SHo[m]+jpix*SHs[m]>=0.)
00367 SHi0[nedges]= SHo[m]+jpix* SHs[m]+.5;
00368 else
00369 SHi0[nedges]= SHo[m]+jpix* SHs[m]-.5;
00370 if(SHj[SHk1[m]]==SHj[SHk0[m]])
00371 {
00372 fprintf(stderr," divide by zero in shpgnrm, SHj[%d]=SHj[%d]=%d, jpix=%d\n",SHk1[m],SHk0[m],SHj[SHk0[m]],jpix);
00373 abort();
00374 }
00375 SHs0[nedges]=fabs((SHi[SHk1[m]]-SHi[SHk0[m]])/(float)(SHj[SHk1[m]]-SHj[SHk0[m]]));
00376 SHx0[nedges]=SHxo[m]+jpix*SHxs[m];
00377 SHy0[nedges]=SHyo[m]+jpix*SHys[m];
00378 SHz0[nedges]=SHzo[m]+jpix*SHzs[m];
00379 SHn0[3*nedges]=SHno[3*m]+jpix*SHns[3*m];
00380 SHn0[1+3*nedges]=SHno[1+3*m]+jpix*SHns[1+3*m];
00381 SHn0[2+3*nedges]=SHno[2+3*m]+jpix*SHns[2+3*m];
00382 SHke[nedges]=nedges;
00383 nedges++;
00384 }
00385 }
00386 }
00387
00388
00389
00390 for(mi=0;mi<nedges;mi++)
00391 {
00392 for(mj=mi+1;mj<nedges;mj++)
00393 {
00394 if(SHi0[SHke[mj]]<SHi0[SHke[mi]])
00395 {
00396 kt=SHke[mi];
00397 SHke[mi]=SHke[mj];
00398 SHke[mj]=kt;
00399 }
00400 if(SHi0[SHke[mj]]==SHi0[SHke[mi]]&&SHiflg[SHke[mj]]<SHiflg[SHke[mi]])
00401 {
00402 kt=SHke[mi];
00403 SHke[mi]=SHke[mj];
00404 SHke[mj]=kt;
00405 }
00406 }
00407 }
00408
00409
00410
00411 mi=0;
00412 while(mi<nedges-1)
00413 {
00414 if(SHi0[SHke[mi]]==SHi0[SHke[mi+1]]&&SHiflg[SHke[mi]]!=0&&SHiflg[SHke[mi+1]]!=0&&SHiflg[SHke[mi]]!=SHiflg[SHke[mi+1]])
00415 {
00416 if(SHs0[SHke[mi+1]]>SHs0[SHke[mi]])SHs0[SHke[mi]]=SHs0[SHke[mi+1]];
00417 SHs0[SHke[mi+1]]=SHs0[SHke[mi]];
00418 for(mj=mi+1;mj<nedges;mj++)SHke[mj]=SHke[mj+1];
00419 nedges--;
00420 }else{
00421 mi++;
00422 }
00423 }
00424
00425
00426
00427 for(m=0;m<nedges;m+=2)
00428 {
00429 de0=.5+SHs0[SHke[m]];
00430 de1=.5+SHs0[SHke[m+1]];
00431 for(ipix=SHi0[SHke[m]];ipix<=SHi0[SHke[m+1]];ipix++)
00432 {
00433 if(ipix>-1&&ipix<shIMax&&jpix>-1&&jpix<shJMax)
00434 {
00435
00436
00437
00438 if(SHi0[SHke[m]]==SHi0[SHke[m+1]])
00439 {
00440 xx=SHx0[SHke[m]];
00441 yy=SHy0[SHke[m]];
00442 zz=SHz0[SHke[m]];
00443 nn[0]=SHn0[3*SHke[m]];
00444 nn[1]=SHn0[1+3*SHke[m]];
00445 nn[2]=SHn0[2+3*SHke[m]];
00446 }else{
00447 t=(float)(ipix-SHi0[SHke[m]])/(float)(SHi0[SHke[m+1]]-SHi0[SHke[m]]);
00448 xx=SHx0[SHke[m]]+t*(SHx0[SHke[m+1]]-SHx0[SHke[m]]);
00449 yy=SHy0[SHke[m]]+t*(SHy0[SHke[m+1]]-SHy0[SHke[m]]);
00450 zz=SHz0[SHke[m]]+t*(SHz0[SHke[m+1]]-SHz0[SHke[m]]);
00451 nn[0]=SHn0[3*SHke[m]]+t*(SHn0[3*SHke[m+1]]-SHn0[3*SHke[m]]);
00452 nn[1]=SHn0[1+3*SHke[m]]+t*(SHn0[1+3*SHke[m+1]]-SHn0[1+3*SHke[m]]);
00453 nn[2]=SHn0[2+3*SHke[m]]+t*(SHn0[2+3*SHke[m+1]]-SHn0[2+3*SHke[m]]);
00454 }
00455 an=sqrt(nn[0]*nn[0]+nn[1]*nn[1]+nn[2]*nn[2]);
00456 if(fabs(an)<1.e-7)
00457 {
00458 nn[0]=SHn0[3*SHke[m]];
00459 nn[1]=SHn0[1+3*SHke[m]];
00460 nn[2]=SHn0[2+3*SHke[m]];
00461 an=sqrt(nn[0]*nn[0]+nn[1]*nn[1]+nn[2]*nn[2]);
00462 nn[0]=nn[0]*an;
00463 nn[1]=nn[1]*an;
00464 nn[2]=nn[2]*an;
00465 }else{
00466 an=1./an;
00467 nn[0]=nn[0]*an;
00468 nn[1]=nn[1]*an;
00469 nn[2]=nn[2]*an;
00470 }
00471
00472 shunpers(&xx,&yy,&zz,&xxx,&yyy,&zzz);
00473
00474
00475
00476 shgetz(&ipix,&jpix,&zbuf);
00477 #ifdef VERBOSE
00478 printf("shgetz %d,%d %f %f\n",ipix,jpix,zbuf,zz);fflush(stdout);
00479 #endif
00480 if(zbuf>zz)
00481 {
00482
00483
00484
00485 shcolor(&xxx,&yyy,&zzz,nn,&(sh_rd[0]),&(sh_gd[0]),&(sh_bd[0]),&(sh_rd[2]),&(sh_gd[2]),&(sh_bd[2]),&r,&g,&b);
00486 #ifdef VERBOSE
00487 printf("shcolor, x-( %f %f %f ) n-( %f %f %f ) fc-(%d %d %d ) bc-(%d %d %d) c %d %d %d\n",xxx,yyy,zzz,nn[0],nn[1],nn[2],sh_rd[0],sh_gd[0],sh_bd[0],sh_rd[2],sh_gd[2],sh_bd[2],r,g,b);
00488 #endif
00489
00490 if(shMask)
00491 {
00492 sh3dmask(&xxx,&yyy,&zzz,nn,&imask);
00493 if(imask==1)shsetp(&ipix,&jpix,&r,&g,&b,&zz);
00494 }else{
00495 shsetp(&ipix,&jpix,&r,&g,&b,&zz);
00496 }
00497 }
00498 }
00499 }
00500 }
00501 }
00502
00503 #ifdef VERBOSE
00504 printf(" done shdopg -- normal end\n");
00505 #endif
00506 return;
00507 }