Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members

Cylinder Class Reference

#include <cylinder.h>

List of all members.

Public Member Functions

 Cylinder ()
 Cylinder (const Cylinder &cyl)
 Cylinder (const vector< Primitive * > &primAxis, const vector< Primitive * > &primSection)
 Cylinder (const vector< Primitive * > &primAxis, const vector< Primitive * > &primSection, const vector< Primitive * > &primProfile)
 ~Cylinder ()
Vector3DapproximationTangent (Point3D *pt1, Point3D *pt2)
void simpleExtrusion (vector< Point3D * > &points, vector< int > &facets)
void profileExtrusion (vector< Point3D * > &points, vector< int > &facets)
void setClosedSection (bool closed)
void setTwist (int angle)

Private Member Functions

void clearVectors ()
vector< Vector3D * > calculateTangents ()
void calculatePoints (vector< Point3D * > &points, const vector< Vector3D * > &tangents)
void calculateProfilePoints (vector< Point3D * > &points, const vector< Vector3D * > &tangents, vector< double > &radius, vector< int > &indexes)
void calculateFacets (vector< int > &facets)

Private Attributes

int nbSections
vector< Point3D * > points
vector< int > facets
vector< Point3D * > axis
vector< Point3D * > section
vector< Point3D * > profile
bool closedShape
int twistAngle


Detailed Description

La classe Cylinder permet de créer des cylindres généralisés et de leur appliquer soit la méthode d'extrusion simple soit celle d'extrusion profil.

Author:
Guitteny Fabrice

Idiart Baptiste

Le Goff Erwan


Constructor & Destructor Documentation

Cylinder::Cylinder  ) 
 

constructeur par défaut

00004 {}

Cylinder::Cylinder const Cylinder cyl  ) 
 

constructeur par copie

Parameters:
cyl cylindre généralisé

00010 { 00011 nbSections = cyl.nbSections; 00012 points = cyl.points; 00013 facets = cyl.facets; 00014 }

Cylinder::Cylinder const vector< Primitive * > &  primAxis,
const vector< Primitive * > &  primSection
 

constructeur pour l'extrusion simple

Parameters:
primAxis ensemble des primitives de l'axe
primSection ensemble des primitives de la section

00033 { 00034 // on récupère tous les points d'échantillons de toutes les primitives de l'axe 00035 for(unsigned int i = 0; i < primAxis.size() ; i++) 00036 for(unsigned int j = 0 ; j < primAxis[i]->samplesPointsList.size() ; j++) 00037 axis.push_back(primAxis[i]->samplesPointsList[j]); 00038 00039 // idem pour la section 00040 for(unsigned int i = 0; i < primSection.size() ; i++) 00041 for(unsigned int j = 0 ; j < primSection[i]->samplesPointsList.size() ; j++) 00042 section.push_back(primSection[i]->samplesPointsList[j]); 00043 00044 // le nombre de sections est le nombre d'échantillons dans l'axe 00045 nbSections = axis.size(); 00046 }

Cylinder::Cylinder const vector< Primitive * > &  primAxis,
const vector< Primitive * > &  primSection,
const vector< Primitive * > &  primProfile
 

constructeur pour l'extrusion selon le profil

Parameters:
primAxis ensemble des primitives de l'axe
primSection ensemble des primitives de la section
primProfile ensemble des primitives du profil

00054 { 00055 // on récupère tous les points d'échantillons de toutes les primitives de l'axe 00056 for(unsigned int i = 0; i < primAxis.size() ; i++) 00057 for(unsigned int j = 0 ; j < primAxis[i]->samplesPointsList.size() ; j++) 00058 axis.push_back(primAxis[i]->samplesPointsList[j]); 00059 00060 // idem pour la section 00061 for(unsigned int i = 0; i < primSection.size() ; i++) 00062 for(unsigned int j = 0 ; j < primSection[i]->samplesPointsList.size() ; j++) 00063 section.push_back(primSection[i]->samplesPointsList[j]); 00064 00065 // idem pour le profil 00066 for(unsigned int i = 0; i < primProfile.size() ; i++) 00067 for(unsigned int j = 0 ; j < primProfile[i]->samplesPointsList.size() ; j++) 00068 profile.push_back(primProfile[i]->samplesPointsList[j]); 00069 00070 // le nombre de sections est le nombre d'échantillons dans l'axe 00071 nbSections = axis.size(); 00072 }

Cylinder::~Cylinder  ) 
 

00020 { 00021 clearVector(points); 00022 facets.clear(); 00023 clearVector(axis); 00024 clearVector(profile); 00025 clearVector(section); 00026 }


Member Function Documentation

Vector3D * Cylinder::approximationTangent Point3D pt1,
Point3D pt2
 

approximation de la tangente

Parameters:
pt1 point1
pt2 point2
Returns:
vecteur tangente

00090 { 00091 Vector3D tangent = Vector3D(*pt1,*pt2); 00092 return new Vector3D(tangent.normalize()); 00093 }

void Cylinder::calculateFacets vector< int > &  facets  )  [private]
 

