Esempio n. 1
0
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;
}
Esempio n. 2
0
void CheckTetra(Tetra *t, Point3 *v[], int n)
{
 int i;
 Point3 Center;
 double Radius;
 double d;

 if(!CalcSphereCenter(t->f[0]->v[0],
		      t->f[0]->v[1],
		      t->f[0]->v[2],
		      t->f[1]->v[1], &Center ))
			  Error("CheckTetra, Bad Tetrahedron, CalcSphereCenter Failed!\n",EXIT);

 Radius = V3DistanceBetween2Points(&Center, t->f[0]->v[0]);
 for(i=0;i<n;i++)
 {
   d=V3DistanceBetween2Points(&Center,v[i]);
   if( d < Radius - EPSILON)
     Error("CheckTetra, A not Delaunay Tetrahedron was built!\n",EXIT);
 }
}
Esempio n. 3
0
Tetra *FastMakeTetra(Face *f, Point3 *v, int n, UG *G)
{
 Plane p;
 Tetra *t;
 float CellBoxRadius= 0.0,	/* Radius of Cell Box to scan for dd-nearest */
	BoxRadius,
	FaceRadius,
	MinRadius=BIGNUMBER;

 struct argGroup args;
 Line Lc;
 IntPoint3 vn,vp, start, end, inc;
 int Index=-1;
 boolean Found=FALSE;

 SI.MakeTetra++;

 UGResetMark(G);

 if(!CalcPlane(&(v[f->v[0]]),&(v[f->v[1]]),&(v[f->v[2]]),&p))
		Error("Faccia composta da tre punti allineati!!\n",EXIT);

 CalcLineofCenter(&(v[f->v[0]]),&(v[f->v[1]]),&(v[f->v[2]]),&Lc);

 FaceRadius=V3DistanceBetween2Points(&(Lc.Lu), &(v[f->v[0]]));

  args.f = f;
  args.Lc = &Lc;
  args.p = &p; 
  args.G = G;
 // printf("checkpoint 0\n");
 do
 {
  CellBoxRadius++;
  BoxRadius=CalcBox(f,v,&Lc,G,&vn,&vp, CellBoxRadius*FaceRadius);

  Found=ScanCellBox(&vn, &vp, v,&args,&Index, &MinRadius);
 }
 while(!Found && CellBoxRadius <= 1);
 //printf("checkpoint 1\n");
// printf("MinRadius = %f BoxRadius = %f\n",MinRadius, BoxRadius);
 if(Found && MinRadius>BoxRadius)
 {float oldMinRadius=MinRadius;

  SI.SecondBox++;
//  printf("f->v[0] = %d, f->v[1] = %d, f->v[2] = %d, sqrt(MinRadius) = %f\n",f->v[0],f->v[1],f->v[2], sqrt(MinRadius));
  BoxRadius=CalcBox(f,v,&Lc,G,&vn,&vp, sqrt(MinRadius));
 // printf("checkpoint 2\n");
//printf("vn->x = %d ,vn->y = %d, vn->z = %d, vp->x = %d, vp->y = %d, vp->z = %d, radius = %f\n",vn.x, vn.y, vn.z, vp.x, vp.y,vp.z,MinRadius);


  ScanCellBox(&vn, &vp, v, &args, &Index, &MinRadius);
   //printf("checkpoint 2.1\n");
  if(oldMinRadius>MinRadius) SI.UsefulSecondBox++;
 }
 
 if(!Found)
 {
  //printf("checkpoint 3\n");
  SI.EmptyBox++;
  CalcLastScan(G, &start, &end, &inc, &p);
  //printf("checkpoint 4\n"); 
  Found=MakeLastScan(&start, &end, &inc, v, &args, &Index,&MinRadius);
 }
 //printf("chekpoint 5\n");
 if(!Found) return NULL;
 if(MinRadius>0)
 {
  SI.MinRadius+=sqrt(MinRadius);
  SI.MinRadiusNum++;
 }


 t=BuildTetra(f,Index);
 if(StatFlag)
 {Point3 C;
  CalcSphereCenter(&(v[f->v[0]]),&(v[f->v[1]]),&(v[f->v[2]]),&(v[Index]),&C);
  SI.Radius+=V3DistanceBetween2Points(&C, &(v[Index]));
 }
 if(CheckFlag)  CheckTetra(t,v,n);

 return t;
}