Classe de vecteurs en 2d / 3d portable, utilisation pour simulations physiques

Soyez le premier à donner votre avis sur cette source.

Vue 9 036 fois - Téléchargée 360 fois

Description

J'ai utilisé cette classe de vecteurs dans plusieurs simulations physiques (cinétiques surtout, physique classique de Newton et Co). L'aspect graphique était géré en OpenGL, mais la classe en elle-même est absolument indépendante de TOUT. Je n'ai rien utilisé de spécial: je n'ai utilisé que iostream pour la fonction de débuggage console, si on l'enlève on peut aussi enlever l'utilisation de la STD. Et puis j'ai aussi inclus math.h, en écrivant à côté les fonctions que j'ai utilisées, donc si vous ne voulez pas utiliser math.h, il vous suffit de réécrire ces fonctions, et tout marchera!

NOTE: le screenshot provient d'une simulation de collisions non-élastiques, les segments colorés sont les vecteurs vitesse des billes

ATTENTION GRANDE MISE A JOUR DU 5 MAI 2005:
--------------------------------------------------------------
je remplace le code (dégueulasse et informe) que j'avais posté ici (quelle daube :/) et je le remplace par deux nouvelles classes écrites récemment, et au passage, vous avez la version 2D et la version 3D. c'est doublement templaté, mais je vous suggères de garder les types proposés dans les 3 typedefs de bas de fichier: V3Di V3Df V3Dd et V2Di V2Df V2Dd. i = int, f = float, d = double.

pas mal de fonctions ont été ajoutées, et puis surtout c'est plus propre ^^

Edit du 30 septembre: correction d'un bug pour GetAngle et ajout des "const" pour les méthodes concernées

Source / Exemple :


//------------------------------------------------------------------------------
#ifndef CVECTEUR2D_H
#define CVECTEUR2D_H
//écrit par Kirua - nicolasboumal@hotmail.com
//------------------------------------------------------------------------------
#include <cmath>    //pour la fonction hypot() (renvoie la racine carrée de la somme des carrés des 2 paramètres)
//------------------------------------------------------------------------------
//Explication: le premier paramètre (T) est le type des coordonnées. Pour un point de l'écran, on voudra
//des int, mais pour un point de l'espace, on préférera float ou même double. Le second paramètre (S)
//indique le type à utiliser pour effectuer les calculs intermédiaires. Il est recommandé d'utilisé un
//type plus précis (par défaut, double) afin d'éviter les pertes trop importantes liées aux arrondis.
template<typename T, typename S = double>
class CVecteur2D
{
    public:
        CVecteur2D() : x(0), y(0) {}
        CVecteur2D(T _x, T _y) : x(_x), y(_y) {}
        CVecteur2D(const CVecteur2D& V) { x = V.x; y = V.y; };
    
        T x, y;
        
        S GetModule() const {return S(hypot(y,x));}
        void SetModule(S m) { S M = GetModule(); x = T(x*m/M); y = T(y*m/M); }
        
        S GetAngle() const { return S(atan2(y, x)); }
        
        CVecteur2D  operator+ (const CVecteur2D& V) const {return CVecteur2D(x+V.x, y+V.y);}
        CVecteur2D  operator- (const CVecteur2D& V) const {return CVecteur2D(x-V.x, y-V.y);}
        CVecteur2D  operator* (const S R) const {return CVecteur2D(T(x*R), T(y*R));}
        CVecteur2D  operator/ (const S R) const {return CVecteur2D(T(x/R), T(y/R));}
        S           operator* (const CVecteur2D& V) const {return x*V.x + y*V.y;}
        CVecteur2D& operator+=(const CVecteur2D& V) {x += V.x; y += V.y; return *this;}
        CVecteur2D& operator-=(const CVecteur2D& V) {x -= V.x; y -= V.y; return *this;}
        CVecteur2D& operator*=(const S R) {x = T(S(x) * R); y = T(S(y) * R); return *this;}
        CVecteur2D& operator/=(const S R) {x = T(S(x) / R); y = T(S(y) / R); return *this;}
        bool        operator==(const CVecteur2D& V) const {return (x == V.x && y == V.y);}
        bool        operator!=(const CVecteur2D& V) const {return (x != V.x || y != V.y);}
};
//------------------------------------------------------------------------------
typedef CVecteur2D<int>    V2Di;
typedef CVecteur2D<float>  V2Df;
typedef CVecteur2D<double> V2Dd;
//------------------------------------------------------------------------------
#endif
//------------------------------------------------------------------------------

Et la classe 3D:

