⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zbufsort.c

📁 很经典的电磁计算(电容计算)软件 MIT90年代开发
💻 C
📖 第 1 页 / 共 3 页
字号:
  /* a larger alpha => greater distance from view plane */  /* => fac is deeper than facref if alpha_fac > alpha_facref */  /*     (ie if alpha_facref - alpha_fac < 0) */  /* => facref is deeper than fac if alpha_facref > alpha_fac */  /* => inconclusive if equal */  if(diff_is_negative(alpha_facref, alpha_fac, 1.0)) return(TRUE);  else if(diff_is_negative(alpha_fac, alpha_facref, 1.0)) return(REVERSE);  else {    fprintf(stderr, 	    "\nis1stFaceDeeper: Warning, face ordering test failure\n");    fprintf(stderr, "  alpha_fac, face %d = %g alpha_facref, face %d = %g\n", 	    fac->index, alpha_fac, facref->index, alpha_facref);    dump_face(stderr, fac);    fprintf(stderr, " Projected corners\n");    dumpCorners(stderr, cproj[0], fac->numsides, 3);    dump_face(stderr, facref);    fprintf(stderr, " Projected corners\n");    dumpCorners(stderr, cproj[1], facref->numsides, 3);    return(FALSE);		/* inconclusive test */  }}#endif/*  returns TRUE if bounding box of facref and fac (proj to facref's plane) insct*/int isThereBoxOverlap(fac, facref, view)face *fac, *facref;double *view;{  int i, j, olap[2];  double cproj[MAXSIDES][3];	/* corners of fac in facref's plane */  double cref[MAXSIDES][3];	/* corners of facref in facref plane */  double alpha[MAXSIDES];	/* 1 => view point 0 => corner */  double minref[2], maxref[2];	/* bounding box coordinates */  double minfac[2], maxfac[2];  double x[3], y[3];		/* coordinates of x and y in facref plane */  double dot(), temp, tvec[3], tvec1[3], margin, ovrlapmgn = 0.0;  /* figure projections of fac's corners back to facref's plane rel to view */  for(i = 0; i < fac->numsides; i++) {    for(j = 0; j < 3; j++) tvec[j] = view[j] - fac->c[i][j]; /* get v-c */    temp = dot(facref->normal, tvec); /* get n.(v-c) */    margin = sqrt(dot(tvec, tvec))*MARGIN;    ovrlapmgn = MAX(margin, ovrlapmgn);	/* used below */    /* test fails if v-c is perpendicular to n */    if(temp > -margin && temp < margin) return(FALSE);    /* get alpha as in c + alpha*(v-c) = c' */    alpha[i] = (facref->rhs - dot(facref->normal, fac->c[i]))/temp;    /* if(alpha[i] < -margin || alpha[i] > 1.0+margin) {      fprintf(stderr, "\nisThereBoxOverlap: big X failure, alpha = %g\n",	      alpha[i]);      exit(1);    } */    for(j = 0; j < 3; j++)	/* get c' */	cproj[i][j] = (1.0-alpha[i])*fac->c[i][j]+alpha[i]*view[j];  }  /* figure x and y coordinates in facref plane (normal is z coordinate) */  /* x = c0-c1 always */  for(j = 0; j < 3; j++) x[j] = facref->c[0][j] - facref->c[1][j];  temp = sqrt(dot(x, x));  for(j = 0; j < 3; j++) x[j] /= temp; /* normalize */  /* y = zXx */  crossProd(y, facref->normal, x);    /* project all fac corner projections onto new x and y coordinates     - facref->c[0] plays the role of origin */  for(i = 0; i < fac->numsides; i++) {    for(j = 0; j < 3; j++) tvec1[j] = cproj[i][j] - facref->c[0][j];    tvec[0] = dot(x, tvec1);	/* get weight in x direction */    tvec[1] = dot(y, tvec1);	/* get weight in y direction */    tvec[2] = 0.0;		/* all z weights must = facref->rhs */    for(j = 0; j < 3; j++) cproj[i][j] = tvec[j]; /* xfer */  }  for(j = 0; j < 3; j++) cref[0][j] = 0.0;  for(i = 1; i < facref->numsides; i++) {    for(j = 0; j < 3; j++) tvec1[j] = facref->c[i][j] - facref->c[0][j];    cref[i][0] = dot(x, tvec1);	/* get weight in x direction */    cref[i][1] = dot(y, tvec1);	/* get weight in y direction */    cref[i][2] = 0.0;		/* all z weights must = facref->rhs */  }  /* figure bounding boxes in new coordinates */  minfac[0] = maxfac[0] = cproj[0][0];  minfac[1] = maxfac[1] = cproj[0][1];  for(i = 1; i < fac->numsides; i++) { /* find max, min for fac */    for(j = 0; j < 2; j++) {      minfac[j] = MIN(minfac[j], cproj[i][j]);      maxfac[j] = MAX(maxfac[j], cproj[i][j]);    }  }  minref[0] = maxref[0] = cref[0][0];  minref[1] = maxref[1] = cref[0][1];  for(i = 1; i < facref->numsides; i++) { /* find max, min for facref */    for(j = 0; j < 2; j++) {      minref[j] = MIN(minref[j], cref[i][j]);      maxref[j] = MAX(maxref[j], cref[i][j]);    }  }  /* check for overlap - call things overlaped even if not to be sure     - no overlap if either no overlap in x or none in y */  /* check for x overlap */  olap[0] = olap[1] = FALSE;  for(j = 0; j < 2; j++) {    if((minref[j]-ovrlapmgn < minfac[j] && minfac[j] < maxref[j]+ovrlapmgn) ||       (minref[j]-ovrlapmgn < maxfac[j] && maxfac[j] < maxref[j]+ovrlapmgn) ||       (minfac[j]-ovrlapmgn < minref[j] && minref[j] < maxfac[j]+ovrlapmgn) ||       (minfac[j]-ovrlapmgn < maxref[j] && maxref[j] < maxfac[j]+ovrlapmgn))	olap[j] = TRUE;  }  if(olap[0] == FALSE || olap[1] == FALSE) return(FALSE);  else return(TRUE);}#if 1 == 0/*  returns TRUE if 1st face is deeper than second - uses Don's 3d X method  - returns FALSE in don't care situations (1st need not be ordered before 2nd)*/int is1stFaceDeeper(first, second, view)face *first, *second;double *view;{  int fst, snd, ret = SAME;  /* figure on which side of each face plane lies the other face */  fst = whichSide(first, second); /* first relative to plane of second */  snd = whichSide(second, first); /* second relative to plane of first */  /* figure returned value */  if((fst == NEG && snd == NEG) || (fst == POS && snd == POS) ||      (fst == SAME && snd == SAME))      ret = FALSE;		/* order arbitrary */  else if((fst == NEG && snd == POS)) ret = TRUE;  else if((fst == POS && snd == NEG)) ret = FALSE;  else if(fst == NEG && snd == SPLIT) ret = TRUE;  else if(fst == POS && snd == SPLIT) ret = FALSE;  else if(fst == SPLIT && snd == POS) ret = TRUE;  else if(fst == SPLIT && snd == NEG) ret = FALSE;  /* next four added 22 Aug 91 w/o really thinking     - catches false SAME's ? *//*  else if(fst == NEG && snd == SAME) ret = TRUE;  else if(fst == POS && snd == SAME) ret = FALSE;  else if(fst == SAME && snd == POS) ret = TRUE;  else if(fst == SAME && snd == NEG) ret = FALSE; */  else if(snd == SPLIT && fst == SPLIT) {    return(isThereProjOverlap(first, second, view));#if 1 == 0    /* if both are split, see if they interact at all */    if(isThereProjOverlap(first, second, view) == FALSE) ret = FALSE;    else {      fprintf(stderr, 	      "\nis1stFaceDeeper: unresolvable both faces split case\n");      ret = TRUE;		/* don't order--try to order w/other check				   sometimes works, sometimes not */    }#endif  }  if(ret == SAME) {    fprintf(stderr,"\nis1stFaceDeeper: bad fst = %d and snd = %d\n", fst, snd);    exit(1);  }  else if(ret == TRUE) {	/* make sure 2nd could overlap 1st */    if(isThereProjOverlap(first, second, view) == FALSE) ret = FALSE;  }  return(ret);}/*#elseint is1stFaceDeeper(first, second, view)face *first, *second;double *view;{  return(isThereProjOverlap(first, second, view));}*/#endif/*  recursive guts of below*/int chkCycle(fac, ref, fp)face *fac, *ref;FILE *fp;{  int b, i;  if(fac->mark == TRUE) return(FALSE);  fac->mark = TRUE;  if(fac->numbehind == 0) return(FALSE);  else {    for(b = 0; b < fac->numbehind; b++) {      /*fprintf(fp, " %d (%d)", (fac->behind)[b]->depth,	      (fac->behind)[b]->index);      if(b % 5 == 0 && b != 0) fprintf(fp, "\n");*/      if(fac->behind[b] == ref) return(TRUE);      else if(chkCycle(fac->behind[b], ref, fp) == TRUE) return(TRUE);    }/*    if((i-1) % 5 != 0 || i == 1) fprintf(fp, "\n"); */  }  return(FALSE);}/*  checks for cycles in the depth graph - BROKEN(?)*/void dumpCycles(faces, numfaces, file)face **faces;int numfaces;FILE *file;{  int i, f, j, b, *cycled, *cyclei, numcycle, cycle = FALSE;  face *fp;  /* for each face, chase behind pointers until a leaf or same face is found */  /*fprintf(file, "\nRecursive behind lists\n");*/  for(f = 0; f < numfaces; f++) {/*    fprintf(file, "%d (%d):", faces[f]->depth, faces[f]->index);*/    for(j = 0; j < numfaces; j++) faces[j]->mark = FALSE;    for(b = 0; b < faces[f]->numbehind; b++) {      if(chkCycle(faces[f]->behind[b], faces[f], file) == TRUE) {	cycle = TRUE;	break;      }    }    if(cycle == TRUE) break;  }  if(cycle == FALSE) fprintf(file, "Adjacency graph has no cycles\n");  else fprintf(file, "Adjacency graph has cycles\n");  for(j = 0; j < numfaces; j++) faces[j]->mark = FALSE;}    /*  recursively sets depths of faces*/void setDepth(fac)face *fac;{  int i;  /* mark so this face won't be renumbered */  fac->mark = TRUE;  if(fac->index == 193) {    i = i + 0;  }  /* do adjacents if needed */  for(i = 0; i < fac->numbehind; i++) {    if((fac->behind[i])->mark == FALSE) setDepth(fac->behind[i]);  }  if(fac->index == 131 || fac->index == 193) {    i = i + 0;  }  /* set depth, update counter */  fac->depth = cnt--;}/*  does a topological sorting of the faces using graph setup by getAdjGraph()  - returns a new set of pointers with deepest (1st to print) face first*/face **depthSortFaces(faces, numfaces)face **faces;int numfaces;{  int f, i, facefound;  face **rfaces;  /* make sure all marks are cleared */  for(f = 0; f < numfaces; f++) faces[f]->mark = FALSE;  /* set depths recursively - zero is deepest (first to be rendered) */  for(f = 0, cnt = numfaces-1; f < numfaces; f++) {    if(faces[f]->mark == FALSE) setDepth(faces[f]);  }  /* make the new set of pointers */  CALLOC(rfaces, numfaces, face *, ON, AMSC);  for(f = 0; f < numfaces; f++) {    for(i = 0, facefound = FALSE; i < numfaces; i++) {      if(faces[i]->depth == f) {	rfaces[f] = faces[i];	facefound = TRUE;	break;      }    }    if(facefound == FALSE) {      fprintf(stderr, "\ndepthSortFaces: can't find depth %d face\n", f);      exit(1);    }  }  return(rfaces);}/*  sets up adjacency graph pointers in faces: pntr in i to j => face i behind j*/void getAdjGraph(faces, numfaces, view, rhs, normal)face **faces;			/* array of face pntrs, faces[0] head of lst */int numfaces;double *view, rhs, *normal;{  int numbehind, f, i, check;  face *fpcur, *fpchk, **behind;  extern int k_;  if(TRUE == TRUE) {		/* if memory can be sacrificed for speed */    /* set up huge n^2 blocked face pointer arrays for each face */    for(f = 0; f < numfaces; f++) {      CALLOC(faces[f]->behind, numfaces, face *, ON, AMSC);      faces[f]->numbehind = 0;    }          /* for each face, check through all faces not previously checked */    for(fpcur = faces[0], f = 0; fpcur != NULL; fpcur = fpcur->next, f++) {      for(fpchk = fpcur->next, numbehind = i = 0; fpchk != NULL; 	  fpchk = fpchk->next, i++) {	if(fpchk == fpcur) continue;	/* a face can't be behind itself */	if((check = is1stFaceDeeper(fpcur, fpchk, view, rhs, normal))==TRUE) { 	  fpcur->behind[(fpcur->numbehind)++] = fpchk;	}	else if(check == REVERSE) fpchk->behind[(fpchk->numbehind)++] = fpcur;      }      if(f % 20 == 0 && f != 0) {	fprintf(stdout, "%d ", f);	fflush(stdout);      }      if(f % 200 == 0 && f != 0) fprintf(stdout, "\n");    }  }  else {    CALLOC(behind, numfaces, face *, ON, AMSC);    /* for each face, check through all the other faces */    for(fpcur = faces[0], f = 0; fpcur != NULL; fpcur = fpcur->next, f++) {      for(fpchk = faces[0], numbehind = i = 0; fpchk != NULL; 	  fpchk = fpchk->next, i++) {	if(fpchk == fpcur) continue;	/* a face can't be behind itself */	if(is1stFaceDeeper(fpcur, fpchk, view) == TRUE) { 	  behind[numbehind++] = fpchk;	}      }      /* transfer blocked face pointers to face struct */      fpcur->numbehind = numbehind;      if(numbehind > 0) CALLOC(fpcur->behind, numbehind, face *, ON, AMSC);      for(; numbehind > 0; numbehind--)          fpcur->behind[numbehind-1] = behind[numbehind-1];      if(f % 20 == 0 && f != 0) {	fprintf(stdout, "%d ", f);	fflush(stdout);      }      if(f % 200 == 0 && f != 0) fprintf(stdout, "\n");    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -