/* Ligne polygonale 3D */ /* */ /* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Mars 2020 */ #include #include #include #include #include #include #include "Pos3D.h" #include "LignePolygonale3D.h" #include "MatriceDeBase.h" /* Constructeurs */ LignePolygonale3D::LignePolygonale3D(void) { nbPoints = 0; tPos = NULL; sp = 0; } LignePolygonale3D::LignePolygonale3D(int nbPoints) { this->nbPoints = nbPoints; tPos =(Pos3D **) calloc(nbPoints,sizeof(Pos3D *)); for ( int i = 0 ; i < nbPoints ; i++ ) tPos[i] = new Pos3D(); sp = 0; } LignePolygonale3D::LignePolygonale3D(int nbPoints,Pos3D **tPos) { this->nbPoints = nbPoints; this->tPos =(Pos3D **) calloc(nbPoints,sizeof(Pos3D *)); for ( int i = 0 ; i < nbPoints ; i++ ) { this->tPos[i] = new Pos3D(tPos[i]); } sp = nbPoints; } LignePolygonale3D::LignePolygonale3D(LignePolygonale3D *lp) { nbPoints = lp->nbPoints; tPos =(Pos3D **) calloc(nbPoints,sizeof(Pos3D *)); for ( int i = 0 ; i < nbPoints ; i++ ) { tPos[i] = new Pos3D(lp->tPos[i]); } sp = lp->sp; } /* Destructeur */ LignePolygonale3D::~LignePolygonale3D(void) { if ( nbPoints != 0 ) { if ( tPos ) { for ( int i = 0 ; i < nbPoints ; i++) delete(tPos[i]); free(tPos); tPos = NULL; } } } /* Calcul la position d'un point sur une courbe */ /* B-Spline controlee par quatre points */ /* tPos : le tableau des 4 points de controle */ /* t : la valeur de calcul du point */ /* t a prendre dans l'intervalle [0.0,1.0] */ /* mb : la matrice de base */ /* point : le point resultat */ static void positionSurBSpline(Pos3D **tPos,float t,const MatriceDeBase *mb,Pos3D *point) { float vt[4] = { t*t*t,t*t,t,1.0F }; float vtmb[4] = { 0.0F,0.0F,0.0F,0.0F }; for ( int j = 0 ; j < 4 ; j++ ) { for ( int k = 0 ; k < 4 ; k++ ) vtmb[j] += vt[k] * mb->c[k][j] ; } point->x = point->y = point->z = 0.0; for ( int j = 0 ; j < 4 ; j++ ) { point->x += vtmb[j] * tPos[j]->x ; point->y += vtmb[j] * tPos[j]->y ; point->z += vtmb[j] * tPos[j]->z ; } } LignePolygonale3D::LignePolygonale3D(int nbPoints,LignePolygonale3D *lp,const MatriceDeBase *m) { this->nbPoints = nbPoints; tPos =(Pos3D **) calloc(nbPoints,sizeof(Pos3D *)); for ( int i = 0 ; i < nbPoints ; i++ ) { tPos[i] = new Pos3D(); float t = i/(nbPoints-1.0)*(lp->nbPoints-3); int nb =(int) t; if ( nb == lp->nbPoints-3 ) nb = lp->nbPoints-4; positionSurBSpline(&(lp->tPos[nb]),t-nb,m,tPos[i]); } } LignePolygonale3D::LignePolygonale3D(int nbPoints,LignePolygonale3D *lp) { this->nbPoints = nbPoints; tPos =(Pos3D **) calloc(nbPoints,sizeof(Pos3D *)); long long *cn; cn =(long long *) calloc(lp->nbPoints,sizeof(long long)); cn[0] = 1; cn[1] = lp->nbPoints-1; for ( int i = 2 ; i < lp->nbPoints ; i++ ) cn[i] = (cn[i-1]*(lp->nbPoints-i))/i; for ( int i = 0 ; i < nbPoints ; i++ ) { tPos[i] = new Pos3D(); float t =(float) i/(nbPoints-1); float mt = 1.0F-t; for ( int j = 0 ; j < lp->nbPoints ; j++ ) { float fac = cn[j]*pow(t,j)*pow(mt,lp->nbPoints-1-j); tPos[i]->x += fac * lp->tPos[j]->x; tPos[i]->y += fac * lp->tPos[j]->y; tPos[i]->z += fac * lp->tPos[j]->z; } } free(cn); } void LignePolygonale3D::add(Pos3D *p) { tPos[sp]->x = p->x; tPos[sp]->y = p->y; tPos[sp]->z = p->z; sp++; } void LignePolygonale3D::setPosition(int pos,Pos3D *p) { tPos[pos]->x = p->x; tPos[pos]->y = p->y; tPos[pos]->z = p->z; } void LignePolygonale3D::print(void) { for ( int i = 0 ; i < nbPoints ; i++ ) { tPos[i]->print(); printf("\n"); } } void LignePolygonale3D::drawOpenGL(GLenum typePrimitive) { glBegin(typePrimitive); for ( int i = 0 ; i < nbPoints ; i++ ) { glVertex3f(tPos[i]->x,tPos[i]->y,tPos[i]->z); } glEnd(); }