IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

class Vertex: array member ou héritage de valarray ?


Sujet :

C++

  1. #1
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut class Vertex: array member ou héritage de valarray ?
    Salut les C++,

    Après avoir terminer mon dernier projet: la version 2 de it-edit (Integrated Terminals Editor) que je vous invite a tester si vous êtes sous Linux.

    ---

    J'ai et suis en train, je continue, d'écrire une petite library personnelle pour OpenGL.

    Et donc mon ancienne implémentation de la classe Vertex ressemble a cela:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
     
    #ifndef GL_UTILS_VERTEX_H
    #define GL_UTILS_VERTEX_H
     
     
    #include <array>
    #include <iostream>
    #include <ostream>
     
    using namespace std ;
     
    template <typename T>
    class Vertex {
     
      std::array<T, 4> vertex ;
     
      public :
     
        Vertex() { vertex = {T(0), T(0), T(0), T(0)} ; } ;
     
        Vertex(const Vertex<T> &val) { vertex = val.vertex ; } ;
     
     
     
        Vertex(const T x, const T y, const T z, const T w=1) { vertex={x,y,z,w} ;} ;
     
        Vertex<T>& operator = (const Vertex<T> &val) { vertex = val.vertex ; return *this ; } ;
     
        T& operator [] ( const int idx) { return vertex.at(idx) ; } ;
     
        Vertex& operator -() {
     
          vertex[0] = -vertex[0] ;
          vertex[1] = -vertex[1] ;
          vertex[2] = -vertex[2] ;
     
          return *this ;
        }
     
        // ...
    } ;
     
    #endif
    Et la nouvelle implémentation de la classe Vertex ressemble a ceçi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
     
     
    #ifndef GL_UTILS_VERTEX_H
    #define GL_UTILS_VERTEX_H
     
     
    #include "./../../headers/includes.h"
    // #include "./../../headers/defines.h" #define GL_UTILS_TYPE float // defined in this file.
     
    #include <valarray>
     
    using namespace std ;
     
    class Vertex : valarray<GL_UTILS_TYPE> {
     
      public :
     
        //GL_UTILS_TYPE x = valarray[0] ; this doesn't work i don't know how to implement it.
     
        Vertex() : valarray(3) {} ;
     
        Vertex(const GL_UTILS_TYPE x, const GL_UTILS_TYPE y, const GL_UTILS_TYPE z) : valarray{x,y,z} {} ;
     
        friend ostream& operator<<(ostream &os, Vertex &vertex) {
     
          os << "Vertex at x: " << vertex[0] << ", y: " << vertex[1] << ", z: " << vertex[2] << endl ;
     
          return os ;
     
        } ;
     
        // Is this right to get a pointer on the start of valarray ?
        GL_UTILS_TYPE *get_vertex() { return (GL_UTILS_TYPE *) this ; }    
     
       // To be continued...
     
    } ;
     
    #endif
    Quel est la meilleur solution d'implémentation a votre humble avis:

    1. un membre array de la classe Vertex et écrire tous l'overloading d'opérateur ?

    ou

    2. une classe Vertex héritant de la classe valarray, héritant de tous les bienfaits du valarray.

    ---

    Sinon vous aurez sans doute remarquer que la première implémentation de la classe Vertex est une `template class`.

    Le problème est que je n'arrive pas a compiler en fichier objet une classe template, pour des classes ayant plus de méthodes complexes.


    Que j'aimerai séparer du *.h en fichier *.cpp compilable en fichier objet.


    Est-ce parce que un template n'est pas compilable en fichier objet et sinon dans le cas contraire alors comment faire ???

    ---

    Merci pour vos réponses et votre précieuse aide illuminant les ténèbres de mon ignorance.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Personnellement, je préfère le std::array, parce que sa taille est fixé à la compilation.
    Il n'y a pas d'allocation dynamique, alors qu'il est probable que valarray le fasse, puisse que la taille est un argument de son constructeur.

    Par contre, dans le cas de ta version array, il serait bon que le constructeur soit écrit ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        Vertex(): vertex{0,0,0,0} {}
         Vertex(const Vertex<T> &val) : vertex(val.vertex) {}
    Ainsi, tu n'aurais pas de double initialisation du vertex.

    Surtout, l'opérateur - unaire retourne un autre vertex, il n'a pas lieu de modifier l'objet.

    Concernant la compilation, une template n'est pas une classe. C'est un modèle pour que le compilateur puisse générer des classes (vertex<int>, vertex<double>, etc).
    Le compilateur a besoin de l'intégralité de la template pour cela.
    Tu peux éventuellement écrire les implémentations dans un second .h (parfois nommé .tpp), que tu inclues à la fin du premier.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,
    Citation Envoyé par Luke spywoker Voir le message
    Quel est la meilleur solution d'implémentation a votre humble avis:

    1. un membre array de la classe Vertex et écrire tous l'overloading d'opérateur ?

    ou

    2. une classe Vertex héritant de la classe valarray, héritant de tous les bienfaits du valarray.
    De toutes façons, tu ne dois surtout pas utiliser l'héritage publique, car ta classe Vertex n'est ni un array ni un valarray au sens du LSP.

    De plus, ni std::array ni std::valarray ne sont prévus pour intervenir dans une relation d'héritage publique(leur destructeur est public et non virtuel)

    Tu peux éventuellement envisager l'héritage privé, pour indiquer que ton Vertex est "IMPLEMENTE SOUS LA FORME" d'un std::array / std::valarray, mais tu n'as a priori besoin d'accéder qu'aux fonctions membre publiques de ces classes et non à leurs fonctions membres protégées (y en a-t-il seulement ), ce qui réduit fortement l'intérêt d'un héritage quel qu'en soit la visibilité.

    Si bien que tu as tout aussi bon temps d'utiliser un std::array / std::valarray sous la forme d'un membre de ta classe

    Au passage: Tu ne dois AU GRAND JAMAIS mettre une directive using namespace std; dans un fichier d'en-tête car c'est typiquement le genre de directive qui se répandra comme un virus et qui finira à terme pas poser plus de problèmes qu'elle n'apporte de solutions.

    D'ailleurs, je suis même du genre à être plus virulent que cela vis à vis de cette directive (là, je viens de te donner le conseil "consensuel" ) et, si cela ne tenait qu'à moi, je te dirais volontiers que tu ne dois utiliser cette directive absolument nulle part en justifiant mon point de vue par le fait qu'elle a été mise en place pour permettre au code "pré normalisation" de continuer à fonctionner quand le comité a décidé de faire passer la bibliothèque standard dans l'espace de noms std.

    A part pour du code écrit à l'époque, il est bien plus utile (à mon sens du moins) de profiter de la capacité de séparer clairement les différentes fonctionnalités dans des espaces de noms différents, que de s'éviter l'écriture de cinq caractères de temps en temps
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    Merci pour vos conseils avisées,

    Je pensais que valarray était bien fait pour stocker des valeurs numériques, en outre la méthode shift() aurai été intéressant pour une classe Color.

    Tous les opérateurs sont déjà surchargés et en plus il y a une histoire avec le mot-clef restrict:
    ce qui permet des opérations sur ces classes d'optimiser semblable à l'effet du mot-clé restrict dans le langage de programmation C.
    Dommage seulement qu'il n'y ai pas d'accès au pointeur, comme vector<>.data(), sous-jacent...

    A méditer.


    Sinon j'ai déjà écrit une classe dérivé de pair() pour des coordonnées 2D (x -> first, y -> second).

    Merci pour le conseil concernant le namespace, je pense vraiment l'appliquer.

    Merci pour vos réponses éclairées.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  5. #5
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    Et l'option de réutiliser les classes de la bibliothèque standard plutôt que d'en faire une nouvelle, l'as-tu considérée? A voir l'interface de Vertex,
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    using Vertex = std::valarray<GL_UTILS_TYPE>;
    me paraîtrait tout à fait fonctionnel!
    Idem pour les coordonnées:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    using Coord2D = std::pair<GL_UTILS_TYPE, GL_UTILS_TYPE>

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par stendhal666 Voir le message
    Et l'option de réutiliser les classes de la bibliothèque standard plutôt que d'en faire une nouvelle, l'as-tu considérée? A voir l'interface de Vertex,
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    using Vertex = std::valarray<GL_UTILS_TYPE>;
    me paraîtrait tout à fait fonctionnel!
    Idem pour les coordonnées:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    using Coord2D = std::pair<GL_UTILS_TYPE, GL_UTILS_TYPE>
    Pour un vertex, cela peut effectivement s'envisager, mais pour une coordonnée (qu'elle soit 2D ou 3D), devoir jouer avec first/second (dans le cas d'une std::pair) ou get<0>/get<1>(/get<2>) dans le cas d'un tuple, cela me semble quand même moyen-moyen: typiquement les coordonnées représente l'axe des X, des Y (et des Z), et il serait dommage de retirer ce genre d'information

    Ceci dit, je ne verrais pas de problème à utiliser std::pair ou std::tuple (selon le cas) de manière sous-jacente... De toutes manières, une coordonnée devrait typiquement être utilisée de manière constante -- comme devraient en théorie l'être toutes les classes à sémantique de valeur -- vu que, si l'on change un tant soit peu la valeur de l'un des axes, on obtient bel et bien une coordonnée totalement différente
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Perso, pour une coordonnée (ou un vecteur, c'est strictement identique), j'ai toujours opté pour un simple POD
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     struct Vector {
      double x;
      double y;
      double z;
    };
    T'embellis de quelques helpers comme un constructeur, opérateurs etc et basta.
    Pour l'aspect "sémantique de valeur" etc, osef. C'est le programme qui doit être bien écrit et fournir le vector par const& ou copie quand il ne doit pas être modifié. Inutile de se compliquer la tâche, et btw il est toujours utile et (très) souvent nécessaire de ne modifier que la composante x de ta position. Rien de plus lourd que de devoir se taper une écriture position = Vector(position.x+1, position.y, position.z); au lieu d'un trivial position.x += 1;. C'est lourd, moche, moins lisible et n'apporte rien. C'est un élément simple, qu'on manipule simplement, et régulièrement, alors faisons simple!
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  8. #8
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    mais pour une coordonnée (qu'elle soit 2D ou 3D), devoir jouer avec first/second (dans le cas d'une std::pair) ou get<0>/get<1>(/get<2>) dans le cas d'un tuple, cela me semble quand même moyen-moyen: typiquement les coordonnées représente l'axe des X, des Y (et des Z), et il serait dommage de retirer ce genre d'information
    C'est vrai. D'un autre côté ça fait une classe de moins à créer, documenter, tester, peut-être un ou deux fichiers de moins à inclure et compiler (selon les options).

  9. #9
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    D'un coté, tu vas avoir des coordonnées monde (et caméra) en 3D, et des coordonnées écran en 2D, ce qui signifie probablement deux types, et une fonction de conversion de l'un vers l'autre.

    De plus, tu auras aussi la notion de déplacement (vecteur) et de position (pixel/vertex/...). mathématiquement, les déplacements sont ajoutables, mais pas les positions.
    Tu devrais avoir deux classes distinctes.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  10. #10
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    A vrai dire, je suis tout à fait d'accord avec leternel, à vrai dire : il n'y a absolument rien qui empêche une classe coordonnée d'être implémentée sous la forme d'un vecteur de taille correspondante.

    C'est d'autant plus vrai que tu utiliseras une bonne partie des fonctionnalités propres aux vecteurs pour calculer la "nouvelle coordonnée" de quelque chose qui doit se déplacer (ou lorsque tu devra convertir les coordonnées 2D en coordonnées 3D, ou dans l'autre sens).
    Mais, à la base, tout ce que l'on demande à une coordonnée, c'est de permettre d'obtenir les valeurs relatives aux différents axes envisagé, ce qui représente une interface beaucoup plus réduite que celle qui devrait être exposée par un vecteur.

    Ceci dit, étant donné qu'une classe coordonnée (qu'elle soit 2D ou 3D) peut se contenter de fournir l'accès aux données d'un vecteur (x() qui renvoie vecteur [0], y() qui renvoie vecteur[1] et z() qui renvoie vecteur[2] s'il échoit) si tu teste correctement les comportements de ta/tes classe(s) vecteur, tu peux partir du principe que ta/tes classe(s) coordonnée fonctionne correctement car il n'y a aucun test particulier à faire en plus

    Quant à savoir si on implémente la classe vecteur à l'aide des possibilités offertes par la bibliothèque standard (je verrais bien un std::array pour le coup) ou sous la forme d'un POD, comme proposé par Bousk, je crois que cela ne changera pas forcément grand chose, si ce n'est lorsqu'il s'agira de renvoyer cela vers OpenGL... Et encore, ce sera toujours un memcpy
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  11. #11
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    Merci a tous pour vos avis d'expert avisées,

    ça me parait pas mal le coup des:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    using Vertex = std::valarray<GL_UTILS_TYPE>;
    Mais d'un autre coté je n'utilise que la classe Vertex pour générer mes formes sous forme de fonction renvoyant un std::vector<std::vector<Vertex<float>>> comme par exemple:

    * generate_hemisphere(...)

    * generate_ellipsoid(...)

    * etc...

    Donc d'un autre coté pas besoin de surcharger le truc car je copie les float après dans un VertexBuffer lors de l'initialisation d'une classe Hemisphere ou Ellipsoid...

    Mais tous cela est encore sous forme très brouillon et sûrement a reformater...

    Par ailleurs ont peut faire comme cela pour une coordonnée 2D:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    #include <iostream>
     
    class Coord : std::pair<float, float> {
     
      public :
     
        float x = this->first ;
        float y = this->second ; 
     
        Coord(float x, float y) : pair(x,y) {} ;
    } ;
     
    int main(int argc, char *argv[]) {
     
      Coord my_coord(1.5f, 2.5f) ;
     
      std::cout << my_coord.x << " " << my_coord.y << std::endl ;
     
    }
    Merci a tous.
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  12. #12
    Membre chevronné

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Points : 1 878
    Points
    1 878
    Billets dans le blog
    21
    Par défaut
    Par ailleurs ont peut faire comme cela pour une coordonnée 2D:
    hum... il y a un petit problème avec ton code...

    float x = this->first ;
    float y = this->second ;
    cela fait 4 float par coordonnées, c'est un peu beaucoup...
    et si quelqu'un a le malheur d'utiliser coord.x à un endroit et coord.first à un autre, ça va être funky.

  13. #13
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Luke spywoker Voir le message
    Merci a tous pour vos avis d'expert avisées,

    ça me parait pas mal le coup des:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    using Vertex = std::valarray<GL_UTILS_TYPE>;
    Mais d'un autre coté je n'utilise que la classe Vertex pour générer mes formes sous forme de fonction renvoyant un std::vector<std::vector<Vertex<float>>> comme par exemple:
    Sur ce coup là, tu serait sans doute bien inspiré de créer une classe "matrice" qui pourrait "linéariser" l'accès à tes éléments.

    En effet, std::vector utilise l'allocation dynamique de la mémoire pour la représentation des éléments qu'ils contient, si bien que, si tu as X lignes de Y éléments, tu n'as absolument aucune garanties que les Y éléments d'une ligne particulière soit contigus avec les éléments des lignes qui précèdent ou qui suivent.

    De plus, en utilisant un std::vector<std::vector<UnType>, il n'y a aucune obligation pour que chaque ligne soit composée... du même nombre d'éléments. Or, si tu joues avec OpenGL, c'est un aspect pour lequel tu apprécierais surement d'avoir ce genre de garantie

    Or, lorsque tu crée un std::vector<std::vector<UnType>> c'est, à la base, parce que tu veux pouvoir représenter NombreDeLignes * NombreDeColonnes éléments... On peut donc faire tenir tous ces éléments dans ...un tableau "à une seule dimension" qui contiendra cette valeur totale, et on peut accéder assez facilement à un élément donné se trouvant à une ligne et à une colonne donnée grâce à la formule élémentRecherché = ligneRecherchée * nombreDeColonnes + colonneRecherchéeUn truc assez sympa est donc de créer une classe qui pourrait ressembler à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    template <typename Type>
    class Matrix{
    public:
        Matrix(size_t lines, size_t columns, T defaultValue={}):lines_{lines},columns_{column},
            datas_(lines*columns){
            std::fill(datas_.begin(), datas_.end(), defaultValue);
        }
        T operator()(size_t l, size_t c) const{
            assert(l < lines_ && "line out of range");
            assert(c < columns_ && "column out of range");
            return data_[l*columns_ + c];
        }
        T& operator()(size_t l, size_t c) {
            assert(l < lines_ && "line out of range");
            assert(c < columns_ && "column out of range");
            return data_[l*columns_ + c];
        }
    private:
        size_t lines_;
        size_t columns_;
        std::vector<T> datas_;
    };
    (note d'ailleurs que, si tu as la possibilité de connaitre les dimensions de la matrice à la compilation, il y a surement encore mieux à faire )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  14. #14
    Membre expérimenté
    Avatar de Luke spywoker
    Homme Profil pro
    Etudiant informatique autodidacte
    Inscrit en
    Juin 2010
    Messages
    1 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant informatique autodidacte

    Informations forums :
    Inscription : Juin 2010
    Messages : 1 077
    Points : 1 742
    Points
    1 742
    Par défaut
    En faites ma classe Matrix,

    est basé sur un array<T, 4*4> a une dimension...
    Pour faire tes armes:
    Use du présent pour construire ton futur sinon use de ce que tu as appris auparavant.
    Et sois toujours bien armé avant de te lancer.
    Le hasard ne sourit qu'aux gens préparés...
    Site: Website programmation international (www.open-source-projects.net)
    Site: Website imagerie 3D (www.3dreaming-imaging.net)
    Testez aux moins pendant une semaine l'éditeur avec terminaux intégrées it-edit Vous l'adopterai sûrement !
    FUN is HARD WORK !!!

  15. #15
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Luke spywoker Voir le message
    En faites ma classe Matrix,

    est basé sur un array<T, 4*4> a une dimension...
    C'est une idée, mais tu pourrais généraliser encore énormément les choses : 4*4, ca semble être pas mal, mais... pourquoi 4*4 et pas 2*2, 3*3 ou 3*4 question:

    Cela toutes ces solutions peuvent très facilement correspondre à la définition mathématique de "matrice"

    Tu pourrais donc parfaitement avoir une classe matrice tout à fait générique proche de (code à main levé, mérite sans doute quelques aménagements )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    template <typename T, size_t L, size_t C>
    class Matrix{
        /* parce que ce sera plus facile à utiliser */
        template <typename U>
        using Data_t = std::array<U, L * C>;
    public:
        /* juste pour récupérer ces valeurs, en cas de besoin */
        enum{
            maxLines = L,
            maxCols = C
        };
       Matrix(T defaultValue = T{}){
           std::fill(datas_.begin(),datas_.end(),defaultValue);
       }
       T operator()(size_t l, size_t c) const{
           asssert(l < maxLines && "line out of range");
           assert( c < maxCols && "column out of range");
           return datas_[l*maxCols + c];
       }
       T & operator()(size_t l, size_t c) {
           asssert(l < maxLines && "line out of range");
           assert( c < maxCols && "column out of range");
           return datas_[l*maxCols + c];
       }
    private:
        Data_t datas_;
    };
    quitte à renommer la classe que je présentais dans mon intervention précédente en "DynMatrix", par exemple
    Et, bien sur, il y a surement un max de choses à rajouter (le calcul du déterminant, les opérations matricielles "classiques", ...), mais bon, je te laisse jouer avec ca
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Vertex arrays
    Par goutbouyo dans le forum OpenGL
    Réponses: 9
    Dernier message: 06/01/2005, 13h11
  2. classe Vertex
    Par nicolas66 dans le forum OpenGL
    Réponses: 21
    Dernier message: 26/11/2004, 23h19
  3. [SDL+glut] vertex array précompilés
    Par khayyam90 dans le forum OpenGL
    Réponses: 3
    Dernier message: 01/10/2004, 17h07
  4. vertex array
    Par Jbx 2.0b dans le forum OpenGL
    Réponses: 2
    Dernier message: 12/07/2004, 11h37
  5. Performance des vertex array
    Par Mathieu.J dans le forum OpenGL
    Réponses: 13
    Dernier message: 25/06/2004, 10h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo