begin process at 2012 02 07 08:31:07
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

OpenGL

 > CLASS VECTEUR 3D

CLASS VECTEUR 3D


 Information sur la source

 Description

Voila la definition d'une classe de vecteur 3D, c'est assez utile pour les programmes OpenGL par exemple.
La classe ne contient pas toutes les opérations mais les plus importantes :
==, =, +, -, *, /, ., ^, norm, normalize.  

Source

  • /**************************************************************************************
  • *
  • * Name : Vector3D.h
  • *
  • **************************************************************************************/
  • #include <windows.h>
  • #include <stdio.h>
  • #include <stdlib.h>
  • #include <math.h>
  • class Vector3D
  • {
  • public:
  • /*---------------------------------- Constructor --------------------------------*/
  • Vector3D () {}
  • Vector3D (float X, float Y, float Z)
  • {
  • x = X; y = Y; z = Z;
  • }
  • /*---------------------------------- Operators ----------------------------------*/
  • // Return himself
  • operator Vector3D () const
  • {
  • return Vector3D(x, y, z);
  • }
  • // Add vector
  • Vector3D operator + (Vector3D Vector)
  • {
  • return Vector3D (Vector.x + x, Vector.y + y, Vector.z + z);
  • }
  • // Subtract vectors
  • Vector3D operator - (Vector3D Vector)
  • {
  • return Vector3D (x - Vector.x, y - Vector.y, z - Vector.z);
  • }
  • // "produit vectoriel"
  • Vector3D operator ^(Vector3D Vector)
  • {
  • Vector3D vNormal;
  • vNormal.x = ((y * Vector.z) - (z * Vector.y));
  • vNormal.y = ((z * Vector.x) - (x * Vector.z));
  • vNormal.z = ((x * Vector.y) - (y * Vector.x));
  • return vNormal;
  • }
  • // Divide by a scalar
  • Vector3D operator * (float num)
  • {
  • // Return the scaled vector
  • return Vector3D(x * num, y * num, z * num);
  • }
  • // "produit scalaire"
  • float operator * (Vector3D Vector)
  • {
  • return (x * Vector.x + y * Vector.y + z * Vector.z);
  • }
  • // Divide by a scalar
  • Vector3D operator / (float num)
  • {
  • // Return the scale vector
  • return Vector3D(x / num, y / num, z / num);
  • }
  • // = operator
  • void operator = (Vector3D Vector)
  • {
  • x = Vector.x;
  • y = Vector.y;
  • z = Vector.z;
  • }
  • // == operator
  • bool operator == (Vector3D Vector)
  • {
  • return (x == Vector.x && y == Vector.y && z == Vector.z);
  • }
  • // != operator
  • bool operator != (Vector3D Vector)
  • {
  • return (x != Vector.x || y != Vector.y || z != Vector.z);
  • }
  • /*---------------------------------- Functions ----------------------------------*/
  • // Work out the norm of our vector
  • float Norm()
  • {
  • // Norme = sqrt(x^2 + y^2 + z^2)
  • return (float)sqrt( Vector3D(x,y,z) * Vector3D(x,y,z) );
  • }
  • // Work out the vector normalized : Vector.norm() == 1
  • Vector3D Normalize()
  • {
  • return (Vector3D(x,y,z) / Norm());
  • }
  • float x, y, z;
  • };
/**************************************************************************************
*
*  Name : Vector3D.h
*
**************************************************************************************/

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

class Vector3D
{
public:
	
	/*---------------------------------- Constructor --------------------------------*/
	Vector3D () {}

	Vector3D (float X, float Y, float Z) 
	{ 
		x = X; y = Y; z = Z;
	}

	/*---------------------------------- Operators ----------------------------------*/
	// Return himself
	operator Vector3D () const
	{
		return Vector3D(x, y, z);
	}

	// Add vector
	Vector3D operator + (Vector3D Vector)
	{
		return Vector3D (Vector.x + x, Vector.y + y, Vector.z + z);
	}

	// Subtract vectors 
	Vector3D operator - (Vector3D Vector)
	{
		return Vector3D (x - Vector.x, y - Vector.y, z - Vector.z);
	}

	// "produit vectoriel"
	Vector3D operator ^(Vector3D Vector)
	{
		Vector3D vNormal;	

		vNormal.x = ((y * Vector.z) - (z * Vector.y));
		vNormal.y = ((z * Vector.x) - (x * Vector.z));
		vNormal.z = ((x * Vector.y) - (y * Vector.x));

		return vNormal;										 
	}
	
	// Divide by a scalar
	Vector3D operator * (float num)
	{
		// Return the scaled vector
		return Vector3D(x * num, y * num, z * num);
	}

	// "produit scalaire"
	float operator * (Vector3D Vector)
	{
		return (x * Vector.x +  y * Vector.y + z * Vector.z);
	}

	// Divide by a scalar
	Vector3D operator / (float num)
	{
		// Return the scale vector
		return Vector3D(x / num, y / num, z / num);
	}