//------------------------------------------------------------------------------
#ifndef CVECTEUR3D_H
#define CVECTEUR3D_H
//écrit par Kirua - nicolasboumal@hotmail.com
//------------------------------------------------------------------------------
#include <cmath>
//------------------------------------------------------------------------------
template<typename T, typename S = double>
class CVecteur3D
{
    public:
        CVecteur3D() : x(0), y(0), z(0) {}
        CVecteur3D(T _x, T _y, T _z) : x(_x), y(_y), z(_z) {}
        CVecteur3D(const CVecteur3D& V) { x = V.x; y = V.y; z = V.z; }
    
        T x, y, z;
        
        S GetModule() const { return S(sqrt(x*x + y*y + z*z)); }
        void SetModule(S m) { S M = GetModule(); x = T(x*m/M); y = T(y*m/M); z = T(z*m/M); }
        
        CVecteur3D  operator+ (const CVecteur3D& V) const {return CVecteur3D(x+V.x, y+V.y, z+V.z);}
        CVecteur3D  operator- (const CVecteur3D& V) const {return CVecteur3D(x-V.x, y-V.y, z-V.z);}
        CVecteur3D  operator* (const S R) const {return CVecteur3D(T(x*R), T(y*R), T(z*R));}
        CVecteur3D  operator/ (const S R) const {return CVecteur3D(T(x/R), T(y/R), T(z/R));}
        S           operator* (const CVecteur3D& V) const {return x*V.x + y*V.y + z*V.z;}
        CVecteur3D& operator+=(const CVecteur3D& V) {x += V.x; y += V.y; z += V.z; return *this;}
        CVecteur3D& operator-=(const CVecteur3D& V) {x -= V.x; y -= V.y; z -= V.z; return *this;}
        CVecteur3D& operator*=(const S R) {x = T(S(x) * R); y = T(S(y) * R); z = T(S(z) * R); return *this;}
        CVecteur3D& operator/=(const S R) {x = T(S(x) / R); y = T(S(y) / R); z = T(S(z) / R); return *this;}
        bool        operator==(const CVecteur3D& V) const {return (x == V.x && y == V.y && z == V.z);}
        bool        operator!=(const CVecteur3D& V) const {return (x != V.x || y != V.y || z != V.z);}
        
        //produit croisé (cross product, produit vectoriel)
        CVecteur3D  operator^  (const CVecteur3D& V) const {return CVecteur3D(y*V.z - z*V.y, z*V.x - x*V.z, x*V.y - y*V.x);}
        CVecteur3D& operator^= (const CVecteur3D& V) {x = y*V.z - z*V.y; y = z*V.x - x*V.z; z = x*V.y - y*V.x; return *this;}
};
//------------------------------------------------------------------------------
typedef CVecteur3D<int>    V3Di;
typedef CVecteur3D<float>  V3Df;
typedef CVecteur3D<double> V3Dd;
//------------------------------------------------------------------------------
#endif
//------------------------------------------------------------------------------

Conclusion :


Si vous trouvez des erreurs / incohérences ... ou si vous avez des suggestions: postez joyeusement.

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

twxs
Messages postés
3
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
21 décembre 2005
-
il est preferable de templater les methodes
template<typename S>
CVecteur2D operator* (const S factor) const
{
return CVecteur2D( T(factor)*x, T(factor)*y );
}
template<typename S>
CVecteur3D(const CVecteur3D<S>& V) { x (T)V.x; y (T)V.y; z = (T)V.z; }
cs_Kirua
Messages postés
3006
Date d'inscription
dimanche 14 avril 2002
Statut
Membre
Dernière intervention
31 décembre 2008
-
pourquoi? ça évite de faire les calculs intermédiaires sur les vecteurs d'entiers avec des entiers, et puis ça évite aussi d'imposer un choix (par exemple: double).

et il y a une faute d'ortho trop bête dans le commentaire -_-
twxs
Messages postés
3
Date d'inscription
dimanche 2 février 2003
Statut
Membre
Dernière intervention
21 décembre 2005
-
j'avais vu, mais pas dit ;), je degagerai aussi le S en parametre de la classe
cs_Kirua
Messages postés
3006
Date d'inscription
dimanche 14 avril 2002
Statut
Membre
Dernière intervention
31 décembre 2008
-
Une chose que je n'ai pas faite dans ce code-ci: les opérateurs + - * / ^ == et != devraient être définis comme 'const', c'est assez important. Désolé de ne pas faire la modif ici.
cs_Kirua
Messages postés
3006
Date d'inscription
dimanche 14 avril 2002
Statut
Membre
Dernière intervention
31 décembre 2008
-
Yup, j'ai pris cette habitude sur ton conseille il y a un paquet de mois déjà :) Enfin, c'est tjs bon à repréciser, j'ai en effet sans doute pas fait la modif ici.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.