GLam Collection version 0.4 -  ACCUEIL -  CLASSES -  HIERARCHIE -  MEMBRES -  EXEMPLES


Pneu et jante

L'objet modélisé ici est une roue du robot Wifibot 4G.
Le programme montre comment créer une classe d'objets par dérivation de la classe GLamGroup.


L'axe de la roue correspond à l'axe 0X du repère, et le diamètre central du pneu est dans le plan 0YZ.


Le pneu est fabriqué par une enveloppe gauche de révolution sur laquelle sont positionnés les crans inclinés. Un cran est défini par un polygone et déformé ensuite au moyen d'une matrice de glissement.


La figure ci-contre (roue droite) est obtenue par création et projection d'un objet de classe WbWheel dans une classe cliente dérivée de GLamWidget (version QtGLam) :

WbWheel* roue ;                        // attribut
... ...
roue = new WbWheel( WbWheel::Right ) ; // création
... ...
roue->draw() ;                         // projection
pneu_example.png


Interface : wbwheel.h

#ifndef WBWHEEL_H
#define WBWHEEL_H

#include <qt4/GLam/glam.h>      // version QtGLam

// dimensions (cm) ------------------------------------------------------------

#define R_Jante     3.10        // rayon extérieur de la jante
#define R_Pneu      6.20        // rayon hors tout du pneu (avec crans)
#define R_Env       5.90        // rayon de l'enveloppe du pneu (hors crans)
#define R_Axe       0.40        // rayon de l'axe
#define R_Fix       0.70        // rayon du logement de la vis axiale
#define L_Pneu      6.00        // largeur hors tout du pneu
#define L_Jante     5.40        // largeur hors tout de la jante
#define L_PneuInt   0.20        // débord intérieur du pneu p/r flasque jante
#define L_PneuExt   ( L_Pneu - L_Jante - L_PneuInt )
#define L2_Axe      3.20        // profondeur du logement de l'axe
#define L_Fix       1.60        // profondeur du lamage pour la vis axiale
#define L_Cran      ( L_Pneu / 2.0 )    // largeur 0X d'un cran
#define L2_Cran     ( 0.3 * L_Cran )    // point de cassure avant du cran
#define H1_Cran     0.90        // largeur 0Y d'un cran au centre du pneu
#define H2_Cran     0.60        // largeur 0Y d'un cran en périphérie du pneu
#define H3_Cran     ( -L_Cran / 3.0 )   // inclinaison 0XY d'un cran
#define Nb_Crans    20          // 20 crans à gauche / 20 crans à droite

// matériaux ------------------------------------------------------------------

#define MAT_Pneu    "BlackRubber"
#define MAT_Jante   "WhitePlastic"

// ----------------------------------------------------------------------------

class WbWheel : public GLamGroup
{
  public :
    enum Side { Left , Right } ;

    WbWheel(Side side ) ;

  private :
    void createTyre() ;
    void createWheel() ;

  private :
    Side                m_side ;
    GLamRevolution*     m_env ;
    GLamTesselation*    m_cran[2] ;
    GLamGroup*          m_pneu ;
    GLamRevolution*     m_jante ;
} ;

#endif


Implémentation : wbwheel.cpp

#include "wbwheel.h"

WbWheel::WbWheel(Side side )
{
  m_side = side ;
  createWheel() ;
}

void WbWheel::createTyre()
{
  XamMatrix   m ;
  int         id ;

  // points de contrôle de l'enveloppe du pneu (ordre trigo)
  double pts_env[][2] = {
    { R_Jante, -L_Pneu / 2 + L_PneuInt }, { 0.70 * R_Env, -L_Pneu / 2 },
    { 0.98 * R_Env, -L_Pneu / 2 }, { R_Env, 0 },  { 0.98 * R_Env, L_Pneu / 2 },
    { 0.70 * R_Env, L_Pneu / 2 }, { R_Jante, L_Pneu / 2 - L_PneuExt } } ;

  // calcul de l'enveloppe par BSpline
  int n = 100 ;
  double* pts = new double[ n * 2 ] ;
  n = GLamObject::bSplinePoints((double*)pts_env,7, pts, n ) ;

  // création de l'objet
  m_env = new GLamRevolution(pts, n, 90 ) ;
  if ( m_side == Left ) {
    m.toScale(-1, 1, 1 ) ;
    m_env->setDefaultTransform( m ) ;
  }

  delete [] pts ;

  // polygone de définition d'un cran de pneu
  double pts_cran[][2] = {
    { 0, 0 }, { L_Cran, H3_Cran }, { L_Cran, H3_Cran + H2_Cran },
    { L2_Cran, H3_Cran * L2_Cran / L_Cran + H2_Cran }, { 0, H1_Cran } } ;

  // création de l'objet cran droit
  GLamRoundedPolygon  tmp( (double*)pts_cran, 5, 0.1, 1 ) ;
  m_cran[0] = new GLamTesselation( tmp ) ;

  double r =  R_Pneu - m_cran[0]->thickness() ;
  double z = -0.1 ;                           // inclinaison 0XZ des crans

    m = XamMatrix(  1,  0,  0,  0,              // shear + translate matrix !
                  0,  1,  0,  0,
                  z,  0,  1,  r,
                  0,  0,  0,  1 ) ;

  m_cran[0]->setDefaultTransform( m ) ;

  // création de l'objet cran gauche
  m_cran[1] = new GLamTesselation( *m_cran[0] ) ;
  m(2,0) = -m(2,0) ;                          // inversion pente du cran
  m_cran[1]->setDefaultTransform( m ) ;
  m.toScale(-1, 1, 1 ) ;                      // réflexion p/r axe Y
  m_cran[1]->multDefaultTransform( m ) ;

  m_pneu = new GLamGroup ;
  id = m_pneu->addObject( m_env ) ;
  m_pneu->addObjectRotate(id, 0, 90, 0) ;

  for ( int i = 0 ; i < Nb_Crans ; ++i ) {
    double a = i * 360.0 / Nb_Crans ;
    id = m_pneu->addObject( m_cran[0] ) ;
    m_pneu->addObjectRotate(id, a, 0, 0 ) ;
    a += 360.0 / ( 2 * Nb_Crans ) ;
    id = m_pneu->addObject( m_cran[1] ) ;
    m_pneu->addObjectRotate(id, a, 0, 0 ) ;
  }

  GLamMaterial  mat_pneu("data/materials.dta", MAT_Pneu ) ;
  m_pneu->setMaterial( mat_pneu.mat10() ) ;
}

void WbWheel::createWheel()
{
  createTyre() ;

  XamMatrix m ;

  // profil de construction de la jante droite
  double  pts_jante[][2] = {
    { R_Jante, L_Jante }, { R_Fix, L2_Axe + L_Fix }, { R_Fix, L2_Axe },
    { R_Axe,  L2_Axe }, { R_Axe, 0 }, { R_Jante, 0 } } ;

  // centrage dans l'axe du pneu
  GLamObject::translatePoints((double*)pts_jante, 6, 0, -L_Pneu / 2 + L_PneuInt ) ;

  m_jante = new GLamRevolution( (double*)pts_jante, 6, 90 ) ;

  m.toRotateY( m_side == Right ? 90 : -90 ) ;
  m_jante->setDefaultTransform( m ) ;

  GLamMaterial  mat_jante("data/materials.dta", MAT_Jante ) ;
  m_jante->setMaterial( mat_jante.mat10() ) ;

  // assemblage
  this->addObject( m_jante ) ;
  this->addObject( m_pneu ) ;
}

Doxygen version 1.5.8 - GLam Collection - (c) 2009-2010 Alain Menu