	// = operator
	void operator = (Vector3D Vector)
	{
		x = Vector.x;
		y = Vector.y;
		z = Vector.z;
	}

	// == operator
	bool operator == (Vector3D Vector)
	{
		return (x == Vector.x && y == Vector.y && z == Vector.z);
	}

	// != operator
	bool operator != (Vector3D Vector)
	{
		return (x != Vector.x || y != Vector.y || z != Vector.z);
	}
	
	/*---------------------------------- Functions ----------------------------------*/
	// Work out the norm of our vector
	float Norm()
	{
		// Norme = sqrt(x^2 + y^2 + z^2)
		return (float)sqrt( Vector3D(x,y,z) * Vector3D(x,y,z) );
	}
	// Work out the vector normalized : Vector.norm() == 1
	Vector3D Normalize()
	{  
		return (Vector3D(x,y,z) / Norm());
	}

	float x, y, z;						
};

 Conclusion

exemple :

Vector3D Vector1(0.0,4.0,0.0);
Vector3D Vector2(9.0,6.0,0.0);
Vector3D Vector3(0.0,0.0,0.0);
float result;
char buffer[255];

Vector3 = Vector1 ^ Vector2;
result  = Vector1 * Vector2;

sprintf(buffer, "(0.0,4.0,0.0)) ^ (9.0,6.0,0.0) = (%f,%f,%f)", Vector3.x, Vector3.y, Vector3.z);
MessageBox(NULL,buffer,"RESULT",MB_OK );

sprintf(buffer, "(0.0,4.0,0.0) * (9.0,6.0,0.0) = %f", result);
MessageBox(NULL,buffer,"RESULT",MB_OK);

sprintf(buffer, "Norm of Vector3 = %f", Vector3.Norm());
MessageBox(NULL,buffer,"RESULT", MB_OK);


 Sources de la même categorie

Source avec Zip Source avec une capture AFFICHER DES COURBES DE BEZIER par shorzy
Source avec Zip Source avec une capture BASE/MOTEUR 3D EN QT/OPENGL (COMPLET ET FONCTIONNEL!) POUR U... par envi33
Source avec Zip Source avec une capture CLASSE AVEC OPENGL - OBJETS 3D ET ANIMATIONS par rasta63
Source avec Zip Source avec une capture LETTRES 3D AVEC OPENGL ET QT par opossum_farceur
Source avec Zip CUBE 3D GLUT32 VC++ ET DEVC++ par bobby03

Commentaires et avis

Commentaire de barraq le 02/03/2005 21:58:15

Comment on dis :

produit scalaire et produit vectoriel en anglais :D

( et on se fou pas de ma gueule :D )

Commentaire de brosse_adan le 02/03/2005 22:51:36

on dit Dot Product pour produit scalaire, et Cross Product pour le vectoriel!

:)

Commentaire de barraq le 03/03/2005 10:28:48

Merci :)

et aussi un petit truc, dans la redéfinition de l'operateur = par exemple, j'ai utilisé Vector3D(x,y,z) a la place the "this" car en fait quand j'utilise "this" sa marche pas :s
si quelqu'un sai pourquoi ....

Commentaire de shenron666 le 03/03/2005 13:54:26

pour ce qui est de l'opérateur = je ne comprend pas trop mais prend plutot exemple sur celui-ci :

Vector3D& operator=(const Vector3D& Vector)
{
        x = Vector.x;
        y = Vector.y;
        z = Vector.z;
        return *this;
}

de même un contructeur de copie qui est très utile pour ce genre de classe :

Vector3D(const Vector3D& Vector)
{
       *this = Vector;
}

tout simplement, l'opérateur = fera le reste

tu peux regarder mes sources
http://www.cppfrance.com/code.aspx?ID=29029
tu y trouvera peut-etre un peu d'inspiration ;-)

bon début en tout cas

Commentaire de steve_clamage le 03/03/2005 14:46:16

Dans ce cas la ce n'est pas nécessaire de redefinir le constructeur de copie et operator=, il faut laisser le compilateur s'en charger.

Pour l'affectation, il ne faut pas oublier le test if( this == &Vector )

Commentaire de Kirua le 03/03/2005 16:50:48

steve, je comprends pas, j'ai le droit d'assigner un objet à lui-même, pq tu veux faire un test?

Vector3D a(...);

a = a;  //c'est légal; idiot mais légal

Ce serait intéressant de "templatiser" tout ça pour qu'on puisse choisir de travailler avec des int / float / double / classe perso / ...

Commentaire de steve_clamage le 03/03/2005 17:03:03

Si il est necessaire de définir soi meme l'operateur d'assignation, alors il est certain que l'auto-assignation peut avoir des effet inattendu si elle n'est pas controlée.

Par exemple:

classe string
{
char *p;

public:

string & operator = (const string & s )
{
delete []p; // si auto asignation on libere le buffer avant
                 // de copier sont contenu
// new[] + copie
}

};
}

Commentaire de Kirua le 03/03/2005 17:24:36

D'accord, d'accord, c'est en effet un cas à traîter quand tu as de la mémoire dynamiquement allouée, mais là pour 3 variables statiques... en même temps, t'as qd même raison sur le fond: c'est même pas la peine de les déclarer.

Commentaire de steve_clamage le 03/03/2005 17:34:41

Oui, on voit que techniquement si on des raisons de définir l'affectation alors pour les memes raisons il faudra détourner l'auto affectation, je pense que c'est ca.

Commentaire de barraq le 03/03/2005 18:36:47

Super merci bien pour tous ces commentaires !
je corrige sa sur mon code alors.
et je regarde http://www.cppfrance.com/code.aspx?ID=29029
cool ;)

Commentaire de luhtor le 04/03/2005 20:55:03

Un conseil, au lieu de ca:
float operator * (Vector3D Vector)
    {
        return (x * Vector.x +  y * Vector.y + z * Vector.z);
    }

met ca:
float operator * (const Vector3D & Vector)
    {
        return (x * Vector.x +  y * Vector.y + z * Vector.z);
    }

C'est beaucoup plus rapide, car tous ceux qui programment sur openGL ont besoin de performance.

De plus, j'ai fais ma propre classe vecteur 3D, en template, ce qui me permet de modifier le type de données de mes vecteurs, genre int, float, double, etc ..., ou autre. Ca peut présenter un intérêt.

De plus, si je vais vecteur / 0 ? il se passe quoi ? il faut donc gérer tous les cas possible pour rendre une classe de vecteur utilisable par tout le monde. Et dernière chose, je pense qu'il vaut mieux séparer en .h et .cpp ou .inl si tu déclares les fonctions en inline.

Dernières chose, si V est un vecteur,
X = 4*V, ta classe le gère ? ou alors il faut mettre X = V*4

Aller ++ :)

Commentaire de Kirua le 04/03/2005 22:57:20

À propos du cas de la division par 0 ... je pense que ds énormément de cas le programmeur prend déjà par ailleurs la précaution ailleurs dans son code, et que donc faire ce test est redondant. De plus, dans ta classe tu ne sais pas, a priori, comment gérer l'erreur: déclencher une exception, retourner un vecteur 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF ? (et si tu templatise c'est pas possible), retourner le vecteur nul, allumer un flag erreur static de la classe ... c'est pas pratique. En plus, une division par zéro c'est pas dur à détecter (suffit de mettre ça dans le code:)

#ifdef DEBUG
if(nul == 0)
cout << "Division de vecteur par 0!" << endl;
#endif

L'effet, ce sera d'avertir le programmeur pdt le débuggage, et puis ben pr le reste il n'aura qu'à faire le test lui même, ça me paraît plus logique.

Commentaire de Kirua le 04/03/2005 22:57:55

c'était num == 0, pas nul == 0, désolé.

Commentaire de luhtor le 05/03/2005 11:19:36

En effet, moi c'était envoyé au gestionnaire d'exception, mais dans ce cas, tu as raison, on ne peut rien définir.

Commentaire de brubru777 le 07/11/2005 02:18:58

Bonjour,

Pour un programme que j'ai fait récemment, j'ai eu besoin d'une classe vecteur. Mon code marchait plutôt bien à un petit détail près. J'ai eu un petit problème avec la surcharge des opérateurs +, -, etc. et << que j'ai redéfini pour afficher les vecteurs en texte sous la forme "(x, y, z)".

Dans un premier temps, j'ai défini les opérateurs arithmétiques de la manière suivante :

vecteur operator+(const vecteur &v) {
vecteur tmp;
tmp.x = x + v.x;
tmp.y = y + v.y;
tmp.z = z + v.z;
return tmp;
}

Cela marchait très bien pour les calculs mais pas pour l'affichage. C'est-à-dire que pour afficher la somme de deux vecteurs, je devais faire :

v = v1 + v2;
cout<<v;

Dans le cas où je mettais juste "cout<<(v1 + v2);", j'avais un message d'erreur.

Pour résoudre ce problème, j'ai redéfini les opérateurs comme cela :

vecteur &operator+(const vecteur &v) {
vecteur &tmp;
tmp->x = x + v.x;
tmp->y = y + v.y;
tmp->z = z + v.z;
return *tmp;
}

Cette solution semble fonctionner aussi bien pour le calcul que pour l' affichage. Cependant, je me demande si elle est bien correcte. Car si j'ai bien compris, on transmet juste l'adresse de la variable tmp et celle-ci est détruite juste après l'opération. Si c'est le cas, ça marcherait donc juste par hasard parce qu'aucun autre processus ne serait venu altérer la mémoire à cet endroit-là.

Est-ce que quelqu'un pourrait m'expliquer ce qui ne marche pas avec la première méthode et pourquoi la deuxième méthode qui me semble incorrecte marche?

D'avance merci.

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,624 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales