diff --git a/README b/DIRECTIVES similarity index 88% rename from README rename to DIRECTIVES index 823981a..fcc8c99 100644 --- a/README +++ b/DIRECTIVES @@ -1,186 +1,166 @@ Programming project Semester II, Physics session Introduction: The purpose of this project is to learn how to symulate a physical system and, eventually, implement it using a 3D graphical engine. The programming language used is the C++. A graphical representation is written using the OpenGL engine powered by a Qt window manager. Members: Raffaele Ancarola, Armando Cincotti Goals: I) Numerical symulation of a simple system (ex. a pendule) II) Describing a more complex system (ex. damped harmonic oscillator) III) The symulation of a particle system (always numerically) IV) Graphics setup (Qt and OpenGL) V) The transposition of older symulations into a graphical representation -Structure and organization: - - symkit: - - The core of the project. - A library which contains all the components needed in order - to build any symulation in the simplest way. - Here all low level calls, OpenGL functions and basic mechanics - are implemented and all functionalities - are accessible as an object oriented engine. - - test: - - The part of the project where symkit is used in order to - numerically symulate a physical system. - - qtproject: - - A Qt project where .... - Coding rules: - The content of a .h file must be bound by a #ifndef MACRO block in order to prevent compilation conflicts, for example: #ifndef __MYFILE_H__ #define __MYFILE_H__ /* My content */ class MyClass { /* Class content */ }; #endif // __MYFILE_H__ - Class names must begin with a capitalized letter, for example: class MyClass { /* Class content */ }; - Namespace, structure, variable and function names must NOT begin with a capitalized letter, for example: void eraseAll(); int foo = 0; double _time; struct boundingBox { /* Struct content */ }; - Warning! Few and well structured classes is better than a lot and small ones. Which means that inheritance is powerful and, for this reason, it is easy to abuse too. - Reminder of Chappelier: Never, NEVER copy-paste implementation code Use functions, classes, inheritance, pointers instead - Keep strict order in your code Remember that your partner have to be able to fully understant your code, so there are some tips: - TAB INDENT SET TO 4 SPACE CHARACTERS Your partner could use a different editor than yours, so taking fixed the Tab indent size to "4 space characters" is good in order to read the same text in the same vision - EXPLAIN WHAT YOU ARE DOING C++ allows you to comment your code. In some complex situations understanding a plain code could be much complicated for other people. Another reason to comment your code is that it speeds up debugging. Sometimes making an important change to the code could cause confusion onto other parts of the code, so commenting your code is useful to find faster an error and fix it better. For example: /* Set the delta time */ void set_dt(const float&); extern int error; // global error code - MAKE NAMES NOT TOO LONG Avoid very long names. Even if more comprehensible, use shorter names and eventually comment to explain them. - INDENTATION IS IMPORTANT Indentation style if free, but it must be fixed, ordered and logical. Some examples to write the same thing: - KEYWORDS USAGE float hello(const int& entry); float hello (int const& entry); - LOOPS for (int i = 0; i < 100; ++i) { /* Content */ } for (int i = 0; i < 100; ++i) { /* Content */ } int i; for (i = 0; i <= 99; ++i) { /* Content */ } - CONDITIONALS (4 spaces indent template) if (s == "hello") { s = "_hello_"; } else if (s == "_hello") s += "_"; } else { s = "_none_"; } - NESTING (4 spaces indent template) if (enable) { for (auto obj : objects) { if (obj == 0) continue; else return obj; } } diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..1a14184 --- /dev/null +++ b/README.txt @@ -0,0 +1,58 @@ +READ ME PLEASE + + +POUR L'UTILISATEUR + + + + + +POUR CELUI QUI EVALUE + +DOCUMENTS TEXTE + + Les document texte demand�s, JOURNAL, REPONSES et CONCEPTION se trouvent dans le dossier "doc". + JOURNAL et REPONSES ont �t�s �crit avec Notepad++, donc si ouverts avec d'autres programmes de lecture texte + la mise en page pourrait apparaitre pas tout affait correcte. + CONCEPTION est un pdf �crit en Latex, cela ne devrait pas causer de probl�mes. + +CODE INT�GR� + + Le code est divis� en 6 subdirs r�li�s dans le m�me projet par le qmakefile "symkit.pro". + Pour chaque subdirs on a un .pro pour le qmake. + + Biblioth�ques base: + + -SYMATH: - il contient le code qui g�re la partie math�matique du projet, c'est � dire vecteurs, + integrateurs et descriptors (code pour la description differentielle du mouvement d'objets physiques) + - il contient aussi une structure utile pour la gestion d'erreur. + + -SYMGRAPH: il contient le code qui s'occupe de la cr�ation et de la g�stion d'un monde graphique 3D, plus g�n�ralment, de la gestion de f�netres OpenGL. + + -SYMPLOT: il contient le code qui g�re le dessin de graphes, notamment le dessin des espaces des phases + + -SYMVIEWER: - il contient le code qui g�re l'interface utilisateur, + pour le contr�le interactif de la scene et des valeur affich�s � l'�cran + - il permet aussi l'implementation d'une version alternative d'affichage en mode texte. + + Biblioth�ques executables: + + -ALPHA: - il contient la pr�mi�re implementation faite du programme executable: + ouverture d'une f�netre OpenGL pour simulation des premiers oscillateurs implement�s, + dont une implementation abandonn�e et am�lior�e conceptuellement dans le projet finale. + - il est fourni en guise de temoignage de l'�volution du code, et comme grand "file" test + comme ceux demand�s pour le rendu finale. + - le code a �t� n�anmoins modifi� un minimum vers la fin du sem�stre, + pour qu'il compile, dans le but de rendre aussi un t�moignage visuel de la viellie implementation. + + -BETA: - il s'appelle BETA mais il representel'implementation d�finitive pour le rendu. + - il contient code executable qui cr�e des simulations graphique et ouvre les f�netres du monde 3D, + de l'espace des phase, et de l'interface utilisateur. + - c'est aussi le code qui fait le lien concret entre les 4 biblioth�ques base constituant le programme. + + +FICHIERS DE TEST + + Les fichiers de test demand�s se trouvent dans le dossier "templates". + Les test li�s � l'implementation graphique ne sont pas pr�sent dans templates + car on consid�re le code prensent dans ALPHA comme un grand "test" sur le monde graphique qu'on a cr��. diff --git a/beta/betascene.cpp b/beta/betascene.cpp index 24f0987..2cef243 100644 --- a/beta/betascene.cpp +++ b/beta/betascene.cpp @@ -1,280 +1,281 @@ #define _USE_SVECTOR_OSTREAM #include "betascene.h" #include <iostream> #include "newtonsphere/newtonsphere.h" #include "pendules/pendule.h" #include "marbled.h" #include "ressort/ressor.h" #include "pendcouple/pendcouple.h" #include "pendressort/penduleressort.h" #include <QKeyEvent> #include "skerror.h" #include "models/glsphere.h" #include "models/glmarbled.h" #include "skplot2d.h" using namespace std; using namespace symkit; using namespace models; #include "camera.h" #define DARK_BLUE 0.0f, 0.05f, 0.15f #define BLUE_SKY 0.48f, 0.8f, 0.97f #ifndef M_PI #define M_PI 3.141592654 #endif BetaScene::BetaScene(SKPlot2D * plot, QWidget *parent) : Scene(parent), KeyListener(), plot(plot) { sphereModel = new GLSphere(); marbledModel = new GLMarbled(); sphere = new NewtonSphere(sphereModel); pendule = new Pendule(sphereModel, {7, 0, 0}); ressor = new Ressor(sphereModel, {-3, 0, 5}); penduleCouple = new PenduleCouple(sphereModel, {0, 1, 0}); penduleCouple2 = new PenduleCouple(sphereModel, {M_PI, M_PI / 2}, {0, 0}, 10, 5, 2, 2); penduleRessort = new PenduleR(sphereModel, {-10, 7, 8}); marbled = new Marbled(marbledModel); /* Set the color of the sky */ setClearColor(DARK_BLUE); try { /* Load shapes */ addActor(sphere); addActor(pendule); addActor(marbled); addActor(ressor); addActor(penduleCouple2); addActor(penduleCouple); addActor(penduleRessort); } catch (const SKError& err) { cerr << err << endl; } /* Set a camera offset */ getCamera()->move(10, Z); // register key events addKeyListener(this); /* Plotting registering */ //plot = new SKPlot2D(); if (plot == 0) return; /* * Register two streams for the * coupled pendule */ plot->registerNewStream(); plot->registerNewStream(); plot->setBackgroundColor(color_s(0.9, 0.9, 0.9)); plot->setAxysX(SKAxys(20, -10, color_s(0, 0, 1))); plot->setAxysY(SKAxys(10, -5, color_s(0, 1, 0))); //plot->show(); } BetaScene::~BetaScene() { delete sphere; delete marbled; delete pendule; delete ressor; delete penduleCouple2; delete penduleCouple; delete penduleRessort; delete sphereModel; delete marbledModel; //delete plot; } #include "assets.h" void BetaScene::initialize() { sphereModel->initialize(); marbledModel->initialize(); } #include "pendcouple/penduledesc.h" void BetaScene::tickPlugin(float) { if (plot == 0) return; const PenduleDesc * desc = penduleCouple->getPenduleDescriptor(); for (int i = 0; i < 2; ++i) (*plot)[i] << Point2D(desc->getAngle(i), desc->getAngularSpeed(i)); /*cout << "Beta: valid context: " << context()->isValid() << endl; cout << "Beta: sharing context: " << context()->isSharing() << endl; cout << "Beta plot: valid context: " << plot->context()->isValid() << endl; cout << "Beta plot: sharing context: " << plot->context()->isSharing() << endl; */ plot->update(); } void BetaScene::closeEvent(QCloseEvent*) { /* Remove all shapes */ this->removeAllActors(); cout << "Closing OpenGL window" << endl; } #define T_UNIT 0.25 #define R_UNIT 2.5 void BetaScene::onKeyPress(int key) { switch(key) { case Qt::Key_W: getCamera()->move(-T_UNIT, Z); break; case Qt::Key_S: getCamera()->move(T_UNIT, Z); break; case Qt::Key_A: getCamera()->move(-T_UNIT, X); break; case Qt::Key_D: getCamera()->move(T_UNIT, X); break; case Qt::Key_K: getCamera()->move(T_UNIT, Y); break; case Qt::Key_J: getCamera()->move(-T_UNIT, Y); break; case Qt::Key_Up: getCamera()->rotate(-R_UNIT, X); break; case Qt::Key_Down: getCamera()->rotate(R_UNIT, X); break; case Qt::Key_Right: getCamera()->rotate(-R_UNIT, Y); break; case Qt::Key_Left: getCamera()->rotate(R_UNIT, Y); break; case Qt::Key_Space: // give the sphere an impulse sphere->applyRepulsion( getCamera() ); break; case Qt::Key_P: - // stop the sphere + // stop the particles + sphere->toggleEvolving(); sphere->toggleRunningDescriptor(); pendule->toggleEvolving(); pendule->toggleRunningDescriptor(); ressor->toggleEvolving(); ressor->toggleRunningDescriptor(); penduleCouple2->toggleEvolving(); penduleCouple2->toggleRunningDescriptor(); penduleCouple->toggleEvolving(); penduleCouple->toggleRunningDescriptor(); penduleRessort->toggleEvolving(); penduleRessort->toggleRunningDescriptor(); break; case Qt::Key_V: // set the sphere to verbose mode sphere->setVerbose( !sphere->getVerbose() ); break; //Pour le debugging (contrôler si le comportement est sensé) case Qt::Key_E: cout << "Pendule coupled first system energy: " << penduleCouple->energy() << endl; break; case Qt::Key_F: cout << "Pendule coupled second system energy: " << penduleCouple2->energy() << endl; - //semble ne pas être constant, on a peut être pas pris la bonne equation + //semble ne pas être constant, on n'a pas pris la bonne equation très probablement break; case Qt::Key_1: cout << "Pendule Simple" << endl; cout << *pendule << endl; break; case Qt::Key_2: cout << "Ressort" << endl; cout << *ressor << endl; break; case Qt::Key_3: cout << "Pendule Charriot" << endl; cout << *penduleRessort << endl; break; case Qt::Key_4: cout << "Pendule Couple" << endl; cout << *penduleCouple << endl; break; case Qt::Key_5: cout << "Pendule Couple 2" << endl; cout << *penduleCouple2 << endl; break; case Qt::Key_Escape: exit(0); break; default: break; } } void BetaScene::onKeyRelease(int) { } diff --git a/beta/pendcouple/penduledesc.cpp b/beta/pendcouple/penduledesc.cpp index f312ec0..0ebc355 100644 --- a/beta/pendcouple/penduledesc.cpp +++ b/beta/pendcouple/penduledesc.cpp @@ -1,104 +1,108 @@ #include "penduledesc.h" PenduleDesc::PenduleDesc(double l1, double l2, double m1, double m2, const Vector &p, const Vector &pp, double g) : Oscillateur(p, pp), g(g) { l[0] = l1; l[1] = l2; m[0] = m1; m[1] = m2; adjust(2); } PenduleDesc::PenduleDesc(double l1, double l2, double m1, double m2, const std::vector<double> &p, const std::vector<double> &pp, double g) : Oscillateur(p, pp), g(g) { l[0] = l1; l[1] = l2; m[0] = m1; m[1] = m2; adjust(2); } #define CHECK_BOUND_INDEX(index) index < 2 && index >= 0 void PenduleDesc::setLength(double l, int index) { if (CHECK_BOUND_INDEX(index)) this->l[index] = l; } void PenduleDesc::setMass(double m, int index) { if (CHECK_BOUND_INDEX(index)) this->m[index] = m; } +#include "skerror.h" + +using namespace symkit; + double PenduleDesc::getLength(int index) const { if (CHECK_BOUND_INDEX(index)) return l[index]; else - return 0; // TODO, throw error + throw SKError(ERR_BOUND, "getLength", "PenduleDesc", "Looking for a non-existing value", false); } double PenduleDesc::getMass(int index) const { if (CHECK_BOUND_INDEX(index)) return m[index]; else - return 0; // TODO, throw error + throw SKError(ERR_BOUND, "getMass", "PenduleDesc", "Looking for a non-existing value", false); } double PenduleDesc::getAngle(int index) const { if (CHECK_BOUND_INDEX(index)) return getp()[index]; else - return 0; // TODO, throw error + throw SKError(ERR_BOUND, "getAngle", "PenduleDesc", "Looking for a non-existing value", false); } double PenduleDesc::getAngularSpeed(int index) const { if (CHECK_BOUND_INDEX(index)) return getp_prime()[index]; else - return 0; // TODO, throw error + throw SKError(ERR_BOUND, "getAngularSpeed", "PenduleDesc", "Looking for a non-existing value", false); } #include <cmath> Vector PenduleDesc::equation() const { Vector out = {0, 0}; double dteta = p[0] - p[1]; double M = m[0] + m[1]; double sin_dteta = sin(dteta); double cos_dteta = cos(dteta); double denom = m[0] + m[1] * sin_dteta * sin_dteta; // first angle out[0] = m[1] * g * cos_dteta * sin(p[1]) - M * g * sin(p[0]) - m[1] * l[0] * p_prime[0] * p_prime[0] * sin_dteta * cos_dteta - m[1] * l[1] * p_prime[1] * p_prime[1] * sin_dteta; out[0] /= denom * l[0]; // second angle out[1] = M * g * cos_dteta * sin(p[0]) - M * g * sin(p[1]) + m[1] * l[1] * p_prime[1] * p_prime[1] * sin_dteta * cos_dteta + M * l[0] * p_prime[0] * p_prime[0] * sin_dteta; out[1] /= denom * l[1]; return out; } diff --git a/beta/pendressort/penduleressortdesc.cpp b/beta/pendressort/penduleressortdesc.cpp index 38588d0..cd71f2c 100644 --- a/beta/pendressort/penduleressortdesc.cpp +++ b/beta/pendressort/penduleressortdesc.cpp @@ -1,100 +1,108 @@ #include "penduleressortdesc.h" #include <cmath> PenduleRessort::PenduleRessort(const std::vector<double>& p, const std::vector<double>& p_p, const double& k, const double& l, const double& m1, const double& m2, const double& fr1, const double& fr2, const double& g, integral_operation op) : Oscillateur(p, p_p, op), k(k), l(l), g(g) { m[0] = m1; m[1] = m2; fr[0] = fr1; fr[1] = fr2; adjust(2); } PenduleRessort::PenduleRessort(const Vector& p, const Vector& p_p, const double& k, const double& l, const double& m1, const double& m2, const double& fr1, const double& fr2, const double& g,integral_operation op) : Oscillateur(p, p_p, op), k(k), l(l), g(g) { m[0] = m1; m[1] = m2; fr[0] = fr1; fr[1] = fr2; adjust(2); } double PenduleRessort::getLenght() const { return l; } double PenduleRessort::getk() const { return k; } #define CHECK_BOUND_INDEX(index) index < 2 && index >= 0 +#include "skerror.h" + +using namespace symkit; + double PenduleRessort::getMass(int index) const { if (CHECK_BOUND_INDEX(index)) return m[index]; else - return 0; // TODO, throw error + throw SKError(ERR_BOUND, "getMass", "PenduleRessort", "Looking for a non-existing value", false); } double PenduleRessort::getFrottement(int index) const { if (CHECK_BOUND_INDEX(index)) return fr[index]; else - return 0; // TODO, throw error + throw SKError(ERR_BOUND, "getFrottement", "PenduleRessort", "Looking for a non-existing value", false); } double PenduleRessort::getg() const { return g; } void PenduleRessort::setLenght(const double& l) { this->l=l; } void PenduleRessort::setk(const double& k) { this->k=k; } void PenduleRessort::setMass(const double& m, int index) { if (CHECK_BOUND_INDEX(index)) this->m[index] = m; + else + throw SKError(ERR_BOUND, "setMass", "PenduleRessort", "Looking for a non-existing memory-buffer", false); } void PenduleRessort::setFrottement(const double& fr, int index) { if (CHECK_BOUND_INDEX(index)) this->fr[index] = fr; + else + throw SKError(ERR_BOUND, "setFrottement", "PenduleRessort", "Looking for a non-existing memory-buffer", false); } void PenduleRessort::setg(const double& g) { this->g=g; } Vector PenduleRessort::equation() const { double a(m[0] + m[1]*sin(p[1])*sin(p[1])); double b(k*p[0] + fr[0]*p_prime[0] - m[1]*l*p_prime[1]*p_prime[1]*sin(p[1])); double c(g*sin(p[1]) + fr[1]*p_prime[1]); return { (-b + m[1]*c*cos(p[1]))/a , (b*cos(p[1]) - (m[0]+m[1])*c)/(l*a) }; } diff --git a/doc/JOURNAL.txt b/doc/JOURNAL.txt index 361febf..ddefb2a 100644 --- a/doc/JOURNAL.txt +++ b/doc/JOURNAL.txt @@ -1,221 +1,223 @@ # PROGRESSION Format : [fait/� faire] TACHE Dur�e (en minutes; remplacer les ??) Vous pouvez ajouter vos propres t�ches si vous le jugez utile (p.ex. d�composition plus fine). [V] Cr�er le JOURNAL 2 [V] Lire compl�tement le descriptif g�n�ral 80 [V] S'inscrire en bin�me 2 [V] Fusionner les deux projets (avec git-bash) 120 [V] Makefile 80 [V] Vecteur finie (pleinement op�rationnelle et test�e) 400 [V] Fichier REPONSES 230 [V] Oscillateur 120 [V] Oscillateur: finition en foction du reste 120 [V] Int�grateur d'Euler-Cromer 10 [V] Pendule 120 [V] Ressort 120 [V] Systeme 40 [V] Graphisme: cadre g�n�ral 180 [V] Graphisme: implementation 2200 [V] Graphisme: optimisation 1000 [V] Structure projet (id�ation de toute les classes) 200 [V] Structure (implementation classes secondaires) 200 [V] OscillateurCouple (tests et corrections) 360 [V] PenduleDouble 120 [V] Espace des phases 200 [V] Alpha 90 [V] Beta 90 [V] Interface utilisateur interactive 1200 [V] integrateur Newmark 60 [V] fichier CONCEPTION 1000 [ ] fichier README 30 [V] fichier JOURNAL 500 ====================================================================== # A FAIRE (PROCHAINE ETAPE) Mettez ici ce que vous pensez devoir �tre la ou les 2 prochaines �tapes pour chacun. Par exemple : ATTENTION COMMENTER TOUJOURS SON PROPRE CODE ====================================================================== # SUIVI ## Semaine 1 : Pris connaissance du projet, lu les documents d'information, pris connaissance des utils mat�matiques et num�riques n�cessaire pour l'implementation du projet Cr�ation d'un Makefile dynamique mis � jour en parall�le avec le projet ## Semaine 2 : Set up des r�pertoir: un r�pertoir commun pour le projet et deux autres pour le travail individuel. Creation et administration d'un milieu de travail appropri�. Creation d'un fichier CMake, pour le crossplatforming (fonctionnant sur Linux et Windows) dynamique permettant d'implemnter dynamiquements les diff�rentes composantes du projet. (Il sera complet� vers la fin du projet). Creation d'une classe Vector et test li�es. Debug de la classe Vector. Reponse aux questions de la semaine 2. -------------------------------------------------- ## Semaine 3 : Set up de Qt creator sur les deux machines (laptop personnels). Cr�ation d'un fichier ".pro" pour la compilation du projet. Abandonn�e l'id�e d'un CMake, vu que qmake fonction tr�s bien pour les deux plateforme. Prise connaissance de l'interface de Qt. Suivi tutoriel fourni par le cours sur Qt et OpenGl. Cr�� prototype de classes: -SVector(Vecteurs statiques(ex. positions force et acc�leration)) -Camera -Matpoint -Particle -Partsystem -Scene -Shape Et debut implementation. -------------------------------------------------- ## Semaine 4 : Implementation des classes: -SVector -Matpoint -Particle -Partsystem -Scene -Shape -Camera S�rie li�e au projet: Cr�ation de classe g�nerale "Oscillateur" et test li�s avec creation de classe h�r�ditaire "PenduleS" (Pendule simple). Mise � jour du fichier REPONSES.txt Debug general des implementations graphiques. Test avec premi�re simulation (Integration par M�tode d'Euler) sur une sph�re en opengl. Partition du project en qt subdirs projets: libs: - symath - symgraph apps: - alpha symath: Elle est la bibliot�que du projet qui s'occupe des fonctions numeriques de base sur lequelles on va construire le reste du projet, ou bien graphique et symulations. Contenu: - Vector: classe qui manage les vecteurs � dimension dynamique - SVector: classe qui manage les vecteurs � dimension fixe - Particle: structure qui implemente le kit de base pour une symulation dynamique symgraph: Ici elle est implement�e toute la partie graphique qui s'interface � la OpenGL. Le syst�me est fait d'une telle fa�on qu'on peut charger et enlever des object dessinables dynamiquement. Tests et debugs li�es � chaque nouveau fichiers de code cr��. -------------------------------------------------- ## Semaine 5 : Amelior�e classe Oscillateur. Cr��e sous-classe Ressort (� une dimension) et faits test corr�l�s. Creation simulations graphiques d'un Ressort et d'un PenduleS. Debug de ces classes (en s'aidant des simulations graphiques). Reponse aux questions de la serie de cette semaine. Implementation de methodes d'integration Newmark et Euler-Cromer distincts. -------------------------------------------------- ## Semaine 6 : Am�lioration de tout le styst�me graphique. Compl�tion du projets en g�n�rale avec cr�ation de SuperClasses et sous-classes pour la gestion de tout les aspects de: dessin, colorage, description mat�matique, contr�le d'op�rations etc. Tests et debugs li�es aux implementations faites. -------------------------------------------------- ## Semaine 7 : Cr�e un structure "SKerror" pour faciliter la gestion et l'affichage de messages d'erreurs. Cr�e un syst�me et simulation graphiques de trois objets physiques (oscillateurs). Cr�ation d'un test "alpha" et finition. R�ponse aux question de la semaine 7. Debug de GLBuffer. Creation de "Conception.pdf" en latex, premier index, introduction aux r�pertoirs/classes principaux/le. "Conception.pdf" � completer dans les semaines qui suivent. Premier rapport fait � l'assistants. Armando: Essaye classe "PeduleC", quelque soucis avec l'implementation graphique, je demanderai � Raffaele -------------------------------------------------- ## Semaine 8 : Fini implementation graphique du pendule coupl�. Probl�mes li�s � sa simulation numerique: - Avec integrateur EulerCromer l'erreur se cumule et la valeur de vitesse explose - Avec integrateur newMark l'erreur se cumule et la valeur de vitesse explose, ou la valeur cherch�e n'est jamais assaez precise et l'integrateur entre dans une loop infinie qui bloque la simulation (pour �viter cela on lui a donn� un nombre maximale de loop) Recherche du probl�me, on se fait imprimer l'�nergie pour controller qu'elle reste constante (elle oscille bcp trop). Debug important � faire au niveau numerique. Essayer peut-etre un autre integrateur. Pas un probl�me d'integrateur, pas d'ordre d'update des pendules. Nouvelles id�es pour l'amelioration de nos "Syst�mes" graphiques. Implementation pour la semaine prochaine. Test du fonctionnement des exceptions. -------------------------------------------------- ## Semaine 9 : Nouveau descriptor "Penduleressort". Cr�e simulation num�rique et graphique d'un Pendule coupl� � un ressort Commencement de la partie beta du projet (tr�s probablement celle qui contiendra le main final). Rearrangement du syst�me "Pendulecoupl�" dans un seul descriptor pour les deux particules (On laisse la vieille implementation dans le repertoir "templates", comme trace de tous nos tests) R�solu ainsi le probl�me de divergence du syst�me d'oscillateurs coupl�s. Modifi�e implementation graphique de particules et syst�mes pour faciliter l'affichage d'oscillateurs coupl�s. Debut r�daction integrale de Conception.pdf Premier chapitre achev�. -------------------------------------------------- ## Semaine 10 : Reponses aux questions de la semaine 11. Reflection sur l'implementation d'un espace de phases. Implementation complete du subdir Symplot: subdir d�di� � la cr�ation et dessin d'un espace de phase. Implementation affichage des particules pour en faire une simulation mode texte, tests et debug. -------------------------------------------------- ## Semaine 11 : Fin redaction deuxi�me et troisi�me partie du document CONSEPTION. Implementation d'une interface utilisateur (Subdir Symviewer). Correction conceptuelle des OscillatorParticle et SymSystems � l'interieur du Subdir Beta. -------------------------------------------------- ## Semaine 12 : Compl�tion fichier CONCEPTION. Am�lioration et debug de l'interface utilisateur (GUI). Implimentation plus interactive de cette derni�re. +Contr�le globale du c�de, recherche d'exceptions pas encore g�r�es. +Redaction d'un README. -------------------------------------------------- ## Semaine 13 : diff --git a/symath/skerror.h b/symath/skerror.h index ebb8220..6308eb2 100644 --- a/symath/skerror.h +++ b/symath/skerror.h @@ -1,41 +1,42 @@ #ifndef SKERROR_H #define SKERROR_H #include <string> namespace symkit { enum SKErrorType { - ERR_INIT = -6, + ERR_INIT = -7, ERR_EVOLVE, ERR_RENDER, ERR_NULL_POINTER, ERR_NUMERICAL, + ERR_BOUND, ERR_OTHERS = -1 }; struct SKError { SKError(const SKErrorType&, const std::string &functionName, const std::string &className, const std::string &comment = "", bool fatal = true); SKErrorType type; std::string functionName; std::string className; std::string comment; bool fatal; }; } #include <iosfwd> std::ostream& operator<<(std::ostream&, const symkit::SKError&); #endif // SKERROR_H diff --git a/symath/vector.cpp b/symath/vector.cpp index 9ce2567..3f0441e 100644 --- a/symath/vector.cpp +++ b/symath/vector.cpp @@ -1,373 +1,373 @@ #include "vector.h" #include <cmath> // pour sqrt() #include "svector.h" using namespace std; Vector::Vector() : components(DEFAULT_VECTOR_SIZE) {} // Costructeur sur la base d'une liste de valuers -// + Vector::Vector(const initializer_list<double> &init) : components(init.begin(), init.end()) {} // Constructeur sur la base d'un std::vector -// + Vector::Vector(const vector<double>& init) : components(init) {} Vector::Vector(const Vector& init) { *this = init; } //Destructeur Vector::~Vector(){} //Permet, par un simple operator =, d'affecter un Vector à un autre /*Vector& Vector::operator=(const Vector& v) { // clear current memory this->clear(); // assure allocation size this->components.reserve(v.size()); // copy all components for (auto comp : v) this->components.push_back(comp); return *this; }*/ /* for auto loop */ Vector::iterator Vector::begin() { return components.begin(); } Vector::iterator Vector::end() { return components.end(); } Vector::const_iterator Vector::begin() const { return components.begin(); } Vector::const_iterator Vector::end() const { return components.end(); } Vector Vector::unit() const { return (*this) / this->module(); } /* * cette fonctions était démandée en exercice, mais l'operator "[]" permet de faire la même chose * et en plus elle foction de operateur [] comme pour les "vector" (ex. v[i] cordonnée i de v) * mais pour notre classe "Vector" * void Vector::set_coord(size_t i, double x){ if (i<components->size()) *components[i]=val; //On vérifie si l'entrée i est plausible pour ensuite affecter la valeur à la coordonnée choisie else throw string("Vector: Out of bound error"); //Autrement on lance une erreur d'Out of bound } */ void Vector::augmente(double x) { components.push_back(x); //On rajoute simplement la valeur à un nouveau paramètre, correspondant à une dimension de plus } void Vector::decale() { components.pop_back(); } void Vector::clear(){ components.clear(); } //Permet d'utiliser la fonction size pour une variale Vector, comme si celle si était un vector size_t Vector::size() const { return components.size(); } /*Ici de suite on retrouve deux foctions "identiques" * mais qui opèrent sur des objets constants ou non */ const double& Vector::operator[](size_t i) const { return components[i]; //Retourne la valeur du vecteur à l'indice i(i commence à 0) } double& Vector::operator[](size_t i) { return components[i]; //Retourne la valeur du vecteur à l'indice i(i commence à 0) } /*void Vector::affiche() const{ cout << "("; for(auto a : *components){ cout << a << ", "; } //Par cette boucle on peut afficher un après l'autre tous les coordonnées du Vecteur cout << ")"<< endl; } * * * Celle si à été substituée par un ostream implementé plus loins */ //Operateurs comparaisons bool Vector::operator==(const Vector& v) const { if(components.size() != v.size()) return false; //Retourne déjà faux si les deux vecteurs n'ont pas la même dimension for(size_t i(0); i < v.size(); ++i){ if (components[i] != v[i]) return false; //Lors que le programme rencontre deux coordonnées différenentes respectivement pour la même dimension des deux vecteurs //la fonction retourne false } return true; } bool Vector::operator>=(const Vector& v) const { return sq_module() >= v.sq_module(); } bool Vector::operator<=(const Vector& v) const { return sq_module() <= v.sq_module(); } bool Vector::operator>=(double m) const { return sq_module() >= m * m; } bool Vector::operator<=(double m) const { return sq_module() <= m * m; } bool Vector::operator>(const Vector& v) const { return sq_module() > v.sq_module(); } bool Vector::operator<(const Vector& v) const { return sq_module() < v.sq_module(); } bool Vector::operator>(double m) const { return sq_module() > m * m; } bool Vector::operator<(double m) const { return sq_module() < m * m; } bool Vector::operator!=(const Vector& w) const { return !(*this == w); } //Operateurs somme et produit Vector& Vector::operator+=(const Vector& w) { size_t n = (this->size() <= w.size()) ? this->size() : w.size(); for (size_t i= 0; i < n; ++i) (*this)[i] += w[i]; return *this; } Vector& Vector::operator-=(const Vector& w) { size_t n = (this->size() <= w.size()) ? this->size() : w.size(); for (size_t i = 0; i < n; ++i) (*this)[i] -= w[i]; return *this; } Vector& Vector::operator*=(double k) { for (size_t i = 0; i < this->size(); ++i) (*this)[i] *= k; return *this; } Vector& Vector::operator/=(double k) { for (size_t i = 0; i < this->size(); ++i) (*this)[i] /= k; return *this; } const Vector operator+(Vector v, const Vector& w) { return v += w; } const Vector operator-(Vector v, const Vector& w) { return v -= w; } const Vector operator*(Vector v, double const& k) { return v *= k; } const Vector operator/(Vector v, double const& k) { return v /= k; } #include "skerror.h" using namespace symkit; /* Cross product */ Vector Vector::operator^(const Vector& w) const { Vector u = {0, 0, 0}; if (this->size() != 3 || w.size() != 3) throw SKError(ERR_NUMERICAL, "operator^", "Vector", "Cross product of non-3D vectors", 0); u[0] = (*this)[1] * w[2] - (*this)[2] * w[1]; u[1] = (*this)[2] * w[0] - (*this)[0] * w[2]; u[2] = (*this)[0] * w[1] - (*this)[1] * w[0]; return u; } /* Dot product */ double Vector::operator*(const Vector& w) const { double x = 0; if (this->size() != w.size()) throw SKError(ERR_NUMERICAL, "operator*", "Vector", "Scalar producat of vector with different dimension", 0); for (size_t i = 0; i < this->size(); ++i) x += (*this)[i] * w[i]; return x; } Vector Vector::operator-() const { return (*this) * (-1); } Vector& Vector::operator~() { return (*this)*=-1.0; } double Vector::sq_module() const { double x = 0; for (size_t i = 0; i < this->size(); ++i) x += (*this)[i] * (*this)[i]; return x; } double Vector::module() const { return sqrt(this->sq_module()); } /* Implementation of ostream operator overloading */ /* Le prototype je le mets dans un header séparé parce que * il ne fait pas partie de l'implementation d'un vecteur * Une classe l'utilisant n'as pas besoin de l'imprimer */ //#include "iosymkit.h" // pour implementer ostream<< #include <ostream> void Vector::affiche(std::ostream& os) const { os << "("; for (size_t i(0); i < (components.size() - 1); ++i) { os << components[i] << ", "; } os << components[components.size()-1] << ")"; } // Flux de sortie permettant d'afficher les coordonnées du vecteur ostream& operator<<(ostream& os, const Vector& v) { v.affiche(os); return os; } #include "svector.h" /* * Cross product implementation for SVector */ const SVector<3> operator^(const SVector<3>& v, const SVector<3>& w) { SVector<3> u = {0, 0, 0}; if (v.size() != 3 || w.size() != 3) throw SKError(ERR_NUMERICAL, "operator^", "SVector", "Cross product of non-3D vectors", 0); u[0] = v[1] * w[2] - v[2] * w[1]; u[1] = v[2] * w[0] - v[0] * w[2]; u[2] = v[0] * w[1] - v[1] * w[0]; return u; } diff --git a/symgraph/actors/actorgroup.cpp b/symgraph/actors/systems/actorgroup.cpp similarity index 100% rename from symgraph/actors/actorgroup.cpp rename to symgraph/actors/systems/actorgroup.cpp diff --git a/symgraph/actors/actorgroup.h b/symgraph/actors/systems/actorgroup.h similarity index 100% rename from symgraph/actors/actorgroup.h rename to symgraph/actors/systems/actorgroup.h diff --git a/symgraph/actors/particlesystem.cpp b/symgraph/actors/systems/particlesystem.cpp similarity index 100% rename from symgraph/actors/particlesystem.cpp rename to symgraph/actors/systems/particlesystem.cpp diff --git a/symgraph/actors/particlesystem.h b/symgraph/actors/systems/particlesystem.h similarity index 100% rename from symgraph/actors/particlesystem.h rename to symgraph/actors/systems/particlesystem.h diff --git a/symgraph/actors/symsystem.cpp b/symgraph/actors/systems/symsystem.cpp similarity index 100% rename from symgraph/actors/symsystem.cpp rename to symgraph/actors/systems/symsystem.cpp diff --git a/symgraph/actors/symsystem.h b/symgraph/actors/systems/symsystem.h similarity index 100% rename from symgraph/actors/symsystem.h rename to symgraph/actors/systems/symsystem.h diff --git a/symgraph/symgraph.pro b/symgraph/symgraph.pro index 9379d37..2c0c221 100644 --- a/symgraph/symgraph.pro +++ b/symgraph/symgraph.pro @@ -1,63 +1,63 @@ TEMPLATE = lib QT += core opengl CONFIG += c++11 staticlib release warn_on DESTDIR += lib win32:LIBS += opengl32.lib LIBS += -L../symath/lib/ -lsymath INCLUDEPATH += $$PWD/../symath HEADERS += \ scene.h \ camera.h \ actors/shape.h \ skactor.h \ specs/scalable.h \ specs/positionable.h \ specs/orientable.h \ specs/renderable.h \ specs/colorable.h \ specs/specs.h \ specs/evolvable.h \ actors/decoration.h \ listeners/keylistener.h \ listeners/mouselistener.h \ specs/describable.h \ models/glsphere.h \ models/glmarbled.h \ glmodel.h \ actors/particles/newtonparticle.h \ actors/particle.h \ actors/particles/oscillatorparticle.h \ - actors/particlesystem.h \ + actors/systems/particlesystem.h \ actors/systems/interactingsystem.h \ scenewrapper.h \ - actors/actorgroup.h \ - actors/symsystem.h \ + actors/systems/actorgroup.h \ + actors/systems/symsystem.h \ graphtools.h SOURCES += \ scene.cpp \ camera.cpp \ actors/shape.cpp \ actors/decoration.cpp \ specs/describable.cpp \ models/glsphere.cpp \ models/glmarbled.cpp \ glmodel.cpp \ actors/particles/newtonparticle.cpp \ actors/particle.cpp \ actors/particles/oscillatorparticle.cpp \ - actors/particlesystem.cpp \ + actors/systems/particlesystem.cpp \ actors/systems/interactingsystem.cpp \ scenewrapper.cpp \ - actors/actorgroup.cpp \ - actors/symsystem.cpp \ + actors/systems/actorgroup.cpp \ + actors/systems/symsystem.cpp \ graphtools.cpp RESOURCES += \ shaders.qrc