calculs des facettes

Parameters:
facets ensemble des facettes

00190 { 00191 // nombre de points d'échantillons dans la section 00192 int rangeOfSamplesSection = section.size(); 00193 00194 // limite variable selon si la section est fermée 00195 int limit; 00196 00197 if (closedShape) 00198 limit = rangeOfSamplesSection; 00199 else 00200 limit = rangeOfSamplesSection - 1; 00201 00202 00203 for(int i = 0 ; i < nbSections -1; i++) 00204 00205 for(int j =0 ; j < limit ; j++) 00206 { 00207 // à chaque fois, on récupère 4 points et on génère 2 facettes triangulaires 00208 00209 // premier triangle 00210 facets.push_back(i*rangeOfSamplesSection + j); 00211 facets.push_back((i+1)*rangeOfSamplesSection + j); 00212 facets.push_back(i*rangeOfSamplesSection + (j+1) % rangeOfSamplesSection); 00213 00214 // deuxième triangle 00215 facets.push_back((i+1)*rangeOfSamplesSection + j); 00216 facets.push_back((i+1)*rangeOfSamplesSection + (j+1) % rangeOfSamplesSection); 00217 facets.push_back(i*rangeOfSamplesSection + (j+1)%rangeOfSamplesSection); 00218 } 00219 }

void Cylinder::calculatePoints vector< Point3D * > &  points,
const vector< Vector3D * > &  tangents
[private]
 

calcul des points pour l'extrusion simple

Parameters:
points ensemble des points
tangents ensemble des tangentes associées

00127 { 00128 // caractérisation du repère de Fresnet 00129 Vector3D normal; // normale au point d'échantillon 00130 Vector3D normalPrev; // normale précédente 00131 Vector3D binormal(0.0,0.0,-1.0); // binormale (plan Oxy --> binormale constante) 00132 00133 // nombre de points d'échantillons dans la section 00134 int rangeOfSamplesSection = section.size(); 00135 00136 // angle de torsion 00137 double angle = 0.0; 00138 00139 for(int i = 0; i < nbSections; i++) 00140 { 00141 // calcul de la normale 00142 normal = binormal ^ *tangents[i]; 00143 00144 // inversion de la normale si elle est opposée à la précédente 00145 if(i != 0) 00146 if((normal * normalPrev) < 0) 00147 normal *= -1; 00148 00149 normalPrev = normal; 00150 00151 // le centre de la section est le point échantillon courant de l'axe 00152 Point3D sectionCenterPoint = *axis[i]; 00153 00154 // calcul de l'angle si la torsion n'est pas nulle 00155 if (twistAngle != 0) 00156 angle += (double) ((twistAngle / nbSections) * M_PI / 180); 00157 00158 for(int j = 0; j < rangeOfSamplesSection; j++) 00159 { 00160 // récupération d'un point échantillon de la section 00161 Point3D sectionPoint = *section[j]; 00162 00163 // calcul de la rotation si la torsion n'est pas nulle 00164 if (twistAngle != 0) 00165 { 00166 double tr_x = sectionPoint[0] - (*axis[0])[0]; 00167 double tr_y = sectionPoint[1] - (*axis[0])[1]; 00168 00169 sectionPoint[0] = (tr_x * cos(angle) - tr_y * sin(angle)) + (*axis[0])[0]; 00170 sectionPoint[1] = (tr_x * sin(angle) + tr_y * cos(angle)) + (*axis[0])[1]; 00171 } 00172 00173 // calcul des coordonnées du point 00174 double x = sectionCenterPoint[0] + (sectionPoint[0] * normal[0] + sectionPoint[1] * binormal[0]) / SCALE_FACTOR_SIMPLE; 00175 double y = sectionCenterPoint[1] + (sectionPoint[0] * normal[1] + sectionPoint[1] * binormal[1]) / SCALE_FACTOR_SIMPLE; 00176 double z = sectionCenterPoint[2] + (sectionPoint[0] * normal[2] + sectionPoint[1] * binormal[2]) / SCALE_FACTOR_SIMPLE; 00177 00178 // ajout du point à la liste 00179 points.push_back(new Point3D(x,y,z)); 00180 } 00181 } 00182 }

void Cylinder::calculateProfilePoints vector< Point3D * > &  points,
const vector< Vector3D * > &  tangents,
vector< double > &  radius,
vector< int > &  indexes
[private]
 

calcul des points pour l'extrusion selon le profil

Parameters:
points ensemble des points
tangents ensemble des tangentes associées
radius rayons associés
indexes indices des points échantillons de l'axe

00229 { 00230 // caractérisation du repère de Fresnet 00231 Vector3D normale; // normale au point d'échantillon 00232 Vector3D normalePrev; // normale précédente 00233 Vector3D binormale(0.0,0.0,-1.0); // binormale (plan Oxy --> binormale constante) 00234 00235 // nombre de points d'échantillons dans la section 00236 int rangeOfSamplesSection = section.size(); 00237 00238 // vectuer tangente 00239 Vector3D tangentNorm; 00240 00241 // angle de torsion 00242 double angle = 0.0; 00243 00244 for(unsigned int i = 0; i < indexes.size(); i++) 00245 { 00246 00247 // vérification de la tangente 00248 if (!tangents[indexes[i]]) 00249 { 00250 if (i > 0) 00251 tangentNorm = *tangents[indexes[i-1]]; 00252 else 00253 tangentNorm = Vector3D(1,0,0); 00254 } 00255 else 00256 tangentNorm = *tangents[indexes[i]]; 00257 00258 // calcul de la normale 00259 normale = binormale ^ tangentNorm; 00260 00261 // inversion de la normale si elle est opposée à la précédente 00262 if(i != 0) 00263 if( (normale * normalePrev) < 0 ) 00264 normale *= -1; 00265 00266 normalePrev = normale; 00267 00268 // le centre de la section est le point échantillon courant de l'axe 00269 Point3D sectionCenterPoint = *axis[indexes[i]]; 00270 00271 // calcul de l'angle si la torsion n'est pas nulle 00272 if (twistAngle != 0) 00273 angle += (double) ((twistAngle / nbSections) * M_PI / 180); 00274 00275 for(int j = 0; j < rangeOfSamplesSection; j++) 00276 { 00277 // récupération d'un point échantillon de la section 00278 Point3D sectionPoint = *section[j]; 00279 00280 // calcul de la rotation si la torsion n'est pas nulle 00281 if (twistAngle != 0) 00282 { 00283 double tr_x = sectionPoint[0] - (*axis[0])[0]; 00284 double tr_y = sectionPoint[1] - (*axis[0])[1]; 00285 00286 sectionPoint[0] = (tr_x * cos(angle) - tr_y * sin(angle)) + (*axis[0])[0]; 00287 sectionPoint[1] = (tr_x * sin(angle) + tr_y * cos(angle)) + (*axis[0])[1]; 00288 } 00289 00290 // calcul des coordonnées du point 00291 double x = sectionCenterPoint[0] + ( (sectionPoint[0]*normale[0] + sectionPoint[1]*binormale[0] ) * radius[i]) / SCALE_FACTOR_PROFILE; 00292 double y = sectionCenterPoint[1] + ( (sectionPoint[0]*normale[1] + sectionPoint[1]*binormale[1] ) * radius[i]) / SCALE_FACTOR_PROFILE; 00293 double z = sectionCenterPoint[2] + ( (sectionPoint[0]*normale[2] + sectionPoint[1]*binormale[2] ) * radius[i]) / SCALE_FACTOR_PROFILE; 00294 00295 // ajout du point à la liste 00296 points.push_back(new Point3D(x,y,z)); 00297 } 00298 } 00299 }

vector< Vector3D * > Cylinder::calculateTangents  )  [private]
 

calcul des tangentes en chaque point échantillon de l'axe

Returns:
vecteur tangent à l'axe

00100 { 00101 vector<Vector3D *> tangents; 00102 Point3D *pt1; 00103 Point3D *pt2; 00104 00105 //calcul des vecteurs tangents aux sections 00106 for(int i = 0; i < nbSections - 1; i++) 00107 { 00108 pt1 = axis[i]; 00109 pt2 = axis[i+1]; 00110 00111 //on ajoute le point a la liste des points origine 00112 Vector3D * tangent = approximationTangent(pt1,pt2); 00113 if(tangent != NULL) 00114 tangents.push_back(tangent); 00115 } 00116 00117 tangents.push_back(tangents[nbSections - 2]); 00118 00119 return tangents; 00120 }

void Cylinder::clearVectors  )  [private]
 

effacer les vecteurs

00079 { 00080 clearVector(points); 00081 facets.clear(); 00082 }

void Cylinder::profileExtrusion vector< Point3D * > &  points,
vector< int > &  facets
 

méthode d'extrusion selon le profil

Parameters:
points ensemble des points
facets ensemble des facettes

00327 { 00328 // on efface les vecteurs 00329 clearVectors(); 00330 00331 // nombre d'echantillons dans le profil 00332 int rangeOfSamplesProfile = profile.size(); 00333 00334 // rapport entre le nombre d'échantillonnage du profil et celui de l'axe 00335 // si le profil est plus échantillonné que l'axe, il faut sur-échantillonner l'axe 00336 int sampleRatio = (int) (rangeOfSamplesProfile / nbSections); 00337 00338 // points d'échantillonage de l'axe après sur-échantillonnage 00339 vector<Point3D *> overSampleAxis; 00340 00341 // sur-échantillonnage si rapport > 1 00342 if (sampleRatio > 1) 00343 { 00344 sampleRatio++; 00345 00346 // on rajoute des points d'échantillonnage dans l'axe par interpolation 00347 for (int i = 0; i < nbSections - 1; i++) 00348 { 00349 double xStep = ( (*axis[i + 1])[0] - (*axis[i])[0] ) / sampleRatio; 00350 double yStep = ( (*axis[i + 1])[1] - (*axis[i])[1] ) / sampleRatio; 00351 for (int j = 0; j < sampleRatio; j++) 00352 { 00353 double x = (*axis[i])[0] + j * xStep; 00354 double y = (*axis[i])[1] + j * yStep; 00355 overSampleAxis.push_back(new Point3D(x,y,0)); 00356 } 00357 } 00358 overSampleAxis.push_back(axis[nbSections - 1]); 00359 nbSections = overSampleAxis.size(); 00360 00361 axis = overSampleAxis; 00362 } 00363 00364 00365 // calcul des tangentes 00366 vector<Vector3D *> tangents = calculateTangents(); 00367 00368 // indices des échantillons de l'axe 00369 // (il faut gérer les rebroussements : 00370 // les indices ne sont donc pas forcément dans le même ordre!) 00371 int index = 0; 00372 00373 // valeurs min et max des y du profil : 00374 // sert à "mapper" le profil sur l'axe (tailles différentes) 00375 double y_min = (*profile[0])[1]; 00376 double y_max = y_min; 00377 00378 // recherche de y_min et y_max 00379 for (int i = 0; i < rangeOfSamplesProfile; i++) 00380 { 00381 double y = (*profile[i])[1]; 00382 if (y < y_min) 00383 { 00384 y_min = y; 00385 index = i; // le point de départ est celui dont le y est minimum et non toujours le 1er de la liste 00386 } 00387 if (y > y_max) 00388 y_max = y; 00389 } 00390 00391 // distance sur les y 00392 double diff_y = y_max - y_min; 00393 00394 vector<int> indexes; // tableau des indices des sections de l'axe à traiter 00395 vector<double> radius; // tableau des rayons associés à chaque section 00396 00397 for (int i = 0; i < rangeOfSamplesProfile - 1; i++) 00398 { 00399 // gestion des rebroussements 00400 int sense; 00401 00402 // différence sur y entre 2 échantillons successifs du profil : permet de connaître le sens 00403 float yVariation = (*profile[i + 1])[1] - (*profile[i])[1]; 00404 00405 if (yVariation != 0.0) // si la variation n'est pas nulle, le sens vaut 1 ou -1 00406 sense = (int) (yVariation / abs(yVariation)); // selon le signe de cette variation 00407 else 00408 sense = 0; // sinon, le sens est nul (2 sections sur le même point) 00409 00410 double currentRadius = (*profile[i])[0]; // rayon du point courant du profil ie sa valeur x 00411 double nextRadius = (*profile[i + 1])[0]; // rayon du point suivant (sert pour l'interpolation) 00412 00413 // nombre de sections de l'axe entre 2 points successifs du profil : 00414 // on "mappe" le profil sur l'axe 00415 int nbSectionsInter = (int) (nbSections * abs(yVariation) / diff_y); 00416 00417 // pour un meilleur rendu, on force le minimum à 2 00418 if (nbSectionsInter < 2) 00419 nbSectionsInter = 2; 00420 00421 // calcul du pas du rayon entre 2 sections intermédiaires (interpolation) 00422 int radiusStep = (int) ( (nextRadius - currentRadius) / (nbSectionsInter - 1)); 00423 00424 // calcul des indices et des rayons associés 00425 for (int j = 0; j < nbSectionsInter - 1; j++) 00426 { 00427 indexes.push_back(index); // ajout de l'indice en cours 00428 radius.push_back(currentRadius + j * radiusStep); // calcul du rayon par interpolation 00429 00430 // gestion des extrémités : 00431 // on ne peut pas reculer si on est au 1er point de l'axe 00432 // ni avancer si on est au dernier 00433 if ( (index == 0) && (sense == -1) ) 00434 sense = 0; 00435 if ( (index == nbSections - 1) && (sense == 1) ) 00436 sense = 0; 00437 00438 // calcul de l'indice suivant selon les rebroussements 00439 index += sense; 00440 } 00441 } 00442 00443 // calcul des points 00444 calculateProfilePoints(points,tangents,radius,indexes); 00445 00446 // le nombre de sections est changé 00447 nbSections = radius.size(); 00448 00449 // calcul des facettes 00450 calculateFacets(facets); 00451 }

void Cylinder::setClosedSection bool  closed  )  [inline]
 

modificateur : si la section est fermée

Parameters:
closed vrai si la section est fermée

00161 {closedShape = closed;}

void Cylinder::setTwist int  angle  )  [inline]
 

modificateur : valeur de l'angle de torsion

Parameters:
angle nouvelle valeur de l'angle

00166 {twistAngle = angle;}

void Cylinder::simpleExtrusion vector< Point3D * > &  points,
vector< int > &  facets
 

méthode d'extrusion simple

Parameters:
points ensemble des points
facets ensemble des facettes

00307 { 00308 // on efface les vecteurs 00309 clearVectors(); 00310 00311 // on calcule les tangentes 00312 vector<Vector3D *> tangents = calculateTangents(); 00313 00314 // calcul des points 00315 calculatePoints(points,tangents); 00316 00317 // calcul des facettes 00318 calculateFacets(facets); 00319 }


Member Data Documentation

vector<Point3D *> Cylinder::axis [private]
 

points échantillons de l'axe

bool Cylinder::closedShape [private]
 

savoir si la section est fermée

vector<int> Cylinder::facets [private]
 

ensemble des facettes générées

int Cylinder::nbSections [private]
 

nombre de sections du cylindre

vector<Point3D *> Cylinder::points [private]
 

ensemble des points générés

vector<Point3D *> Cylinder::profile [private]
 

points échantillons du profil

vector<Point3D *> Cylinder::section [private]
 

points échantillons de la section

int Cylinder::twistAngle [private]
 

angle de torsion


The documentation for this class was generated from the following files:
Generated on Tue Nov 29 21:58:59 2005 for CylinderGenerator by doxygen 1.3.7