boolean ScanCellBox(IntPoint3 *vn, IntPoint3 *vp, Point3 *v, struct argGroup* args, int *index,float *MinRadius) { Face *f = args->f; Line *Lc = args->Lc; Plane *p = args->p; UG *G = args->G; int i,j,k; int CellIndex; Plist *P; Plane Mp; Point3 c; float Radius; int indpnt=-1; boolean Found=FALSE; for(i=vn->x; i<=vp->x; i++) for(j=vn->y; j<=vp->y; j++) for(k=vn->z; k<=vp->z; k++) { CellIndex = i + j*G->x + k*G->y*G->x; if(!UGIsMarked(G,CellIndex)) { UGMark(G,CellIndex); P=G->C[CellIndex]; while(P) { indpnt=P->p; if(G->UsedPoint[indpnt]!=0) if((indpnt!=f->v[0]) && (indpnt!=f->v[1]) && (indpnt!=f->v[2]) && RightSide(p,&(v[indpnt])) ) { CalcMiddlePlane(&(v[indpnt]),&(v[f->v[0]]),&Mp); if(CalcLinePlaneInter(Lc,&Mp,&c)) { Radius=V3SquaredDistanceBetween2Points(&c, &(v[indpnt])); if(!RightSide(p,&c)) Radius=-Radius; if(Radius==*MinRadius) Error("Cinque punti cocircolari!!\n",EXIT); if(Radius<*MinRadius) { *MinRadius=Radius; *index=indpnt; Found=TRUE; } } } P=P->next; } /* end while */ } /* end if !IsMarked */ } /* end for */ return Found; }
Tetra *MakeTetra(Face *f,Point3 *v[], int n) { Plane p,Mp; boolean found=FALSE; double Radius=BIGNUMBER, rad; Line Lc; int pind=0; Tetra *t; Point3 Center, c; int i; if(!CalcPlane(f->v[0],f->v[1],f->v[2],&p)) Error("MakeTetra, Face with collinar vertices!\n",EXIT); CalcLineofCenter(f->v[0],f->v[1],f->v[2],&Lc); for(i=0;i<n;i++) { if((v[i]!=f->v[0]) && (v[i]!=f->v[1]) && (v[i]!=f->v[2]) && RightSide(&p,v[i]) ) { CalcMiddlePlane(v[i],f->v[0],&Mp); if(CalcLinePlaneInter(&Lc,&Mp,&c)) { rad=V3SquaredDistanceBetween2Points(&c, v[i]); if(!RightSide(&p,&c)) rad=-rad; if(rad==Radius) Error("MakeTetra, Five cocircular points!\n",EXIT); if(rad<Radius) { found=TRUE; Radius=rad; Center=c; pind=i; } } } } if(!found) return NULL; t=BuildTetra(f,v[pind]); if(CheckFlag) CheckTetra(t,v,n); if(StatFlag) {Point3 C; CalcSphereCenter(f->v[0], f->v[1], f->v[2], v[pind], &C); SI.Radius+=V3DistanceBetween2Points(&C, v[pind]); } return t; }
Tetra *FirstTetra(Point3 *v[], int n) { int i, MinIndex=0; double Radius, MinRadius=BIGNUMBER; Tetra *t; Plane p[3], Mp; Line Lc; Face f; Point3 c; boolean found=FALSE; f.v[0]=v[n/2-1]; /* The first point of the face is the */ /* nearest to middle plane in negative */ /* halfspace. */ /* The 2nd point of the face is the */ /* euclidean nearest to first point */ for(i=n/2;i<n;i++) /* that is in the positive halfspace */ { Radius=V3SquaredDistanceBetween2Points(f.v[0], v[i]); if(Radius<MinRadius) { MinRadius=Radius; MinIndex=i; } } f.v[1]=v[MinIndex]; /* The 3rd point is that with previous */ /* ones builds the smallest circle. */ CalcMiddlePlane(f.v[0],f.v[1], &(p[0])); MinRadius=BIGNUMBER; for(i=0;i<n;i++) if(v[i]!=f.v[0] && v[i]!=f.v[1]) { CalcMiddlePlane(f.v[0], v[i],&(p[1])); if(CalcPlane(f.v[0],f.v[1],v[i],&(p[2]))) if(CalcPlaneInter(&(p[0]), &(p[1]), &(p[2]), &c)) { Radius=V3DistanceBetween2Points(&c, f.v[0]); if(Radius<MinRadius) { MinRadius=Radius; MinIndex=i; } } } f.v[2]=v[MinIndex]; /* The first tetrahedron construction is analogous to normal */ /* MakeTetra, only we dont limit search to an halfspace. */ MinRadius=BIGNUMBER; CalcPlane(f.v[0], f.v[1], f.v[2],&p[0]); CalcLineofCenter(f.v[0], f.v[1], f.v[2], &Lc); for(i=0;i<n;i++) if(v[i]!=f.v[0] && v[i]!=f.v[1] && v[i]!=f.v[2] ) { CalcMiddlePlane(v[i], f.v[0], &Mp); if(CalcLinePlaneInter(&Lc, &Mp, &c)) { Radius=V3SquaredDistanceBetween2Points(&c, v[i]); if(MinRadius==Radius) Error("FirstTetra, Five cocircular points!\n",EXIT); if(Radius<MinRadius) { found=TRUE; MinRadius=Radius; MinIndex=i; } } } if(!found) Error("FirstTetra, Planar dataset, unable to build first tetrahedron.\n",EXIT); if(!RightSide(&p[0],v[MinIndex])) ReverseFace(&f); t=BuildTetra(&f, v[MinIndex]); CheckTetra(t,v,n); ReverseFace(t->f[0]); /* First Face in first Tetra */ /* must be outward oriented */ return t; }
boolean MakeLastScan(IntPoint3 *Start, IntPoint3 *End, IntPoint3 *Inc, Point3 *v, struct argGroup* args, int *index, float *MinRadius) { Face *f = args->f; Line *Lc = args->Lc; Plane *p = args->p; UG *G = args->G; int i,j,k; int CellIndex; Plist *P; Plane Mp; Point3 c; float Radius; int indpnt=-1; for(i=Start->x; Inc->x*i <= Inc->x*End->x; i+=Inc->x) { // printf("LastScan cell x=%d\n",i); if(!ExaminableCell(i,Start->y,Start->z,p,G)) i=End->x; else for(j=Start->y; Inc->y*j<=Inc->y*End->y; j+=Inc->y) { // printf("LastScan cell y=%d\n",j); if(!ExaminableCell(i,j,Start->z,p,G)) j=End->y; else for(k=Start->z; Inc->z*k<=Inc->z*End->z; k+=Inc->z) { // printf("LastScan cell z=%d\n",k); if(!ExaminableCell(i,j,k,p,G)) k=End->z; else { CellIndex = i + j*G->x + k*G->y*G->x; if(!UGIsMarked(G, CellIndex)) { P=G->C[CellIndex]; // printf("LastScan found cell x=%d y=%d z=%d\n",i,j,k); while(P) { indpnt=P->p; // printf("LastScan indpnt is: %d\n",indpnt); if((indpnt!=f->v[0]) && (indpnt!=f->v[1]) && (indpnt!=f->v[2]) && RightSide(p,&(v[indpnt])) ) { CalcMiddlePlane(&(v[indpnt]),&(v[f->v[0]]),&Mp); if(CalcLinePlaneInter(Lc,&Mp,&c)) { Radius=V3SquaredDistanceBetween2Points(&c, &(v[indpnt])); // printf("LastScan Radius: %f\n",Radius); if(!RightSide(p,&c)) Radius=-Radius; if(Radius==*MinRadius) Error("Cinque punti cocircolari!!\n",EXIT); if(Radius<*MinRadius) { // printf("LastScan found Radius: %f\n",Radius); *MinRadius=Radius; *index=indpnt; } } } P=P->next; } /* end while */ } /* end if IsMarked */ } /* end if examinable */ } /* end for k */ } /* end for j */ } /* end for i */ if(*index==-1) return FALSE; return TRUE; }