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]; } }
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]); }
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]); }
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); }
Pointf3 Orthonormal(Pointf3 v, Pointf3 against) { return Unit(Orthogonal(v, against)); }
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; }