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

OpenGL Discussion :

lier un cube à un objet (POO)


Sujet :

OpenGL

  1. #1
    Membre régulier Avatar de Hypnos
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 87
    Points : 108
    Points
    108
    Par défaut lier un cube à un objet (POO)
    Bonjour,

    Je me suis créé un petit monde en 3D (une maison, deux sapins, une pelouse, une rivière). Rien d'extraordinaire, je sais .
    Voilà pour la partie OpenGL.

    En C++, j'ai créé un petit algorithme qui permet de déplacer un objet (au sens POO du terme) suivant certaines formules et suivant les agissements de l'utilisateur.

    J'aimerais lier cet objet (POO) à un cube en OpenGl, pour que lorsque l'utilisateur fasse avancer mon objet, graphiquement il déplace le cube.
    Y a-t-il une syntaxe spéciale ou je dois tout gérer par variable ?

    Question subsidiaire : connaîtriez-vous un site qui référencie toutes des formules pour gérer la gravité, des rebonds, etc...
    Je ne cherche pas à créer un moteur physique, mais qqchose qui tienne un peu plus la route que ce que j'ai actuellement.
    J'ai cherché sur , mais je n'ai rien trouvé de très explicite et compréhensible .

    Je suis sous Windows, sans Glut.

    Merci.

  2. #2
    Membre averti Avatar de charly
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 329
    Points : 358
    Points
    358
    Par défaut
    bah moi j ai fais un truc tous simple a cree en delphi ... un system vectoriel qui aplique a chaque trajectoire , une resistance de l air ( exprimer en % ) et un vecteur vers le bas represantant la graviter ... suivant ses donnes tu peux facilement donner une impression de trajectoire coherante ... pour les rebonds ... tu cree la meme trajectoire diviser .... sa rends bien ! en general

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 41
    Points
    41
    Par défaut
    Tu peux assez facilement trouver des trucs comme celui de charly pour "émuler" un moteur de physique sans te conformer aux vraies équations, il suffit d'un peu d'astuce. Maintenant, si tu veux que tes objets respectent vraiment les lois de la physique :

    Citation Envoyé par Hypnos
    je n'ai rien trouvé de très explicite et compréhensible
    Normal : la physique n'a rien d'explicite et de compréhensible !! (et encore moins la physique des chocs...) Il faudra donc aller voir des sites de physique et de maths plutôt que des sites de développement...

    Moi perso, les seules équations vraiment exactes que j'utilise pour rendre un mouvement réaliste sont celles de la vitesse et de la position en fonction du temps et de l'accélération :
    - la vitesse est l'intégrale de l'accélération par rapport au temps :
    vitesse = vitesseInitiale + acceleration*frameTime
    - la position est l'intégrale double de l'accélération par rapport au temps :
    position = positionInitiale + (acceleration*frameTime*frameTime)/2 + vitesse*frameTime

    C'est la seule façon d'obtenir un effet d'inertie qui soit le même quel que soit le frametime (donc quelles que soient les perf de la machine). Par contre, je ne prend pas encore en compte la masse de l'objet. C'est-à-dire qu'au lieu de demander à l'utilisateur la masse de l'objet et la résultante des forces, puis de calculer l'accelération (F=m.a), le moteur demande directement l'accelération à l'utilisateur...

    Si tu ne trouve pas ces 2 équations assez explicites et compréhensible, dis-le moi je détaillerai...

  4. #4
    Membre averti Avatar de charly
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 329
    Points : 358
    Points
    358
    Par défaut
    ah tien j aime bien je prends , merci patapez
    En faite tous depant de ce que tu veux faire , moi je suis plus orienter jeux video , et donc , une aproximiter et tolerer , mais si tu veux faire des graphique pousser et conforme a une realites exacte , alors ouvre tes bouquin de physique , et chope des equation

  5. #5
    Membre régulier Avatar de Hypnos
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 87
    Points : 108
    Points
    108
    Par défaut
    PataPetz >> Merci pour les équations, je prends aussi .

    Juste une précision, c'est quoi l'unité de mesure de l'accélération?

    Charly >> Tu utilises des vecteurs, ok, mais les paramètres d'un vecteur sont sa norme, sa direction et son sens. Tu intègres tout ça, ou tu utilises juste une force d'une certaine valeur
    ->
    F ?

    Prenons la gravité qui vaut en Europe 9.2 (euh...je crois que c'est ça ), tu utilises F = 9.2 ? et après, comment tu intègres cette valeur en direction verticale, sens vers le bas ? Tu fais une addition de vecteurs ?

    Tu pourrais mettre un exemple stp ?

  6. #6
    Membre averti Avatar de charly
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 329
    Points : 358
    Points
    358
    Par défaut
    non , je n utilise ni direction , ni sens ... le vecteur est deja definis ... ( on parlera de vertex plutot )
    soit V(x,y,z)
    a chaque trajectoire ( aussi representer par un vecteur T(x,y,z) ) tu apliquez le vecteur V ! tous depant maintenant de tes reglages , mais la graviter etant une force verticale ( enfin d apres la physique non , l espace est isotrope , mais sa on s en fout ) donc on peux resumer le vecteur V comme sa : V(0,N,0) ou le N represente bien sur la norme ( donc l instensites de la force ) . Pour l apliquer a ton vertex de trajectoire :
    T(x,y,z) tu fais une simple addition T(x+0,y+n,z+0) et tu apliques aux points suivant la trajectoire le nouveau vertex T .

    Ce systeme d emulation de gravites et ultra simple et facile a realiser ... tu n as qu a changer la norme pour accentuer ou diminuer la force de la graviter ... et sa donne des exelents resultats.... en esperant avoir ete clair

  7. #7
    Membre régulier Avatar de Hypnos
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 87
    Points : 108
    Points
    108
    Par défaut
    oui très, merci, mais y a quand même encore qqchose que je ne comprends pas. La gravité est une force verticale, c'est pas la coordonnée Z la verticale ?
    Parce que tu mets : V(0, N, 0)

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par Hypnos
    les paramètres d'un vecteur sont sa norme, sa direction et son sens
    Ces 3 paramètres ont beau être nécessaires et suffisants pour décrire un vecteur, il est déconseillé de les utiliser pour représenter numériquement un vecteur. Comme le dit Charly, un vecteur 3D est représenté par ses 3 coordonnées x, y, z. A partir de là tu peux calculer la norme la direction, le sens... l'opération inverse serait nettement plus lourde !
    Si tu veux faire des maths par l'informatique, je te conseille de bien te renseigner dés le début sur la façon de représenter chaque type de données, sinon tu vas t'arracher les cheveux !!! (et faire perdre du temps à ton µP). Par exemple, même si un plan peux être représenté par 3 points lui appartenant, il n'est pas difficile de comprendre que cette représentation est beaucoup trop monolythique, et que l'utilisation de l'équation de plan Ax+By+Cz-D=0 (ou Ax+By+Cz+D=0 selon la convention choisie...) est bien plus adaptée au calcul numérique...

    Sinon pour répondre à ta question, l'accélération s'exprime bien sûr en [u/s²] (u étant l'unité de longueur, par exemple le mètre ou l'unité openGL). La vitesse étant exprimée en u/s, une différence de vitesse l'est aussi. Or, une accélération représente le différentiel de vitesse par seconde, donc des [[unités par seconde] par seconde], donc des [[u/s]/s], donc des [u/s²].
    Bien sûr je prend ici la seconde comme unité de temps mais c qu'un exemple.

    Sinon pour info, il fo garder à l'esprit la relation entre [m/s²] et [N/kg]. En effet, la 3è loi de newton nous dit : F=m.a. Donc :
    [N] = [kg].[m/s²]
    [N/kg] = [m/s²]
    Par conséquent, la gravitation de 9.2 dont tu parle peut s'exprimer des deux façon : on peut dire qu'elle est de 9.2 N/kg, mais aussi 9.2 m/s². Et c'est cette dernière forme qui nous intéresse le plus, puisqu'elle permet de constater qu'il s'agit d'une accélération, indépendante de la masse de l'objet qui subit cette force de gravitation (en négligent le frottement de l'air, un objet tombe à la même vitesse quel que soit son poids). Cela répond à ta 2è question : pour intégrer cette valeur dans tes calculs, ben il suffit de la mettre à la place de "accélération" dans mes équations... et ton objet sera en chute libre au dessus de l'Europe !

  9. #9
    Membre régulier Avatar de Hypnos
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 87
    Points : 108
    Points
    108
    Par défaut
    ok patapetz merci pour ces éclaircissements.

    C'est vrai qu'il est inutile de surcharger le cpu si des fonctions approximatives peuvent faire à peu près la même chose (mon truc doit pas être précis du tout) et donc utiliser directement les coordonnées du vecteur est bien plus simple.

    Pour l'accélération, je savais que qqchose était au carré, mais je savais plus quoi .

    Ok très bien merci à tous les deux, je vais essayer d'intégrer tout ça.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 41
    Points
    41
    Par défaut
    Citation Envoyé par Hypnos
    C'est vrai qu'il est inutile de surcharger le cpu si des fonctions approximatives peuvent faire à peu près la même chose
    Je me suis mal fait comprendre : cette façon de représenter un vecteur n'a rien d'approximatif, c'est AU CONTRAIRE la SEULE façon vraiment précise de représenter un vecteur, SANS PERTE DE PRECISION durant les calculs !!!!!
    En effet, essayons d'examiner la représentation d'un vecteur avec une norme, une direction et un sens :
    - norme : c'est un scalaire
    - direction : c'est un vecteur de norme 1. Premier problème : à chaque opération effectuée sur le vecteur, il va falloir vérifier que la norme est toujours 1, et renormaliser si nécessaire, ce qui implique une perte évidente de précision (je ne parle pas ici de perte de temps, mais bien de perte de PRECISION).
    - sens : un booléen
    - Mais surtout deuxième problème : il aura fallu un total de 5 valeur pour représenter un vecteur en trois dimensions !! On se retrouve donc dans un cas où 2 ensemble différents de 5 valeurs peuvent représenter un même vecteur. En d'autres termes, la fonction faisan correspondre l'ensemble des éléments à 5 valeurs avec l'ensemble des vecteurs de l'espace N'EST PAS BIJECTIVE, et ça c'est très grave !

    Il faut TOUJOURS représenter les choses avec le nombre MINIMUM de données pouvant mathématiquement le représenter. Il y a plein d'exemples :
    - cas d'un plan : pour reprendre l'exemple précédent, la première méthode (celle des 3 points) utilise 9 valeurs pour représenter un plan, tandis que la deuxième (Ax+By+Cz-D=0) n'en utilise que 4 (A, B, C, D). La 2è est donc mathématiquement préférable.
    - cas d'une rotation : on peut représenter un rotation par une matrice 3x3. On utilise alors 9 valeurs. Cela implique des problème de perte de précision liés au fait que toute matrice 3x3 ne représente pas une rotation. On peut même perdre un degrés de liberté à cause du phénomène de gimbal lock ! Tous ces problèmes n'existe plus grâce aux quaternion, qui permettent de représenter exactement la même chose grâce à 4 valeurs seulement !! Encore une fois, c'est la solution a adopter.

    Bref, tout ça pour te faire comprendre que le fait que l'on utilise moins de valeurs pour représenter la même données ne revèle pas une imprécision, mais au contraire une représentation mathématiquement et surtout numériquement bien meilleure !!!

  11. #11
    Membre averti Avatar de charly
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    329
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 329
    Points : 358
    Points
    358
    Par défaut
    l histoire des quaternion m interresse , tu n aurais pas une doc dessu ?

  12. #12
    Membre régulier Avatar de Hypnos
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2002
    Messages : 87
    Points : 108
    Points
    108
    Par défaut
    ok, ok, c'est vrai que je n'avais pas compris ça comme ça, merci bien.

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 55
    Points : 41
    Points
    41
    Par défaut
    Charly>> doc quaternion

    Cette faq m'a pas mal servi au début :
    http://membres.lycos.fr/javamus/articles/mqfaq.html
    Note : le site "Javamus" dont elle est tirée est particulièrement intéressant, je vous conseille d'y faire un tour !

    Tu trouveras sur www.magic-software.com, dans la section source/documentation je crois, un article de David Eberly "Quaternion algebra & calculus", assez complet.
    Note : idem, le reste du site est super intéressant, et les articles d'Eberly toujours très complets.

    Sinon il ya une site spécial sur les quaternions (ya vraiment des fous ) mais je me souviens plus de l'@.

    Par contre je te préviens tout de suite que c'est quand même bien chaud les quaternion, t'as intérêt à t'accrocher. Pas plus tard qu'aujourd'hui g un pote qui a voulu s'y mettre, il a pété les plombs.

    Voici ma classe Quaternion :
    Quaternion.h :
    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
    45
    46
    47
    48
    49
    50
    #ifndef _QUATERNION_H_
    #define _QUATERNION_H_
     
     
    #include "Point3.h"
     
     
    class Quaternion
    {
    private:
    	Point3<float> _v;
    	float _w;
     
    public:
    	// Constructeurs
    	Quaternion();
    	Quaternion(float, float, float, float);
    	Quaternion(const Point3<float>&, float); // ATTENTION : axis & angle NE REPRESENTENT PAS _v & _w
     
    	// Opérateurs
    	friend Quaternion operator+ (const Quaternion&, const Quaternion&);
    	friend Quaternion operator/ (const Quaternion&, float);
    	friend Quaternion operator* (const Quaternion&, const Quaternion&);
    	friend Quaternion operator* (const Quaternion&, float);
    	Quaternion& operator*= (const Quaternion&);
     
    	// Fonctions de modification
    	void normalize();
    	void rotate(const Point3<float>&, float);
    	void rotate(const Quaternion&);
    	void power(float);
     
    	// Fonctions de consultation
    	const Point3<float>& vPart() const;
    	float wPart() const;
     
    	float getNorm() const;
    	Point3<float> getAxis() const;
    	float getAngle() const;
    	Quaternion getConjugate() const;
    	Quaternion getPower(float) const;
    	Quaternion getSlerp(const Quaternion&, float) const;
     
    	Point3<float> getRightAxis() const;
    	Point3<float> getViewAxis() const;
    	Point3<float> getUpAxis() const;
    };
     
     
    #endif
    Quaternion.cpp :
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    #include "Quaternion.h"
     
     
    // Constructeurs
     
    Quaternion::Quaternion() :
    _v((float)0,(float)0,(float)0), _w((float)1.f)
    {}
     
    Quaternion::Quaternion(float x, float y, float z, float w) :
    _v(x,y,z), _w(w)
    {}
     
     
    Quaternion::Quaternion(const Point3<float> &axis, float angle)
    // ATTENTION : axis et angle NE REPRESENTENT PAS _v et _w
    {
    	float sina = (float)sin(angle/(float)2);
     
    	_v.setCoordinates(axis.x*sina, axis.y*sina, axis.z*sina);
    	_w = (float)cos(angle/(float)2);
     
    	normalize();
    }
     
     
    // Opérateurs
     
    Quaternion operator+ (const Quaternion &q1, const Quaternion &q2)
    { return Quaternion(q1._v.x+q2._v.x, q1._v.y+q2._v.y, q1._v.z+q2._v.z, q1._w+q2._w); }
     
    Quaternion operator/ (const Quaternion &q, const float scal)
    {
    	Quaternion result(q);
     
    	result._v /= scal;
    	result._w /= scal;
     
    	return result;
    }
     
    Quaternion operator* (const Quaternion &q1, const Quaternion &q2)
    {
    	Quaternion result;
     
    	result._w = q1._w*q2._w - q1._v.dot(q2._v);
    	result._v = q1._w*q2._v + q2._w*q1._v + q1._v.cross(q2._v);
     
    	return result;
    }
     
    Quaternion operator* (const Quaternion& q, float f)
    { return Quaternion(q._v.x*f, q._v.y*f, q._v.z*f, q._w*f); }
     
    Quaternion& Quaternion::operator*= (const Quaternion &q)
    {
    	*this = *this*q;
    	return *this;
    }
     
     
     
    // Fonctions de modification
     
    void Quaternion::normalize()
    {
    	float len = getNorm();
     
    	_v /= len;
    	_w /= len;
    }
     
    void Quaternion::rotate(const Point3<float> &axis, float angle)
    {
    	Quaternion r(axis, angle);
    	rotate(r);
    }
     
    void Quaternion::rotate(const Quaternion &q)
    {
    	*this = q*(*this);
    	normalize();
    }
     
    void Quaternion::power(float t)
    {
    	float angle = getAngle();
     
    	try
    	{
    		Point3<float> u = _v.getNormal();
    		_v = u*(float)sin(t*angle);
    		_w = (float)cos(t*angle);
    		normalize();
    	}
    	catch (const NullVectorException&)
    	{
    		_v = 0.f;
    		_w = 1.f;
    	}
    }
     
     
    // Fonctions de consultation
     
    const Point3<float>& Quaternion::vPart() const
    { return _v; }
     
    float Quaternion::wPart() const
    { return _w; }
     
     
    float Quaternion::getNorm() const
    { return (float)sqrt(_w*_w + _v.x*_v.x + _v.y*_v.y + _v.z*_v.z); }
     
    Point3<float> Quaternion::getAxis() const
    {
    	float sinus = (float)sqrt((float)1 - _w*_w);
     
    	if (fabs(sinus) < 0.0005f)
    		sinus = (float)1;
     
    	Point3<float> result(_v.x / sinus, _v.y / sinus, _v.z / sinus);
    	return result;
    }
     
    float Quaternion::getAngle() const
    { return (float)acos(_w)*2.f; }
     
    Quaternion Quaternion::getConjugate() const
    {
    	Quaternion result = *this;
    	result._v = -(result._v);
     
    	return result;
    }
     
    Quaternion Quaternion::getPower(float t) const
    {
    	Quaternion result = *this;
    	result.power(t);
    	return result;
    }
     
    Quaternion Quaternion::getSlerp(const Quaternion& q, float t) const
    { return (*this)*(getConjugate()*q).getPower(t); } 
     
     
    Point3<float> Quaternion::getRightAxis() const
    {
    	float x=_v.x, y=_v.y, z=_v.z;
     
    	return Point3<float>(1 - 2*(y*y + z*z),
    	                     2*(x*y + z*_w),
    	                     2*(x*z - y*_w));
    }
     
    Point3<float> Quaternion::getViewAxis() const
    {
    	float x=_v.x, y=_v.y, z=_v.z;
     
    	return Point3<float>(2*(z*x + y*_w),
    	                     2*(z*y - x*_w),
    	                     1 - 2*(x*x + y*y));
    }
     
    Point3<float> Quaternion::getUpAxis() const
    {
    	float x=_v.x, y=_v.y, z=_v.z;
     
    	return Point3<float>(2*(y*x - z*_w),
    	                     1 - 2*(x*x + z*z),
    	                     2*(y*z + x*_w));
    }
    Il te faut la classe Point3 (tu constatera d'ailleurs que cette classe utilise tout bêtement un quaternion pour sa méthode rotate, ce qui la réduit à 2 lignes... c génial les quaternions !)

    Point3.h : (c une classe template => pas de .cpp)
    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
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    #ifndef _POINT3_H_
    #define _POINT3_H_
     
     
    #include <math.h>
    #include "DivisionByZeroException.h"
    #include "NullVectorException.h"
     
    class Quaternion;
     
     
    #define POINT3_PIDIV180	1.74532925199433E-002f
     
     
    template <class T>
    class Point3
    {
    public:
       T x, y, z;
     
       Point3();
       Point3(T, T, T);
       Point3(const T&);
       virtual ~Point3() {};
     
       Point3<T>& operator= (const Point3<T>&);
       Point3<T>& operator= (const T&);
     
       friend int operator== (const Point3<T>&, const Point3<T>&);
       friend int operator== (const Point3<T>&, const T&);
       friend int operator== (const T&, const Point3<T>&);
       friend int operator!  (const Point3<T>&);
     
       friend int operator< (const Point3<T>&, const Point3<T>&);
       friend int operator< (const Point3<T>&, const T&);
       friend int operator< (const T&, const Point3<T>&);
     
       friend int operator> (const Point3<T>&, const Point3<T>&);
       friend int operator> (const Point3<T>&, const T&);
       friend int operator> (const T&, const Point3<T>&);
     
       friend int operator<= (const Point3<T>&, const Point3<T>&);
       friend int operator<= (const Point3<T>&, const T&);
       friend int operator<= (const T&, const Point3<T>&);
     
       friend int operator>= (const Point3<T>&,const  Point3<T>&);
       friend int operator>= (const Point3<T>&,const  T&);
       friend int operator>= (const T&, const Point3<T>&);
     
       friend Point3<T> operator+ (const Point3<T>&, const Point3<T>&);
       friend Point3<T> operator- (const Point3<T>&, const Point3<T>&);
       friend Point3<T> operator- (const Point3<T>&);
       friend Point3<T> operator* (const Point3<T>&, const T&);
       friend Point3<T> operator* (const T&, const Point3<T>&);
       friend Point3<T> operator/ (const Point3<T>&, const T&);
     
       Point3<T>& operator+= (const Point3<T>&);
       Point3<T>& operator-= (const Point3<T>&);
       Point3<T>& operator*= (const T&);
       Point3<T>& operator/= (const T&);
     
       float dot(const Point3<T>&) const;
       Point3<T> cross(const Point3<T>&) const;
       float projection(const Point3<T>&) const;
     
       T getCoordinate(int) const;
       T getLength() const;
       T getSquare() const;
       T cosinus(const Point3<T>&) const;
       bool isColinear(const Point3<T>&) const;
       Point3<T> getNormal() const;
     
       void setCoordinates(T, T, T);
       void setCoordinate(int, T);
       void rotate(T, const Point3<T>&);
       void rotate(const Quaternion&);
       void normalize();
    };
     
     
    /* Constructeurs */
     
    template <class T>
    Point3<T>::Point3()
    : x((T)0), y((T)0), z((T)0) {}
     
    template <class T>
    Point3<T>::Point3(T a, T b, T c)
    : x(a), y(b), z(c) {}
     
    template <class T>
    Point3<T>::Point3(const T& val)
    : x(val), y(val), z(val) {}
     
     
    /* Opérateurs d'affectation */
     
    template <class T>
    Point3<T>& Point3<T>::operator= (const Point3<T> &v)
    {
    	if (&v != this)
    	{
    		x = v.x;
    		y = v.y;
    		z = v.z;
    	}
     
    	return *this;
    }
     
    template <class T>
    Point3<T>& Point3<T>::operator= (const T &val)
    {
    	x = val;
    	y = val;
    	z = val;
     
    	return *this;
    }
     
     
    /* Opérateurs de comparaison */
     
    template <class T>
    int operator== (const Point3<T> &v1, const Point3<T> &v2)
    { return (v1.x==v2.x && v1.y==v2.y && v1.z==v2.z); }
     
    template <class T>
    int operator== (const Point3<T> &v, const T &l)
    { return (v.getSquare() == powf((float)l,2)); }
     
    template <class T>
    int operator== (const T &l, const Point3<T> &v)
    { return (v == l); }
     
    template <class T>
    int operator! (const Point3<T> &v)
    { return (v == (T)0); }
     
     
    template <class T>
    int operator< (const Point3<T> &v1, const Point3<T> &v2)
    { return (v1.getSquare() < v2.getSquare()); }
     
    template <class T>
    int operator< (const Point3<T> &v, const T &l)
    { return (v.getSquare() < l*l); }
     
    template <class T>
    int operator< (const T &l, const Point3<T> &v)
    { return (v > l); }
     
     
    template <class T>
    int operator> (const Point3<T> &v1, const Point3<T> &v2)
    { return (v1.getSquare() > v2.sqMag); }
     
    template <class T>
    int operator> (const Point3<T> &v, const T &l)
    { return (v.getSquare() > l*l); }
     
    template <class T>
    int operator> (const T &l, const Point3<T> &v)
    { return (v < l); }
     
     
    template <class T>
    int operator<= (const Point3<T> &v1, const Point3<T> &v2)
    { return (v1.getSquare() <= v2.getSquare()); }
     
    template <class T>
    int operator<= (const Point3<T> &v, const T &l)
    { return (v.getSquare() <= l*l); }
     
    template <class T>
    int operator<= (const T &l, const Point3<T> &v)
    { return (v >= l); }
     
     
    template <class T>
    int operator>= (const Point3<T> &v1, const Point3<T> &v2)
    { return (v1.getSquare() >= v2.getSquare()); }
     
    template <class T>
    int operator>= (const Point3<T> &v, const T &l)
    { return (v.getSquare() >= l*l); }
     
    template <class T>
    int operator>= (const T &l, const Point3<T> &v)
    { return (v <= l); }
     
     
    /* Opérateurs arithmétiques */
     
    template <class T>
    Point3<T> operator+ (const Point3<T> &v1, const Point3<T> &v2)
    {
       Point3<T> result;
     
       result.x = v1.x + v2.x;
       result.y = v1.y + v2.y;
       result.z = v1.z + v2.z;
     
       return result;
    }
     
    template <class T>
    Point3<T> operator- (const Point3<T> &v1, const Point3<T> &v2)
    {
       Point3<T> result;
     
       result.x = v1.x - v2.x;
       result.y = v1.y - v2.y;
       result.z = v1.z - v2.z;
     
       return result;
    }
     
    template <class T>
    Point3<T> operator- (const Point3<T> &v)
    {
    	Point3<T> result;
     
    	result.x = -v.x;
    	result.y = -v.y;
    	result.z = -v.z;
     
    	return result;
    }
     
    template <class T>
    Point3<T> operator* (const Point3<T> &v, const T& fac)
    {
       Point3<T> result;
     
       result.x = v.x*fac;
       result.y = v.y*fac;
       result.z = v.z*fac;
     
       return result;
    }
     
    template <class T>
    Point3<T> operator* (const T& fac, const Point3<T> &v)
    { return v*fac; }
     
    template <class T>
    Point3<T> operator/ (const Point3<T> &v, const T& divider)
    {
    	if (!divider)
    		throw DivisionByZeroException();
     
    	Point3<T> result;
     
    	result.x = v.x/divider;
    	result.y = v.y/divider;
    	result.z = v.z/divider;
     
    	return result;
    }
     
    template <class T>
    Point3<T>& Point3<T>::operator+= (const Point3<T> &v)
    {
    	x += v.x;
    	y += v.y;
    	z += v.z;
     
    	return *this;
    }
     
    template <class T>
    Point3<T>& Point3<T>::operator-= (const Point3<T> &v)
    {
    	x -= v.x;
    	y -= v.y;
    	z -= v.z;
     
    	return *this;
    }
     
    template <class T>
    Point3<T>& Point3<T>::operator*= (const T &fac)
    {
    	x *= fac;
    	y *= fac;
    	z *= fac;
     
    	return *this;
    }
     
    template <class T>
    Point3<T>& Point3<T>::operator/= (const T &divider)
    {
    	if (!divider)
    		throw DivisionByZeroException();
     
    	x /= divider;
    	y /= divider;
    	z /= divider;
     
    	return *this;
    }
     
     
    /* Fonctions membres */
     
    template <class T>
    float Point3<T>::dot(const Point3<T> &v) const
    { return x*v.x + y*v.y + z*v.z; }
     
    template <class T>
    Point3<T> Point3<T>::cross(const Point3<T> &v) const
    {
       Point3<T> result;
     
       result.x = y*v.z - z*v.y;
       result.y = z*v.x - x*v.z;
       result.z = x*v.y - y*v.x;
     
       return result;
    }
     
    template <class T>
    float Point3<T>::projection(const Point3<T> &v) const
    {
    	T length = v.getLength();
     
    	if (!length)
    		throw NullVectorException();
     
    	return dot(v)/length;
    }
     
     
    template <class T>
    T Point3<T>::getCoordinate(int index) const
    { return (&x)[index]; }
     
    template <class T>
    T Point3<T>::getLength() const
    { return (T)sqrt((double)getSquare()); }
     
    template <class T>
    T Point3<T>::getSquare() const
    { return (x*x + y*y + z*z); }
     
    template <class T>
    T Point3<T>::cosinus(const Point3<T>& p) const
    {
    	T length = getLength();
    	T pLength = p.getLength();
     
    	if (!length || !pLength)
    		throw NullVectorException();
     
    	return (x*p.x + y*p.y + z*p.z) / (getLength()*p.getLength());
    }
     
    template <class T>
    bool Point3<T>::isColinear(const Point3<T> &v) const
    {
    	// Le vecteur nul est colinéaire à tout vecteur
    	if (!*this || !v)
    		return true;
     
    	float dotPrd = dot(v);
    	return ((dotPrd*dotPrd)/(getSquare()*v.getSquare()) == (T)1);
    }
     
    template <class T>
    Point3<T> Point3<T>::getNormal() const
    {
    	Point3<T> result = *this;
    	result.normalize();
    	return result;
    };
     
     
    template <class T>
    void Point3<T>::setCoordinates(T xx, T yy, T zz)
    {
    	x = xx;
    	y = yy;
    	z = zz;
    }
     
    template <class T>
    void Point3<T>::setCoordinate(int index, T value)
    { (&x)[index] = value; }
     
    template <class T>
    void Point3<T>::rotate(T angle, const Point3<T>& axis)
    { rotate(Quaternion(axis, angle)); }
     
    template <class T>
    void Point3<T>::rotate(const Quaternion& q)
    {
    	Quaternion result = q*Quaternion(x,y,z,(T)0)*q.getConjugate();
    	*this = result.vPart();
    }
     
     
    template <class T>
    void Point3<T>::normalize()
    {
    	T magnitude = getLength();
     
    	if (!magnitude)
    		throw NullVectorException();
     
    	x /= magnitude;
    	y /= magnitude;
    	z /= magnitude;
    }
     
     
    #include "Quaternion.h"
     
     
    #endif

    Pour les classes d'exception... ben c des classes vide, donc soit tu les crée toi-même soit tu remplace les throw par des exit() comme un bourrin

    Je ne garantit rien concernant la fiabilité de tout ça, mais franchement, après les multiples correction que ça a subit, ça doit commencer à s'approcher d'un truc correct. Ya que la fonction d'interpolation (slerp) entre 2 quaternions que je n'ai que très peu testée...

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

Discussions similaires

  1. Tableau d'objets (POO)
    Par poypoy31240 dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 21/04/2010, 11h46
  2. [VxiR2] Lier deux requetes sur objet information ?
    Par tatayoyo dans le forum Deski
    Réponses: 9
    Dernier message: 19/08/2009, 18h05
  3. Réponses: 4
    Dernier message: 08/01/2009, 12h56
  4. [JCombobox] Lier à une liste d'objets
    Par PhildarZ dans le forum Composants
    Réponses: 6
    Dernier message: 06/07/2008, 20h24
  5. Programation Orientée Objet POO
    Par helmis dans le forum Débuter
    Réponses: 11
    Dernier message: 02/05/2008, 18h53

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