Exemple #1
0
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: " );
}
Exemple #2
0
    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;
        }
}
Exemple #4
0
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;
    }
Exemple #6
0
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;
        }


    }

}
Exemple #7
0
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;
}