home *** CD-ROM | disk | FTP | other *** search
- /*** contour.c ***/
-
- #include <stdio.h>
- #include <strings.h>
- #include <math.h>
- #include "common.h"
- #include "contour.h"
- #include "plot.h"
- #include "Xdefs.h"
-
- /* print out a single contour */
- draw_cont()
- {
- FILE *fopen(), *ict;
- extern double cont_level;
- extern double xmin,xmax,ymin,ymax;
- extern plotptr plot_listhead;
- int npts=0,ncurves=0;
- nodeptr N;
- plotptr P;
-
- /* print out info about the image read in */
- fprintf(stdout," Maximum z-value = %f\n",zmax);
- fprintf(stdout," Minimum z-value = %f\n",zmin);
-
- /* check the desired contour level */
- if ((zmin > cont_level) || (cont_level > zmax)) {
- fprintf(stderr,"Error : The desired contour level %.2f",cont_level);
- fprintf(stderr,"is not within the surface\n");
- } else {
- /* now find the desired contours and print it out */
- find_contour(cont_level);
-
- /* open up the file */
- if ((ict = fopen(CTFILE,"w")) == NULL) {
- fprintf(stderr,"cat: can't open %s\n",CTFILE);
- exit(1);
- }
- /* count the number of curves */
- for (P=plot_listhead; P!=NULL; P=P->next) ncurves++;
-
- /* output the x-y limits and the number of curves */
- fprintf(ict,"%10.5f %10.5f %10.5f %10.5f\n",xmin,xmax,ymin,ymax);
- fprintf(ict,"%10.5f\n",(double)ncurves);
-
- /* print out the data for each contour */
- for (P=plot_listhead; P!=NULL; P=P->next) {
- /* count the number of points first */
- npts = 0;
- for (N=P->nodehead; N!=NULL; N=N->next) npts++;
- /* now print out the info */
- fprintf(ict,"%10.5f\n",(double)npts);
- for (N=P->nodehead; N!=NULL; N=N->next)
- fprintf(ict,"%10.5f %10.5f\n",N->pt.x,N->pt.y);
- }
-
- /* finished */
- fprintf(stdout," The x-y points of the %.2f contour ",cont_level);
- fprintf(stdout,"has been printed in \"%s\"\n",CTFILE);
- }
- }
-
- /* draw the contours */
- draw_view(argc,argv)
- int argc;
- char *argv[];
- {
- FILE *fopen(), *ips;
- char *sprintf();
- float rdfloat();
- extern double zmin, zmax;
- double level,cstep;
- char c, command[MAXCHAR];
- int nsteps;
- int FOUND=FALSE;
-
- /* find all the contours first */
- fprintf(stdout," Maximum z-value = %f\n",zmax);
- fprintf(stdout," Minimum z-value = %f\n",zmin);
-
- /* ask for the contour step size */
- while (!FOUND) {
- fprintf(stdout," Enter contour step size :");
- fscanf(stdin,"%lf",&cstep);
- while ( (c=getc(stdin)) != '\n');
- if (cstep < SMALL)
- fprintf(stdout,"Error : Step size %10f is too small\n",cstep);
- else {
- nsteps = (zmax-zmin)/cstep;
- if (nsteps < 1)
- fprintf(stdout," Error : Too few contours %d\n",nsteps);
- else if (nsteps > 50 && nsteps < 100) {
- fprintf(stdout," Warning:%d contour steps will be made\n",nsteps);
- fprintf(stdout," Type return (or n/q) to continue :");
- if ( (c=getc(stdin)) == '\n' || c == 'y' || c == 'Y' )
- FOUND = TRUE;
- else if (c == 'q')
- exit(1);
- if (c != '\n') while ( (c=getc(stdin)) != '\n');
- } else if (nsteps >= 100)
- fprintf(stdout," Error : Too many contours %d\n",nsteps);
- else
- FOUND = TRUE;
- }
- }
- fprintf(stdout," Contour step size = %f\n",cstep);
- fprintf(stdout," Number of contours = %d\n",nsteps);
-
- /* now find the contours */
- level = (int)(zmin/cstep)*cstep + cstep;
- while (level <= zmax+SMALL) {
- find_contour(level);
- level += cstep;
- }
-
- /* now draw the plots */
- if ( (strcmp("xterm",term)==0) ||
- (strcmp("xterms",term)==0) ||
- (strcmp("vt200",term)==0) ||
- (strcmp("vt220",term)==0) ||
- (strcmp("vs100s",term)==0) ) {
- InitWindow(argc,argv);
- RunOps();
- }
-
- /* hp2648 procedures */
- if ((strcmp("hp2648",term)==0) || (strcmp("2648",term)==0)) {
- axeshp();
- plothp();
- endgrhp();
- }
-
- /* Postscript plot */
- if (postscript == ON) {
- if ((ips = fopen(PSFILE,"w")) == NULL) {
- fprintf(stderr,"cat: can't open %s\n",PSFILE);
- exit(1);
- }
- initps(ips);
- axesps(ips);
- plotps(ips);
- endgrps(ips);
- }
-
- /* Get postscript printout */
- if (postscript == ON && printplot == ON) {
- fprintf(stdout," Type return (or n/q) to ");
- fprintf(stdout,"send the plot to the %s printer :",printer);
- if ( (c=getc(stdin)) == '\n' || c == 'y' || c == 'Y' ) {
- sprintf(command,"%s %s %s","lpr",printer,PSFILE);
- system(command);
- fprintf(stdout," Postscript file has been ");
- fprintf(stdout,"sent to the %s printer\n",printer);
- } else if (c == 'q')
- exit(1);
- if (c != '\n') while ( (c=getc(stdin)) != '\n');
- }
- }
-
- /* find all the segments that are formed when triangle intersects z=level */
- find_contour(level)
- double level;
- {
- void delete_segm();
- plotptr insert_plot();
- nodeptr insert_tailnode();
- extern triaptr tria_listhead;
- extern segmptr segm_listhead;
- triaptr T;
- segmptr S;
- plotptr P;
- data PT1,PT2;
-
- for (T=tria_listhead; T!=NULL; T=T->next)
- find_intsct(level,T);
-
- /* now sort out these segments */
- /* start with the segmhead */
- while ((S=segm_listhead)!=NULL) {
- P = insert_plot(level);
- PT1 = S->pt1;
- PT2 = S->pt2;
- insert_tailnode(&PT1,P);
- insert_tailnode(&PT2,P);
- delete_segm(S);
- add_to_tailplot(&PT2,P);
- add_to_headplot(&PT1,P);
- }
- }
-
- /* add to the tail of the plot list */
- add_to_tailplot(pt,P)
- data *pt;
- plotptr P;
- {
- void delete_segm();
- nodeptr insert_tailnode();
- segmptr matching_segm();
- segmptr S;
-
- /* add the further node at every loop iteration */
- while ((S=matching_segm(pt))!=NULL) {
- if (longline(&(S->pt1),pt) ) {
- insert_tailnode(&(S->pt1),P);
- *pt = S->pt1;
- } else {
- insert_tailnode(&(S->pt2),P);
- *pt = S->pt2;
- }
- delete_segm(S);
- }
- return;
- }
-
- /* add to the head of the plot list */
- add_to_headplot(pt,P)
- data *pt;
- plotptr P;
- {
- void delete_segm();
- nodeptr insert_headnode();
- segmptr matching_segm();
- segmptr S;
-
- /* add the further node at every loop iteration */
- while ((S=matching_segm(pt))!=NULL) {
- if (longline(&(S->pt1),pt) ) {
- insert_headnode(&(S->pt1),P);
- *pt = S->pt1;
- } else {
- insert_headnode(&(S->pt2),P);
- *pt = S->pt2;
- }
- delete_segm(S);
- }
- return;
- }
-
- /* Return segment containing data point that matches a given point */
- segmptr matching_segm(pt)
- data *pt;
- {
- int longline();
- extern segmptr segm_listhead;
- segmptr S,SF;
- int FOUND = FALSE;
-
- /* check lengths of lines */
- for (S=segm_listhead; S!=NULL && !FOUND; S=S->next) {
- /* check the first point */
- if (fabs(S->pt1.x - pt->x) < SMALL)
- FOUND = !(longline(&(S->pt1),pt));
- if (!FOUND) {
- /* now check the second point */
- if (fabs(S->pt2.x - pt->x) < SMALL)
- FOUND = !(longline(&(S->pt2),pt));
- }
- if (FOUND) SF = S;
- }
-
- /* return the segment */
- if (!FOUND) SF = NULL;
- return(SF);
- }
-
- /* find the segment of intersection between a triangle and a plane */
- find_intsct(level,T)
- double level;
- triaptr T;
- {
- int longline();
- int plane_intsct_tria();
- int plane_intsct_line();
- segmptr insert_segm();
- data intpts[3],pta;
- int i=0;
- segmptr newptr;
-
- if (plane_intsct_tria(level,T)) {
- if (plane_intsct_line(level,T->pt1,T->pt2,&pta)) intpts[i++] = pta;
- if (plane_intsct_line(level,T->pt2,T->pt3,&pta)) intpts[i++] = pta;
- if (plane_intsct_line(level,T->pt3,T->pt1,&pta)) intpts[i++] = pta;
- if (i==3) {
- /* only way is to have plane intersect tria at one of the nodes */
- if (longline(&(intpts[0]),&(intpts[1])))
- insert_segm(&(intpts[0]),&(intpts[1]));
- else if (longline(&(intpts[1]),&(intpts[2])))
- insert_segm(&(intpts[1]),&(intpts[2]));
- else if (longline(&(intpts[2]),&(intpts[0])))
- insert_segm(&(intpts[2]),&(intpts[0]));
- else
- fprintf(stderr,"Warning: Zero segment length\n");
- } else if (i!=2)
- fprintf(stderr,"Warning: Nonstandard No of intersections = %5d\n",i);
- else if (longline(&(intpts[0]),&(intpts[1])))
- newptr = insert_segm(&(intpts[0]),&(intpts[1]));
- else
- fprintf(stderr,"Warning: Zero segment length\n");
- }
- }
-
- /* find out if a line segment is long or short */
- int longline(pta,ptb)
- data *pta,*ptb;
- {
- int longln = TRUE;
- double dl,dx,dy,dz;
-
- dx = pta->x - ptb->x;
- dy = pta->y - ptb->y;
- dz = pta->z - ptb->z;
- dl = dx*dx + dy*dy + dz*dz;
- if (dl < SMALLER) longln = FALSE;
- return(longln);
- }
-
- /* find out the intersection point between a line and a z-plane */
- int plane_intsct_line(z,pt1,pt2,pt3)
- double z;
- data pt1,pt2,*pt3;
- {
- int intsct = TRUE;
- double t;
-
- if ((pt1.z > z && pt2.z > z) ||
- (pt1.z < z && pt2.z < z) ||
- (fabs(pt1.z-pt2.z) < SMALL) )
- intsct = FALSE;
- if (intsct) {
- t = (z - pt1.z)/(pt2.z-pt1.z);
- pt3->x = pt1.x + (pt2.x-pt1.x)*t;
- pt3->y = pt1.y + (pt2.y-pt1.y)*t;
- pt3->z = z;
- }
- return(intsct);
- }
-
- /* find out if the triangle intersects the plane */
- int plane_intsct_tria(z,T)
- double z;
- triaptr T;
- {
- int intsct = TRUE;
- double z1,z2,z3;
-
- z1 = T->pt1.z;
- z2 = T->pt2.z;
- z3 = T->pt3.z;
- if ((z1>z && z2>z && z3>z) || (z1<z && z2<z && z3<z))
- intsct = FALSE;
- return(intsct);
- }
-
-