void Quadrangle::shrink(const float &l)
{

    Vector2D tab[4];

    for(int i=0; i<4; i++){
        Vector2D orth1 = Orthogonal(-((*this)[(i+1)%4]-(*this)[i])).normalise();
        Vector2D orth2 = Orthogonal( ((*this)[(i-1)%4]-(*this)[i])).normalise();

        std::cout << (*this)[i] << " :: " << (*this)[(i+1)%4] << std::endl;
        std::cout << (*this)[(i+1)%4]-(*this)[i] << std::endl;
        std::cout << "orth1 : " << orth1 << std::endl;

        std::cout << (*this)[i] << " :: " << (*this)[(i-1)%4] << std::endl;
        std::cout << ((*this)[(i-1)%4]-(*this)[i]) << std::endl;
        std::cout << "orth2 : " << orth2 << std::endl;
        std::cout << "tab["<<i<<"] : " << tab[i] << std::endl;

        Vector2D v = (orth1 + orth2)/2;

        std::cout << "v.Norm() : " << v.getNorm() << std::endl;
        std::cout << std::endl;

        tab[i] = (*this)[i]+Normalized(v)*(l/(v.getNorm()));
    }

    for(int i=0; i<4; i++){
        std::cout << "tab["<<i<<"] : " << tab[i] << std::endl;
        (*this)[i] = tab[i];
    }
}
Example #2
0
void Camera::SetPolar(Pointf3 dz, Pointf3 dx, double d, double a, double b, double r)
{
	Pointf3 dy = dz % dx;
	Pointf3 az = RotateX(Pointf3(0, 0, -1), -b);
	az = d * RotateY(az, a);
	Pointf3 loc = az * Matrixf3(dx, dy, dz, target);
	Pointf3 dir = Unit(target - loc);
	Pointf3 su = Orthogonal(dy, dir);
	if(Length(su) <= 1e-10)
		su = Orthogonal(FarthestAxis(dir), dir);
	su = Unit(su);
	Location(loc).Upwards(Rotate(su, dir, r));
}
void calcBezier::calculeOrthogonal(Geometry::Point3D &p0, Geometry::Point3D &p1, Geometry::Point3D &p2, Geometry::Point3D &p3, Geometry::Point3D &p00, Geometry::Point3D &p11, Geometry::Point3D &p22, Geometry::Point3D &p33, double largeur)
{
    Geometry::Vector A(p1.getX()-p0.getX(), p1.getY()-p0.getY(), p1.getZ() - p0.getZ());
    Geometry::Vector B(p3.getX()-p2.getX(), p3.getY()-p2.getY(), p3.getZ() - p2.getZ());
    Geometry::Vector AO = Orthogonal(A);
    AO = Normalized(AO);
    AO = AO * largeur;
    Geometry::Vector BO = Orthogonal(B);
    BO = Normalized(BO);
    BO = BO * largeur;

    p00.setX(p0.getX()+AO[0]);
    p00.setY(p0.getY()+AO[1]);
    p00.setZ(p0.getZ()+AO[2]);

    if (p00.getZ() !=0 )
    {
        AO = Orthogonal(AO);
        AO = Normalized(AO);
        AO = AO * largeur;



        p00.setX(p0.getX()+AO[0]);
        p00.setY(p0.getY()+AO[1]);
        p00.setZ(p0.getZ()+AO[2]);
    }


    p11.setX(p1.getX()+AO[0]);
    p11.setY(p1.getY()+AO[1]);
    p11.setZ(p1.getZ()+AO[2]);


    p22.setX(p2.getX()+BO[0]);
    p22.setY(p2.getY()+BO[1]);
    p22.setZ(p2.getZ()+BO[2]);


    p33.setX(p3.getX()+BO[0]);
    p33.setY(p3.getY()+BO[1]);
    p33.setZ(p3.getZ()+BO[2]);

}
Example #4
0
void Polygone::shrinkPoly(int nb, float l)
{
    if(l == 0)
        return;

    Vector2D tab[nb];

    for(int i = 0;	i < nb;	i++)
    {
        Vector2D v1 = Orthogonal(get(i)-get(i+1)).normalised();
        Vector2D v2 = Orthogonal(get(i-1)-get(i)).normalised();

        Vector2D v = (v1+v2)/2;	//quand on augmente de 1 sur v1 ou v2, on augment de v.norm() sur le v.

        tab[i] = get(i)+Normalized(v)*(l/v.getNorm());
    }
    for(int i = 0;	i < nb;	i++)
         set(i, tab[i]);
}
void calcBezier::calculeOrthogonalSimple(Geometry::Point3D &p0, Geometry::Point3D &p1, Geometry::Point3D &p00, double largeur)
{
    Geometry::Vector A(p1.getX()-p0.getX(), p1.getY()-p0.getY(), p1.getZ() - p0.getZ());
    Geometry::Vector AO = Orthogonal(A);
    AO = Normalized(AO);
    AO = AO * largeur;

    p00.setX(p0.getX()+AO[0]);
    p00.setY(p0.getY()+AO[1]);
    p00.setZ(p0.getZ()+AO[2]);
}
Example #6
0
void Camera::Update()
{
	direction = Unit(target - location);
	distance_delta = -(location ^ direction);
	viewing_distance = double(min(width_mm, height_mm) / (2e3 * tan(viewing_angle / 2.0)));
	Pointf3 up = Orthogonal(upwards, direction);
	if(Squared(up) <= 1e-10)
		up = Orthogonal(FarthestAxis(direction), direction);
	straight_up = Unit(up);
	straight_right = direction % straight_up;
	camera_matrix = Matrixf3(straight_right, straight_up, direction, location);
	invcam_matrix = Matrixf3Inverse(camera_matrix);
	double dw = viewing_distance * view_px * 2e3 / width_mm;
	double dh = viewing_distance * view_py * 2e3 / height_mm;
	double z_times = far_distance - near_distance;
	z_delta = -near_distance / z_times;
	transform_matrix = invcam_matrix * Matrixf3(
		Pointf3(dw / z_times, 0, 0),
		Pointf3(0, dh / z_times, 0),
		Pointf3(shift_x, shift_y, 1) / z_times);
}
Example #7
0
Pointf3 Orthonormal(Pointf3 v, Pointf3 against)
{
	return Unit(Orthogonal(v, against));
}
Example #8
0
void Triangles::IntersectConsMetric(const double * s,const Int4 nbsol,const int * typsols,
				    const  Real8 hmin1,const Real8 hmax1,const Real8 coef,
				    const Real8 anisomax ,const Real8 CutOff,const int NbJacobi,
				    const int DoNormalisation,const int choice)
{ //  the array of solution s is store    
  // sol0,sol1,...,soln    on vertex 0
  //  sol0,sol1,...,soln   on vertex 1
  //  etc.
  const int dim = 2;
  
  int sizeoftype[] = { 1, dim ,dim * (dim+1) / 2, dim * dim } ; 

  // computation of the nb of field 
  Int4 ntmp = 0;
  if (typsols)
    {
      for (Int4 i=0;i<nbsol;i++)
	ntmp += sizeoftype[typsols[i]];
    }
  else
    ntmp = nbsol;

  // n is the total number of fields

  const Int4 n = ntmp;

  Int4 i,k,iA,iB,iC,iv;
  R2 O(0,0);
  int RelativeMetric = CutOff>1e-30;
  Real8 hmin = Max(hmin1,MinimalHmin());
  Real8 hmax = Min(hmax1,MaximalHmax());
  Real8 coef2 = 1/(coef*coef);

  if(verbosity>1) 
    {
      cout << " -- Construction of Metric: Nb of sol. " << n << " nbt = " 
	   << nbt << " nbv= " << nbv 
	   << " coef = " << coef << endl
	   << "     hmin = " << hmin << " hmax=" << hmax 
	   << " anisomax = " << anisomax <<  " Nb Jacobi " << NbJacobi ;
      if (RelativeMetric)
	cout << " RelativeErr with CutOff= "  <<  CutOff << endl;
      else
	cout << " Absolute Err" <<endl;
    }
  double *ss=(double*)s, *ssiii = ss;

  double sA,sB,sC;

  Real8 *detT = new Real8[nbt];
  Real8 *Mmass= new Real8[nbv];
  Real8 *Mmassxx= new Real8[nbv];
  Real8 *dxdx= new Real8[nbv];
  Real8 *dxdy= new Real8[nbv];
  Real8 *dydy= new Real8[nbv];
  Real8 *workT= new Real8[nbt];
  Real8 *workV= new Real8[nbv];
  int *OnBoundary = new int[nbv];
  for (iv=0;iv<nbv;iv++)
    {
      Mmass[iv]=0;
      OnBoundary[iv]=0;
      Mmassxx[iv]=0;
    }

  for (i=0;i<nbt;i++) 
    if(triangles[i].link) // the real triangles 
      {
	const Triangle &t=triangles[i];
	// coor of 3 vertices 
	R2 A=t[0];
	R2 B=t[1];
	R2 C=t[2];


	// number of the 3 vertices
	iA = Number(t[0]);
	iB = Number(t[1]);
	iC = Number(t[2]);
	
	Real8 dett = ::Area2(A,B,C);
	detT[i]=dett;
	dett /= 6;

	// construction of on boundary 
	int nbb =0;
	for(int j=0;j<3;j++)
          {
	    Triangle *ta=t.Adj(j);
	    if ( ! ta || !ta->link) // no adj triangle => edge on boundary
	      OnBoundary[Number(t[VerticesOfTriangularEdge[j][0]])]=1,
		OnBoundary[Number(t[VerticesOfTriangularEdge[j][1]])]=1,
		nbb++;
	  }
	
	workT[i] = nbb;
	Mmass[iA] += dett;
	Mmass[iB] += dett;
	Mmass[iC] += dett;
	
	if((nbb==0)|| !choice)
	  {
	    Mmassxx[iA] += dett;
	    Mmassxx[iB] += dett;
	    Mmassxx[iC] += dett;
	  }
      }
    else
      workT[i]=-1;

  for (Int4 kcount=0;kcount<n;kcount++,ss++)
    { //for  all solution 

      Real8 smin=ss[0],smax=ss[0];
      
      Real8 h1=1.e30,h2=1e-30,rx=0;
      Real8 coef = 1./(anisomax*anisomax);
      Real8 hn1=1.e30,hn2=1e-30,rnx =1.e-30;  

      for ( iv=0,k=0; iv<nbv; iv++,k+=n )
	{
	  dxdx[iv]=dxdy[iv]=dydy[iv]=0;
	  smin=Min(smin,ss[k]);
	  smax=Max(smax,ss[k]);
	}
      Real8 sdelta = smax-smin;
      Real8 absmax=Max(Abs(smin),Abs(smax));
      Real8 cnorm = DoNormalisation ? coef2/sdelta : coef2;
      
      if(verbosity>2) 
	cout << "    Solution " << kcount <<  " Min = " << smin << " Max = " 
	     << smax << " Delta =" << sdelta << " cnorm = " << cnorm <<  endl;

      
      if ( sdelta < 1.0e-10*Max(absmax,1e-20) ) 
	{
	  if (verbosity>2)
	    cout << "      Solution " << kcount << " is constant. We skip. " 
		 << " Min = " << smin << " Max = " << smax << endl;
	  continue;
	}
      
      for (i=0;i<nbt;i++) 
	if(triangles[i].link)
	  {// for real all triangles 
	    // coor of 3 vertices 
	    R2 A=triangles[i][0];
	    R2 B=triangles[i][1];
	    R2 C=triangles[i][2];
	    
	    
	    // warning the normal is internal and the 
	    //   size is the length of the edge
	    R2 nAB = Orthogonal(B-A);
	    R2 nBC = Orthogonal(C-B);
	    R2 nCA = Orthogonal(A-C);
	    // remark :  nAB + nBC + nCA == 0 

	    // number of the 3 vertices
	    iA = Number(triangles[i][0]);
	    iB = Number(triangles[i][1]);
	    iC = Number(triangles[i][2]);
	    
	    // for the test of  boundary edge
	    // the 3 adj triangles 
	    Triangle *tBC = triangles[i].TriangleAdj(OppositeEdge[0]);
	    Triangle *tCA = triangles[i].TriangleAdj(OppositeEdge[1]);
	    Triangle *tAB = triangles[i].TriangleAdj(OppositeEdge[2]);

	    // value of the P1 fonction on 3 vertices 
	    sA = ss[iA*n];
	    sB = ss[iB*n];
	    sC = ss[iC*n];

	    R2 Grads = (nAB * sC + nBC * sA + nCA * sB ) /detT[i] ;
	    if(choice) 
	      {
		int nbb = 0;
		Real8 dd = detT[i];
		Real8 lla,llb,llc,llf;
		Real8  taa[3][3],bb[3];
		// construction of the trans of lin system
		for (int j=0;j<3;j++)
		  {
		    int ie = OppositeEdge[j];
		    TriangleAdjacent ta = triangles[i].Adj(ie);
		    Triangle *tt = ta;
		    if (tt && tt->link)
		      {
			Vertex &v = *ta.OppositeVertex();
			R2 V = v;
			Int4 iV = Number(v);
			Real8 lA  = ::Area2(V,B,C)/dd;
			Real8 lB  = ::Area2(A,V,C)/dd;
			Real8 lC  = ::Area2(A,B,V)/dd;
			taa[0][j] =  lB*lC;
			taa[1][j] =  lC*lA;
			taa[2][j] =  lA*lB;
			Real8 xx = V.x-V.y;
			Real8 yy = V.x + V.y;
			//cout << " iv " << ss[iV*n] << " == " << (8*xx*xx+yy*yy)
			//     << " l = " << lA << " " << lB << " " << lC 
			//     << " = " << lA+lB+lC << " " <<  V << " == " << A*lA+B*lB+C*lC << endl;
			
			lla = lA,llb=lB,llc=lC,llf=ss[iV*n] ;

			bb[j]     =  ss[iV*n] - ( sA*lA + sB*lB + sC*lC ) ;
		      }
		    else
		      {
			nbb++;
			taa[0][j]=0;
			taa[1][j]=0;
			taa[2][j]=0;
			taa[j][j]=1;
			bb[j]=0;
		      }
		  }

		// resolution of 3x3 lineaire system transpose
		Real8 det33 =  det3x3(taa[0],taa[1],taa[2]);		
		Real8 cBC   =  det3x3(bb,taa[1],taa[2]);
		Real8 cCA   =  det3x3(taa[0],bb,taa[2]);
		Real8 cAB   =  det3x3(taa[0],taa[1],bb);
		
		assert(det33);
		//	det33=1;
		// verif
		//	cout << " " << (taa[0][0]*cBC +  taa[1][0]*cCA + taa[2][0] * cAB)/det33 << " == " << bb[0] ;
		//	cout << " " << (taa[0][1]*cBC +  taa[1][1]*cCA + taa[2][1] * cAB)/det33 << " == " << bb[1];
		//	cout << " " << (taa[0][2]*cBC +  taa[1][2]*cCA + taa[2][2] * cAB)/det33 << " == " << bb[2] 
		//	     << "  -- " ;
		//cout << lla*sA + llb*sB+llc*sC+ (lla*llb* cAB +  llb*llc* cBC + llc*lla*cCA)/det33 
		//   << " == " << llf <<  endl;
		// computation of the gradient in the element 
		
		// H( li*lj) = grad li grad lj + grad lj grad lj
		// grad li = njk  / detT ; with i j k ={A,B,C)
		Real8 Hxx = cAB * ( nBC.x*nCA.x) +  cBC * ( nCA.x*nAB.x) + cCA * (nAB.x*nBC.x);
		Real8 Hyy = cAB * ( nBC.y*nCA.y) +  cBC * ( nCA.y*nAB.y) + cCA * (nAB.y*nBC.y);
		Real8 Hxy = cAB * ( nBC.y*nCA.x) +  cBC * ( nCA.y*nAB.x) + cCA * (nAB.y*nBC.x) 
		  + cAB * ( nBC.x*nCA.y) +  cBC * ( nCA.x*nAB.y) + cCA * (nAB.x*nBC.y);
		Real8 coef = 1.0/(3*dd*det33);
		Real8 coef2 = 2*coef;
		//	cout << " H = " << Hxx << " " << Hyy << " " <<  Hxy/2 << " coef2 = " << coef2 << endl;
		Hxx *= coef2;
		Hyy *= coef2;
		Hxy *= coef2;
		//cout << i  << " H = " << 3*Hxx/dd << " " << 3*Hyy/dd << " " <<  3*Hxy/(dd*2) << " nbb = " << nbb << endl;
		if(nbb==0)
		  {
		    dxdx[iA] += Hxx;
		    dydy[iA] += Hyy;
		    dxdy[iA] += Hxy;
		    
		    dxdx[iB] += Hxx;
		    dydy[iB] += Hyy;
		    dxdy[iB] += Hxy;
		    
		    dxdx[iC] += Hxx;
		    dydy[iC] += Hyy;
		    dxdy[iC] += Hxy;
		  }
		
	      }
	    else
	      {
		
		// if edge on boundary no contribution  => normal = 0
		if ( ! tBC || ! tBC->link ) nBC = O;
		if ( ! tCA || ! tCA->link ) nCA = O;
		if ( ! tAB || ! tAB->link ) nAB = O;
	    
		// remark we forgot a 1/2 because
		//       \int_{edge} w_i = 1/2 if i is in edge 
		//                          0  if not
		// if we don't take the  boundary 
		// dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
		
		dxdx[iA] += ( nCA.x + nAB.x ) *Grads.x;
		dxdx[iB] += ( nAB.x + nBC.x ) *Grads.x;
		dxdx[iC] += ( nBC.x + nCA.x ) *Grads.x;
		
		// warning optimization (1) the divide by 2 is done on the metrix construction
		dxdy[iA] += (( nCA.y + nAB.y ) *Grads.x + ( nCA.x + nAB.x ) *Grads.y) ;
		dxdy[iB] += (( nAB.y + nBC.y ) *Grads.x + ( nAB.x + nBC.x ) *Grads.y) ;
		dxdy[iC] += (( nBC.y + nCA.y ) *Grads.x + ( nBC.x + nCA.x ) *Grads.y) ; 
		
		dydy[iA] += ( nCA.y + nAB.y ) *Grads.y;
		dydy[iB] += ( nAB.y + nBC.y ) *Grads.y;
		dydy[iC] += ( nBC.y + nCA.y ) *Grads.y;
	      }
	    
	  } // for real all triangles 
      Int4 kk=0;
      for ( iv=0,k=0 ; iv<nbv; iv++,k+=n )
	if(Mmassxx[iv]>0) 
	  {
	    dxdx[iv] /= 2*Mmassxx[iv];
	    // warning optimization (1) on term dxdy[iv]*ci/2 
	    dxdy[iv] /= 4*Mmassxx[iv];
	    dydy[iv] /= 2*Mmassxx[iv];
	    // Compute the matrix with abs(eigen value)
	    Metric M(dxdx[iv], dxdy[iv], dydy[iv]);
	    MatVVP2x2 Vp(M);
	    //cout <<iv <<  "  M  = " <<  M <<  " aniso= " << Vp.Aniso() ;
	    Vp.Abs();
	    M = Vp;
	    dxdx[iv] = M.a11;
	    dxdy[iv] = M.a21;
	    dydy[iv] = M.a22;
	    //  cout << " (abs)  iv M  = " <<  M <<  " aniso= " << Vp.Aniso() <<endl;
	  }
	else kk++;
      
      
      // correction of second derivate
      // by a laplacien

      Real8 *d2[3] = { dxdx, dxdy, dydy};
      Real8 *dd;
      for (int xy = 0;xy<3;xy++)
	{
	  dd = d2[xy];
	  // do leat 2 iteration for boundary problem
	  for (int ijacobi=0;ijacobi<Max(NbJacobi,2);ijacobi++)
	    {
	      for (i=0;i<nbt;i++) 
		if(triangles[i].link) // the real triangles 
		  {
		    // number of the 3 vertices
		    iA = Number(triangles[i][0]);
		    iB = Number(triangles[i][1]);
		    iC = Number(triangles[i][2]);
		    Real8 cc=3;
		    if(ijacobi==0)
		      cc = Max((Real8) ((Mmassxx[iA]>0)+(Mmassxx[iB]>0)+(Mmassxx[iC]>0)),1.);
		    workT[i] = (dd[iA]+dd[iB]+dd[iC])/cc;
		  }
	      for (iv=0;iv<nbv;iv++)
		workV[iv]=0;

	      for (i=0;i<nbt;i++) 
		if(triangles[i].link) // the real triangles 
		  {
		    // number of the 3 vertices
		    iA = Number(triangles[i][0]);
		    iB = Number(triangles[i][1]);
		    iC = Number(triangles[i][2]);
		    Real8 cc =  workT[i]*detT[i];
		    workV[iA] += cc;
		    workV[iB] += cc;
		    workV[iC] += cc;
		  }

	      for (iv=0;iv<nbv;iv++)
		if( ijacobi<NbJacobi || OnBoundary[iv])
		  dd[iv] = workV[iv]/(Mmass[iv]*6);
	      

	    }

	  
	}

      // constuction  of the metrix from the Hessian dxdx. dxdy,dydy

      Real8 rCutOff=CutOff*absmax;// relative cut off 

      for ( iv=0,k=0 ; iv<nbv; iv++,k+=n )
	{ // for all vertices 
	  //{
	  //Metric M(dxdx[iv], dxdy[iv], dydy[iv]);
	  // MatVVP2x2 Vp(M);	  
	  //cout << " iv M="<<  M << "  Vp = " << Vp << " aniso  " << Vp.Aniso() << endl;
	  //}
	  MetricIso Miso;
	  Real8 ci = RelativeMetric ? coef2/(Max(Abs(ss[k]),rCutOff)) : cnorm ;
	  Metric Miv(dxdx[iv]*ci, dxdy[iv]*ci,  dydy[iv]*ci);
	  MatVVP2x2 Vp(Miv);

	  Vp.Abs();
	  


	  h1=Min(h1,Vp.lmin());
	  h2=Max(h2,Vp.lmax());

	  Vp.Maxh(hmin);
	  Vp.Minh(hmax);

	  rx = Max(rx,Vp.Aniso2());

	  Vp.BoundAniso2(coef);

	  hn1=Min(hn1,Vp.lmin());
	  hn2=Max(hn2,Vp.lmax());
	  rnx = Max(rnx,Vp.Aniso2());

	  Metric MVp(Vp);
	  vertices[iv].m.IntersectWith(MVp);
	}// for all vertices 
      if (verbosity>2)
	{ 
	  cout << "              Solution " << kcount << endl;
	  cout << "              before bounding :  Hmin = " << sqrt(1/h2) << " Hmax = " 
	       << sqrt(1/h1)  << " factor of anisotropy max  = " << sqrt(rx) << endl;
	  cout << "              after  bounding :  Hmin = " << sqrt(1/hn2) << " Hmax = " 
	       << sqrt(1/hn1)  << " factor of anisotropy max  = " << sqrt(rnx) << endl;
	}
    }// end for all solution 

  delete [] detT;
  delete [] Mmass;
  delete [] dxdx;
  delete [] dxdy;
  delete [] dydy;
  delete []  workT;
  delete [] workV;
  delete [] Mmassxx;
  delete []  OnBoundary;
 
}