int main( int argc, char* argv[] ) { int n = 2, nloop = 1; int *ns[] = { &n, &nloop, 0 }, **np = ns; char* arg; for( argv ++; (arg = *argv) && *np; argv ++, np ++ ) **np = atof( arg ); printf( "n %d nloop %d\n", n, nloop ); // srandom(1); T griddata[] = { 0, 1, 2, 3 }; int shape[] = { 2, 2 }; const int nq = 4; T qpt[] = { 0, 0, 0, 1, 1, 0, 1, 1 }; T out[nq]; //.............................................................................. Barypol<T> bary( griddata, shape, 2 ); bary.at( qpt, nq, out ); printvec<T> ( out, nq, "barypol: " ); }
double Mesh::ComputeVolume() const { const size_t nV = GetNPoints(); const size_t nT = GetNTriangles(); if (nV == 0 || nT == 0) { return 0.0; } Vec3<double> bary(0.0, 0.0, 0.0); for (size_t v = 0; v < nV; v++) { bary += GetPoint(v); } bary /= static_cast<double>(nV); Vec3<double> ver0, ver1, ver2; double totalVolume = 0.0; for(size_t t = 0; t < nT; t++) { const Vec3<int> & tri = GetTriangle(t); ver0 = GetPoint(tri[0]); ver1 = GetPoint(tri[1]); ver2 = GetPoint(tri[2]); totalVolume += ComputeVolume4(ver0, ver1, ver2, bary); } return totalVolume/6.0; }
void Triangle::fill_bary(PPM_Image &I, const PPM_Color &C) const { const auto w = I.width() - 1, h = I.height() - 1; auto xmin = std::max(std::min({p1_.x(), p2_.x(), p3_.x(), w}), 0); auto xmax = std::min(std::max({p1_.x(), p2_.x(), p3_.x(), 0}), w); auto ymin = std::max(std::min({p1_.y(), p2_.y(), p3_.y(), h}), 0); auto ymax = std::min(std::max({p1_.y(), p2_.y(), p3_.y(), 0}), h); const auto clr = C.color(); for (auto y = ymin; y <= ymax; ++y) for (auto x = xmin; x <= xmax; ++x) { Vec<3, double> vb {bary(p1_, p2_, p3_, Point{x, y})}; if (vb.x() >= 0 && vb.y() >= 0 && vb.z() >= 0) I[x][y] = clr; } }
void PlanarRectangle::InitUnit( const Rectangle & rect, const vec3f & integrationPoint ) { // copy src points here std::memcpy( &p0, &rect.p0, 4 * sizeof( vec3f ) ); // Normalize each vertex to get the inscribed triangle, // and find the average vertex plane vec3f bary( 0 ); vec3f *verts = &p0; for ( int i = 0; i < 4; ++i ) { verts[i] = Normalize( verts[i] - integrationPoint ); // put in intPos frame bary += verts[i]; } bary *= 0.25f; // project each point on the tangent plane at the barycenter f32 rayLenSq = Dot( bary, bary ); f32 rayLen = std::sqrt( rayLenSq ); ez = bary / rayLen; // plane normal // bary is in relative coordinates to the integration pt already const Plane P{ bary, ez }; for ( int i = 0; i < 4; ++i ) { // with 0 as origin since the vertices are in relative coordinates already verts[i] = P.RayIntersection( vec3f( 0 ), verts[i] ); } const vec3f d0 = p1 - p0; const vec3f d1 = p3 - p0; const vec3f d2 = p2 - p3; const vec3f d3 = p2 - p1; w = Len( d0 ); h = Len( d1 ); ex = d0 / w; ey = d1 / h; area = 0.5f * ( w * h + Len( d2 ) * Len( d3 ) ); }
double ICHull::ComputeVolume() { size_t nV = m_mesh.m_vertices.GetSize(); if (nV == 0 || m_isFlat) { return 0.0; } Vec3<double> bary(0.0, 0.0, 0.0); for(size_t v = 0; v < nV; v++) { bary.X() += m_mesh.m_vertices.GetHead()->GetData().m_pos.X(); bary.Y() += m_mesh.m_vertices.GetHead()->GetData().m_pos.Y(); bary.Z() += m_mesh.m_vertices.GetHead()->GetData().m_pos.Z(); m_mesh.m_vertices.Next(); } bary /= static_cast<double>(nV); size_t nT = m_mesh.m_triangles.GetSize(); Vec3<double> ver0, ver1, ver2; double totalVolume = 0.0; for(size_t t = 0; t < nT; t++) { ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); totalVolume += Volume(ver0, ver1, ver2, bary); m_mesh.m_triangles.Next(); } return totalVolume; }
void Triangulation::calculNextOrdrePoints(std::vector<Triangle *> triangles, int nbSegments) { int nbTriangles=triangles.size(); // int nbSegments=segments.size(); Triangle *triangleCourant; Segment *seg1, *seg2, *seg3; Point *p1, *p2, *p3; Point *m1, *m2, *m3; // std::vector<Point*> gene(2,NULL); std::vector<bool> tri(nbTriangles,false); std::vector<Point*> bary(nbSegments,NULL); // std::cout<<"nbTriangles "<<nbTriangles<<std::endl; for (int t=0; t<nbTriangles; ++t) { triangleCourant=triangles[t]; p1=triangleCourant->getP0(); p2=triangleCourant->getP1(); p3=triangleCourant->getP2(); std::vector<Segment*> segs=triangleCourant->getSegments(); seg1=segs[0]; seg2=segs[1]; seg3=segs[2]; //recherche des segments formant ce triangle // int s=0; // std::cout<<"Triangle "<<t<<" :"<<triangleCourant->getNom()<<std::endl; // while(p1->getSegment(s)->getP1()!=p2) ++s; // seg1=p1->getSegment(s); // s=0; // while(p1->getSegment(s)->getP1()!=p3) ++s; // seg2=p1->getSegment(s); // s=0; // while(p2->getSegment(s)->getP1()!=p3) ++s; // seg3=p2->getSegment(s); // triangleCourant->getSegments(seg1, seg2, seg3); int i1=seg1->getIndex(); int i2=seg2->getIndex(); int i3=seg3->getIndex(); std::vector<bool> marque(nbTriangles,false); if( triangleCourant->calculated() ){ //Tout les segements des triangles hachurés et de leurs voisins(à faire) génére le m^eme barycentre if( bary[i1]==NULL && bary[i2]==NULL && bary[i3]==NULL ) { m1 = new Point(p1, p2); bary[i1]=bary[i2]=bary[i3]=m1; } else { if(bary[i1]!=NULL) m1=bary[i1]; if(bary[i2]!=NULL) m1=bary[i2]; if(bary[i3]!=NULL) m1=bary[i3]; bary[i1]=bary[i2]=bary[i3]=m1; } // marquer le bary des voisins aussi //A TESTER std::vector<Triangle*> voisHach; triangleCourant->getVoisinsHachure(marque, voisHach); for (int i=0; i<voisHach.size() ;i++){ std::vector<Segment*> segs=voisHach[i]->getSegments(); for (int j=0; j<segs.size(); ++j){ bary[segs[j]->getIndex()]=m1; } } } else { if(bary[i1]==NULL){ m1 = new Point(p1, p2); bary[i1]=m1; } else m1=bary[i1]; std::cout<<"seg 1: "<<seg1->getNom()<<" "; std::cout<<"barycentre "<<m1->getNom()<<std::endl; if(bary[i2]==NULL){ m2 = new Point(p1, p3); bary[i2]=m2; } else m2=bary[i2]; std::cout<<"seg 2: "<<seg2->getNom()<<" "; std::cout<<"son barycentre "<<m2->getNom()<<std::endl; if(bary[i3]==NULL){ m3 = new Point(p2, p3); bary[i3]=m3; } else m3=bary[i3]; std::cout<<"seg 3: "<<seg3->getNom()<<" "; std::cout<<"son barycentre "<<m3->getNom()<<std::endl; Segment *m12 = new Segment(m1, m2); Segment *m13 = new Segment(m1, m3); Segment *m23 = new Segment(m3, m2); Triangle *tr = new Triangle(m1, m2, m3); tr->isCalculated(); std::cout<<"Segments crees "<<m12->getNom()<<" "<<m13->getNom()<<" "<<m23->getNom()<<std::endl; Point* p[]= {m1, m2, m3}; this->addPoints(p, 3); Segment* seg[]={m12, m13, m23}; this->addSegments(seg, 3); this->addTriangle(tr); tr->marquerVoisinage(this->voisins); tri[triangleCourant->getIndex()]=true; } } }
ICHullError ICHull::DoubleTriangle() { // find three non colinear points m_isFlat = false; CircularList<TMMVertex>& vertices = m_mesh.GetVertices(); CircularListElement<TMMVertex>* v0 = vertices.GetHead(); while (Colinear(v0->GetData().m_pos, v0->GetNext()->GetData().m_pos, v0->GetNext()->GetNext()->GetData().m_pos)) { if ((v0 = v0->GetNext()) == vertices.GetHead()) { return ICHullErrorCoplanarPoints; } } CircularListElement<TMMVertex>* v1 = v0->GetNext(); CircularListElement<TMMVertex>* v2 = v1->GetNext(); // mark points as processed v0->GetData().m_tag = v1->GetData().m_tag = v2->GetData().m_tag = true; // create two triangles CircularListElement<TMMTriangle>* f0 = MakeFace(v0, v1, v2, 0); MakeFace(v2, v1, v0, f0); // find a fourth non-coplanar point to form tetrahedron CircularListElement<TMMVertex>* v3 = v2->GetNext(); vertices.GetHead() = v3; double vol = ComputeVolume4(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); while (fabs(vol) < sc_eps && !v3->GetNext()->GetData().m_tag) { v3 = v3->GetNext(); vol = ComputeVolume4(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); } if (fabs(vol) < sc_eps) { // compute the barycenter Vec3<double> bary(0.0, 0.0, 0.0); CircularListElement<TMMVertex>* vBary = v0; do { bary += vBary->GetData().m_pos; } while ((vBary = vBary->GetNext()) != v0); bary /= static_cast<double>(vertices.GetSize()); // Compute the normal to the plane Vec3<double> p0 = v0->GetData().m_pos; Vec3<double> p1 = v1->GetData().m_pos; Vec3<double> p2 = v2->GetData().m_pos; m_normal = (p1 - p0) ^ (p2 - p0); m_normal.Normalize(); // add dummy vertex placed at (bary + normal) vertices.GetHead() = v2; Vec3<double> newPt = bary + m_normal; AddPoint(newPt, sc_dummyIndex); m_isFlat = true; return ICHullErrorOK; } else if (v3 != vertices.GetHead()) { TMMVertex temp; temp.m_name = v3->GetData().m_name; temp.m_pos = v3->GetData().m_pos; v3->GetData().m_name = vertices.GetHead()->GetData().m_name; v3->GetData().m_pos = vertices.GetHead()->GetData().m_pos; vertices.GetHead()->GetData().m_name = temp.m_name; vertices.GetHead()->GetData().m_pos = temp.m_pos; } return ICHullErrorOK; }
ParMetisMesh::ParMetisMesh(Mesh* mesh, MPI::Intracomm* comm, std::map<int, bool>& elementInRank, DofMap* mapLocalGlobal) : dim(mesh->getDim()), nElements(0), mpiComm(comm) { FUNCNAME("ParMetisMesh::ParMetisMesh()"); int mpiSize = mpiComm->Get_size(); int elementCounter = 0; int dow = Global::getGeo(WORLD); TraverseStack stack; ElInfo* elInfo = stack.traverseFirst(mesh, 0, Mesh::CALL_EL_LEVEL); while (elInfo) { if (elementInRank[elInfo->getElement()->getIndex()]) elementCounter++; elInfo = stack.traverseNext(elInfo); } nElements = elementCounter; TEST_EXIT(nElements > 0)("No elements in ParMETIS mesh!\n"); // allocate memory eptr = new int[nElements + 1]; eind = new int[nElements * (mesh->getGeo(VERTEX))]; elmdist = new int[mpiSize + 1]; elem_p2a = new int[nElements]; if (dim == dow) xyz = new float[nElements * dim]; else xyz = NULL; eptr[0] = 0; int* ptr_eptr = eptr + 1; int* ptr_eind = eind; float* ptr_xyz = xyz; // gather element numbers and create elmdist mpiComm->Allgather(&nElements, 1, MPI_INT, elmdist + 1, 1, MPI_INT); elmdist[0] = 0; for (int i = 2; i < mpiSize + 1; i++) elmdist[i] += elmdist[i - 1]; // traverse mesh and fill distributed ParMETIS data DimVec<double> bary(dim, 1.0 / mesh->getGeo(VERTEX)); WorldVector<double> world; elementCounter = 0; int nodeCounter = 0; elInfo = stack.traverseFirst(mesh, 0, Mesh::CALL_EL_LEVEL | Mesh::FILL_COORDS); while (elInfo) { Element* element = elInfo->getElement(); int index = element->getIndex(); // if element in partition if (elementInRank[index]) { // remember index setParMetisIndex(index, elementCounter); setAMDiSIndex(elementCounter, index); // write eptr entry nodeCounter += mesh->getGeo(VERTEX); *ptr_eptr = nodeCounter; ptr_eptr++; // write eind entries (element nodes) for (int i = 0; i < dim + 1; i++) { if (mapLocalGlobal) *ptr_eind = (*mapLocalGlobal)[element->getDof(i, 0)].global; else *ptr_eind = element->getDof(i, 0); ptr_eind++; } // write xyz element coordinates if (ptr_xyz) { elInfo->coordToWorld(bary, world); for (int i = 0; i < dim; i++) { *ptr_xyz = static_cast<float>(world[i]); ptr_xyz++; } } elementCounter++; } elInfo = stack.traverseNext(elInfo); } }
int initial_tache(image_double I, vector<T>& h, T& rayon, bool color, T x, T y) { int COL_IMA = I->xsize; int LIG_IMA = I->ysize; int j = x; int i = y; int d = 2*rayon; if (2*d+1 > LIG_IMA) d=(LIG_IMA-1)/2; if(2*d+1 > COL_IMA) d=(COL_IMA-1)/2; if(i<d) i=d+1; if(i>LIG_IMA-1-d) i=LIG_IMA-2-d; if(j<d) j=d+1; if(j>COL_IMA-1-d) j=COL_IMA-2-d; int val_haut=0; int val_bas=255; for (int k = -d; k <= d; k++) { for (int l = -d; l <= d; l++) { T lum = I->data[j+l+(i+k)*COL_IMA]; if (lum > val_haut) val_haut = lum; else if (lum<val_bas) val_bas=lum; } } T seuil = 0; if (!color) seuil = val_bas + (val_haut - val_bas)/3 * 2; else if (color) seuil = val_bas + (val_haut - val_bas)/3; matrix<T> tab = matrix<T>::zeros(2*d+1, 2*d+1); int label = 1; for (int k = -d+1; k <= d; k++){ for(int l = -d+1; l <= d-1; l++){ T lum= I->data[j+l+(i+k)*COL_IMA]; if (lum < seuil) { int imin=l; int imax=l+1; while( (I->data[j+imax+(i+k)*COL_IMA] <= seuil) && (imax <= d-1) ){ imax++; } int vallab=0; for(int m = imin; m <= imax; m++){ if (tab(k+d-1,m+d) != 0){ vallab = tab(k+d-1,m+d); } } if (vallab == 0){ vallab=label; label++; } for(int m = imin; m <= imax; m++){ tab(k+d,m+d)=vallab; } l=imax; } } } matrix<T> bary = matrix<T>::zeros(label, 4); for(int k = -d; k <= d; k++){ for(int l = -d; l <= d; l++){ if(tab(k+d,l+d)!=0){ T lum= I->data[j+l+(i+k)*COL_IMA]; bary(tab(k+d,l+d),0)+=(255-lum)*(j+l); bary(tab(k+d,l+d),1)+=(255-lum)*(i+k); bary(tab(k+d,l+d),2)+=(255-lum); bary(tab(k+d,l+d),3)++; } } } int distmin=100; int labelmin=0; for(int k = 1; k < label; k++){ T dist = std::sqrt( (bary(k,0)/bary(k,2)-x) * (bary(k,0)/bary(k,2)-x)+ (bary(k,1)/bary(k,2)-y) * (bary(k,1)/bary(k,2)-y)); if(dist < distmin && bary(k,3) > 25 ){ /* 25 = surface min*/ distmin=dist; labelmin=k; } } if(labelmin == 0) { printf("pb tache trop petite (<=25 pixels)\n"); return 1; } x=bary(labelmin,0)/bary(labelmin,2); y=bary(labelmin,1)/bary(labelmin,2); T sx2 = 0, sy2 = 0, sxy = 0, ss = 0; for(int k = -d; k <= d; k++){ for(int l = -d; l <= d; l++){ if(tab(k+d,l+d) == labelmin){ sx2+=(j+l-x)*(j+l-x); sy2+=(i+k-y)*(i+k-y); sxy+=(i+k-y)*(j+l-x); ss++; } } } T lambda1 = ((sx2+sy2)/ss + std::sqrt(( (sx2+sy2)*(sx2+sy2)+4*(sxy*sxy-sx2*sy2)))/ss)/2.0; T lambda2 = ((sx2*sy2-sxy*sxy)/(ss*ss))/lambda1; rayon=std::sqrt(lambda1)*2; h[0] = 1.0/rayon; /* lambda1 */ h[1] = (std::sqrt(lambda1/lambda2))/rayon; /* lambda2 */ h[2] = std::atan2(sx2/ss-lambda1, -sxy/ss); /* alpha */ h[3] = x; /* tu */ h[4] = y; /* tv */ h[5] = 0.25; /* rayon cercle 1 */ h[6] = -2.0; /* pente */ h[7] = 0.25; /* rayon cercle 2 */ h[8] = val_haut; /* val_haut */ h[9] = val_bas; /* val_bas */ h[10] = 1.0; /* position step */ return 0; }