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

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

C++ Discussion :

Simuler la gravité : translations horizontales non souhaitées


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 39
    Points : 31
    Points
    31
    Par défaut Simuler la gravité : translations horizontales non souhaitées
    Bonjour, je réalise en ce moment en C++ une simulation de Gravité en 2D, pour le moment je me concentre sur l'axe X.
    PS : je ne suis pas très bon en programmation

    Voici mon problème : mon code est orienté objet, quand je lance le programme, tous ce passe bien jusqu'à que les points se rencontrent en coordonnée 0.0. A ce stade là, il va réafficher ce qui c'est afficher depuis le debut et va le refaire tout en changeant les distance ?aléatoirement?

    Voici le code (j'utilise SDL2 OpenGL et math.h)

    le header
    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
    #pragma once
    #include <stdlib.h>
    #include <iostream>
    #include <SDL2/SDL.h>
    #include <string>
    #include <GL\glew.h>
     
    class graphic
    {
    public:
        graphic();
        ~graphic();
     
        int InitSDL();
        int InitOpenGl();
        int Create_Window(const char *titre, int widht, int height);
        void DrawPoint(float points[]);
        void Quit_SDL();
     
        void CalculePosition(float points[], float masse1, float masse2);
        float CalculeDistance(float points[]);
        float CalculeForce(float points[], float masse1, float masse2);
     
    private:
        SDL_Window* window;
        SDL_GLContext contexteOpenGL;
        GLenum initialisationGLEW;
        GLuint vertexbuffer;
     
        float m_DistX;
        float m_G;
        float m_ForceX;
        float m_accX1;
    };
    La définition de la classe
    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
    #include "graphic.h"
    #include <string>
     
    using namespace std;
     
    graphic::graphic()
    {
        window = 0;
        contexteOpenGL = 0;
        initialisationGLEW = 0;
        m_G = 0.001;
        m_accX1 = 0;
    }
     
    graphic::~graphic()
    {
    }
     
    int graphic::InitSDL()
    {
        //Init SDL
        if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
        {
            cout << "Erreur d'initialisation de la SDL : " << SDL_GetError() << endl;
            Quit_SDL();
            return -1;
        }
     
        //OpenGL version
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
     
        //DoubleBuffer
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
     
        return 0;
    }
     
    int graphic::InitOpenGl()
    {
        //Init OpenGL
        //OpenGL context
        contexteOpenGL = SDL_GL_CreateContext(window);
        if (contexteOpenGL == 0)
        {
            cout << SDL_GetError() << endl;
            Quit_SDL();
            return -1;
        }
     
        //Init Glew
        initialisationGLEW = glewInit();
        if (initialisationGLEW != GLEW_OK)
        {
            cout << "Erreur d'initialisation de GLEW : " << glewGetErrorString(initialisationGLEW) << endl;
            SDL_Delay(2000);
            Quit_SDL();
            return EXIT_FAILURE;
        }
    }
     
    int graphic::Create_Window(const char *titre, int widht, int height)
    {
        window = SDL_CreateWindow(titre, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, widht, height, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
        return 0;
    }
     
    void graphic::Quit_SDL()
    {
        SDL_GL_DeleteContext(contexteOpenGL);
        SDL_DestroyWindow(window);
        SDL_Quit();
    }
     
    void graphic::DrawPoint(float points[])
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, points);
        glEnableVertexAttribArray(0);
        glDrawArrays(GL_POINTS, 0, 2);
        glDisableVertexAttribArray(0);
        SDL_GL_SwapWindow(window);
    }
     
    void graphic::CalculePosition(float points[], float masse1, float masse2)
    {     
        cout << m_ForceX << endl;
        //Points X
        //Points 0
        if (points[0] < 0)
        {
            points[0] += m_accX1;
        }
        else if (points[0] > 0)
        {
            points[0] -= m_accX1;
        }
        else
        {
            points[0] = 0;
        }
     
        //Points 2
        if (points[2] < 0)
        {
            points[2] += m_accX1;
        }
        else if (points[2] > 0)
        {
            points[2] -= m_accX1;
        }
        else
        {
            points[2] = 0;
        }
     
        CalculeDistance(points);
        CalculeForce(points, masse1, masse2);
        m_accX1 = m_ForceX / masse1;
        DrawPoint(points);
    }
    float graphic::CalculeForce(float points[], float masse1, float masse2)
    {
        //Calcule Force
        m_ForceX = m_G*((masse1 * masse2) / pow(m_DistX, 2.0));
        return m_ForceX;
    }
     
    float graphic::CalculeDistance(float points[])
    {
        //Calcule Distance X
        if (points[0] < points[2])
        {
            m_DistX = fdim(points[2], points[0]);
        }
        else if (points[2] < points[0])
        {
            m_DistX = fdim(points[0], points[2]);
        }
        else if (points[0] == points[2])
        {
            m_DistX = 0;
        }
        return m_DistX;
    }
    Et le main
    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
    #include "graphic.h"
    #include "GravitySimulation.h"
    #include <iostream>
    #include <SDL2\SDL.h>
    #include <GL\glew.h>
     
    using namespace std;
     
    int main(int argc, char *argv[])
    {
        float points[] = { -0.5, 0.0,**** 0.5, 0.0 };
        int masse1(2), masse2(2);
        bool etat(true);
     
        graphic window;
     
        window.InitSDL();
        window.Create_Window("GamEngine", 800, 600);
        window.InitOpenGl();
     
        while (etat)
        {
            window.CalculePosition(points, masse1, masse2);
            SDL_Delay(10);
        }
        window.Quit_SDL();
        return 0;
    }
    Voilà, ça fait environ 2 jours que j'essai de régler ce problème sans résultats, merci d'avance pour votre aide

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 855
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 855
    Points : 218 551
    Points
    218 551
    Billets dans le blog
    118
    Par défaut
    Bonjour,

    Quel est le problème ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 39
    Points : 31
    Points
    31
    Par défaut
    Salut merci d'avoir répondu LittleWhite
    tu a essaye mon programme ?? si non essayes le et tu verra le problème et ce sera plus clair pour toi

    Pendant ce temps j'ai recode en asseyant de repartir à zéro mais ça ne marche toujours pas voici le code pour ceux que sa intéresse :
    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
    #include <SDL2\SDL.h>
    #include <GL\glew.h>
    #include <iostream>
    #include <math.h>
     
    using namespace std;
     
    int main(int argc, char **argv)
    {
    	SDL_Window *window(0);
    	SDL_GLContext contextGL(0);
    	float point[] = { 0.4, 0.0,	-0.2, -0.8 };
    	float distX, distY, dist;
    	float G(0.00000005);
    	float ForceX(0), ForceY(0);
    	int m1(1), m2(1);
    	float accX1(0), accX2(0), accY1(0), accY2(0);
     
    	{//Init SDL
    		if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    		{
    			cout << "Erreur lors de l'initialisation de la SDL : " << SDL_GetError() << endl;
    			SDL_Quit();
    			return -1;
    		}
     
    		//Init OpenGL
    		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    		SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
    		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    		SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
     
    		//Create a Window
    		window = SDL_CreateWindow("SimulationGravite2D", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 840, 620, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
     
    		//Create OpenGL context
    		contextGL = SDL_GL_CreateContext(window);
    		if (contextGL == 0)
    		{
    			cout << SDL_GetError() << endl;
    			SDL_DestroyWindow(window);
    			SDL_Quit();
    			return -1;
    		}
    		GLenum initialisationGLEW(glewInit());
    		if (initialisationGLEW != GLEW_OK)
    		{
    			cout << "Erreur d'initialisation de GLEW : " << glewGetErrorString(initialisationGLEW) << endl;
    			SDL_GL_DeleteContext(contextGL);
    			SDL_DestroyWindow(window);
    			SDL_Quit();
    			return -1;
    		}}
     
    	//While
    	while (1==1)
    	{
    		//Draw
    		glClear(GL_COLOR_BUFFER_BIT);
    		glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, point);
    		glEnableVertexAttribArray(0);
    		glDrawArrays(GL_POINTS, 0, 2);
    		glDisableVertexAttribArray(0);
    		SDL_GL_SwapWindow(window);
     
    		//Calcul Distance
    			//X
    				if (point[0] > point[2])
    				{
    					distX = fdim(point[0], point[2]);
    				}
    				else if (point[2] > point[0])
    				{
    					distX = fdim(point[2], point[0]);
    				}
    				else if (point[2] == point[0])
    				{
    					distY = 0;
    				}
    			//Y
    				if (point[1] > point[3])
    				{
    					distY = fdim(point[1], point[3]);
    				}
    				else if (point[3] > point[1])
    				{
    					distY = fdim(point[3], point[1]);
    				}
    				else if (point[3] == point[1])
    				{
    					distY = 0;
    				}
     
    		//Calcul Force
    			ForceX = G*((m1*m2) / distX);
    			ForceY = G*((m1*m2) / distY);
     
    		//Calcul Acceleration
    			if (point[0] < point[2])
    			{
    				accX1 = accX1 + (ForceX / m1);
    				accX2 = accX2 - (ForceX / m2);
    			}
    			else if(point[2] < point[0])
    			{
    				accX1 = accX1 - (ForceX / m1);
    				accX2 = accX2 + (ForceX / m2);
    			}
    			else if (point[0] == point[2])
    			{
    				accX1 = 0;
    				accX2 = 0;
    			}
    			if (point[1] < point[3])
    			{
    				accY1 = accY1 + (ForceY / m1);
    				accY2 = accY2 - (ForceY / m2);
    			}
    			else if (point[3] < point[1])
    			{
    				accY1 = accY1 - (ForceY / m1);
    				accY2 = accY2 + (ForceY / m2);
    			}
    			else if (point[1] == point[3])
    			{
    				accY1 = 0;
    				accY1 = 0;
    			}
    			cout << accX1 << endl;
    			//accY1 = accY1 + (ForceY / m1);
    			//accY2 = accY2 + (ForceY / m2);
     
    		//Calcul Position
    			if (point[0] < point[2])
    			{
    				point[0] += accX1;
     
    				point[2] += accX2;
    			}
    			else if (point[2] < point[0])
    			{
    				point[0] += accX1;
     
    				point[2] += accX2;
    			}
     
    			if (point[1] < point[3])
    			{
    				point[1] += accY1;
     
    				point[3] += accY2;
    			}
    			else if (point[3] < point[1])
    			{
    				point[1] += accY1;
     
    				point[3] += accY2;
    			}
    			//cout << point[0];
    	}
     
    	//Quit
    	SDL_DestroyWindow(window);
    	SDL_Quit();
    	return 0;
    }

  4. #4
    Membre confirmé
    Homme Profil pro
    .
    Inscrit en
    Juin 2002
    Messages
    239
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : .
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2002
    Messages : 239
    Points : 567
    Points
    567
    Par défaut
    Bonjour.

    En général, diviser par 0 ne donne pas un bon résultat ...

    Si distX est nul, alors le calcul de ForceX = G*((m1*m2) / distX) va créer une exception.
    Idem pour ForceY si distY est nul.

    Il y a deux possibilités pour corriger ce problème :

    a) imposer une distance minimum entre les deux points, comme s'ils avaient une taille non nulle :
    ils sont en contact, mais leurs centres d'inertie ne se touchent pas.

    b) si la distance est nulle, mettre la force à 0 : puisqu'ils sont en contact, ils vont le rester ...

    A part cela, il y a plusieurs choses bizarres dans ce code !

    1) en géométrie euclidienne, la distance entre deux points est la racine carrée de distX^2+distY^2.
    C''est elle qui doit apparaître au dénominateur dans le calcul de la force, et non distX ou distY seul.
    ( et élevée au carré, comme dans le premier code montré )

    2) la force donne une accélération, laquelle modifie la vitesse.
    Ce que vous notez accX et accY doit s'appeler vitX et vitY.

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 39
    Points : 31
    Points
    31
    Par défaut
    Bonjour merci pour ton commentaire constructif prof, alors oui c'est vrai que diviser par 0 c'est pas terrible enfin
    donc j'ai modifié le code mais un problème persiste : une fois la collision produite, les 2 points se décalent vers le bord indéfiniment
    Pour mieux comprendre voici le code modifié :

    le header
    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
    #pragma once
    #include <stdlib.h>
    #include <iostream>
    #include <SDL2/SDL.h>
    #include <string>
    #include <GL\glew.h>
     
    class graphic
    {
    public:
    	graphic();
    	~graphic();
     
    	int InitSDL();
    	int InitOpenGl();
    	int Create_Window(const char *titre, int widht, int height);
    	void DrawPoint(float points[]);
    	void Quit_SDL();
     
    	void CalculePosition(float points[], float masse1, float masse2);
    	float CalculeDistance(float points[]);
    	float CalculeForce(float points[], float masse1, float masse2);
     
    private:
    	SDL_Window* window;
    	SDL_GLContext contexteOpenGL;
    	GLenum initialisationGLEW;
    	GLuint vertexbuffer;
     
    	float m_G;
     
    	float m_DistX;
    	float m_DistY;
     
    	float m_ForceX;
    	float m_ForceY;
     
    	float m_vitX1;
    	float m_vitX2;
    	float m_vitY1;
    	float m_vitY2;
    };
    La définition de la classe :
    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
    #include "graphic.h"
    #include <string>
     
    using namespace std;
     
    graphic::graphic()
    {
    	window = 0;
    	contexteOpenGL = 0;
    	initialisationGLEW = 0;
    	m_G = 0.0001;
     
    	m_vitX1 = 0;
    	m_vitX2 = 0;
    	m_vitY1 = 0;
    	m_vitY2 = 0;
    }
     
    graphic::~graphic()
    {
    }
     
    int graphic::InitSDL()
    {
    	//Init SDL
    	if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    	{
    		cout << "Erreur d'initialisation de la SDL : " << SDL_GetError() << endl;
    		Quit_SDL();
    		return -1;
    	}
     
    	//OpenGL version
    	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    	SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
     
    	//DoubleBuffer
    	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
     
    	return 0;
    }
     
    int graphic::InitOpenGl()
    {
    	//Init OpenGL
    	//OpenGL context
    	contexteOpenGL = SDL_GL_CreateContext(window);
    	if (contexteOpenGL == 0)
    	{
    		cout << SDL_GetError() << endl;
    		Quit_SDL();
    		return -1;
    	}
     
    	//Init Glew
    	initialisationGLEW = glewInit();
    	if (initialisationGLEW != GLEW_OK)
    	{
    		cout << "Erreur d'initialisation de GLEW : " << glewGetErrorString(initialisationGLEW) << endl;
    		SDL_Delay(2000);
    		Quit_SDL();
    		return EXIT_FAILURE;
    	}
    }
     
    int graphic::Create_Window(const char *titre, int widht, int height)
    {
    	window = SDL_CreateWindow(titre, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, widht, height, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);
    	return 0;
    }
     
    void graphic::Quit_SDL()
    {
    	SDL_GL_DeleteContext(contexteOpenGL);
    	SDL_DestroyWindow(window);
    	SDL_Quit();
    }
     
    void graphic::DrawPoint(float points[])
    {
    	glClear(GL_COLOR_BUFFER_BIT);
    	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, points);
    	glEnableVertexAttribArray(0);
    	glDrawArrays(GL_POINTS, 0, 2);
    	glDisableVertexAttribArray(0);
    	SDL_GL_SwapWindow(window);
    }
     
    void graphic::CalculePosition(float points[], float masse1, float masse2)
    {
    	cout << m_DistX << "	" << m_DistY << endl;
    	//Axe X
    		//Points 0
    		if (points[0] < points[2])
    		{
    			points[0] += m_vitX1;
    		}
    		else if (points[0] > points[2])
    		{
    			points[0] -= m_vitX1;
    		}
    		else
    		{
    			points[0] = 0;
    		}
     
    		//Points 2
    		if (points[2] < points[0])
    		{
    			points[2] += m_vitX2;
    		}
    		else if (points[2] > points[0])
    		{
    			points[2] -= m_vitX2;
    		}
    		else
    		{
    			points[2] = 0;
    		}
     
    	//Axe Y
    		//Points 0
    		if (points[1] < points[3])
    		{
    			points[1] += m_vitY1;
    		}
    		else if (points[1] > points[3])
    		{
    			points[1] -= m_vitY1;
    		}
    		else
    		{
    			points[1] = 0;
    		}
     
    		//Points 2
    		if (points[3] < points[1])
    		{
    			points[3] += m_vitY2;
    		}
    		else if (points[3] > points[1])
    		{
    			points[3] -= m_vitY2;
    		}
    		else
    		{
    			points[3] = 0;
    		}
     
    	CalculeDistance(points);
    	CalculeForce(points, masse1, masse2);
     
    	m_vitX1 = m_ForceX / masse1;
    	m_vitX2 = m_ForceX / masse2;
     
    	m_vitY1 = m_ForceY / masse1;
    	m_vitY2 = m_ForceY / masse2;
    	DrawPoint(points);
    }
     
    float graphic::CalculeForce(float points[], float masse1, float masse2)
    {
    	//Calcule Force
     
    	m_ForceX = m_G*((masse1 * masse2) / pow(m_DistX, 2.0));
    	if (m_DistX < 0.01)
    	{
    		m_ForceX = 0;
    		m_DistX = 0;
    	}
     
    	m_ForceY = m_G*((masse1 * masse2) / pow(m_DistY, 2.0));
    	if (m_DistY < 0.01)
    	{
    		m_ForceY = 0;
    		m_DistY = 0;
    	}
     
    	return m_ForceX, m_ForceY;
    }
     
    float graphic::CalculeDistance(float points[])
    {
    	//Calcule Distance X
    		if (points[0] < points[2])
    		{
    			m_DistX = fdim(points[2], points[0]);
    		}
    		else if (points[2] < points[0])
    		{
    			m_DistX = fdim(points[0], points[2]);
    		}
    		else if (points[0] == points[2])
    		{
    			m_DistX = 0;
    		}
    	//Calcule Distance Y
    		if (points[1] < points[3])
    		{
    			m_DistY = fdim(points[3], points[1]);
    		}
    		else if (points[3] < points[1])
    		{
    			m_DistY = fdim(points[1], points[3]);
    		}
    		else if (points[1] == points[3])
    		{
    			m_DistY = 0;
    		}
    	return m_DistX, m_DistY;
    }
    le main n'a pas changé si ce n'est que j'ai enlevé le "SDl_Delay(10);" qui était inutile

    Voila merci d'avance pour vos réponse

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Salut,

    De manière générale, si tes éléments visuels commencent à se décaler indéfiniment sur l'horizontale, c'est sans doute que... la force verticale a été mise à 0 (A l'inverse, si tes éléments se mettaient à tomber en ligne droite, ce serait parce que la force horizontale a été mise à 0 )

    Du coup, il t'appartient de décider ce qui se passe avec deux éléments une fois que la collision a eu lieu :
    • tu as une jolie explosion ? les deux forces (verticales et horizontales) doivent être mises à 0 (ou pas, à vrai dire : le dessin de chaque explosion peut très bien suivre la trajectoire d'origine de l'objet )
    • les deux élément s'agglutinent et n'en forment plus qu'un ? il faut déterminer sa nouvelle trajectoire
    • un élément s'arrête, l'autre rebondi les forces de l'un sont mises à 0, les forces de l'autre sont recalculées pour le faire partir "dans l'autre sens".
    • ...
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 39
    Points : 31
    Points
    31
    Par défaut
    Ok merci koala01, il faut en effet décider de ce qu'il se passe après la collision mais une dernière question persiste = j'ai l'impression que mon programme est "bridé" à tant de calcule par seconde : pour que le programme fonctionne correctement il faut que la valeur de m_g soit très basse or en le faisant ça devient très lent, n'y aurait t'il pas de solution pour que ce sois plus rapide sans augmenter la valeur de m_g ?

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Ben, déjà, tu brides toi même le programme avec ton SDL_delay(10) (au niveau de ta fonction main)...

    Ensuite, la gravité, c'est normalement une constante (égale à 9.807 m/s² sur la terre), et tu ne devrais donc jamais modifier cette valeur tant que tu reste dans un système bien spécifique : tu peux passer de 9.807 sur terre à 1.622 sur la lune ou à 3.711 sur mars, mais, tant que tu es soumis à un système de gravité donné (dépendant dans les exemples que je donne de la planète sur laquelle elle est calculée), tu n'as absolument aucune raison d'aller y chipoter.

    De la même manière, la masse des objets déplacés n'a -- a priori -- (mais bon, on pourrait trouver des cas dans lesquels cette assertion serait fausse ) pas à évoluer dans le temps : un obus de 540kg est sensé peser 540kg au moment où il est tiré et... continuer à les peser au moins jusqu'à ce qu'il percute un obstacle .

    Si tu veux modifier la vitesse de tes objets, il ne te reste donc plus que deux choses que tu puisse faire varier : la force de propulsion, qui n'a absolument rien à voir, ni avec la masse de ton objet, ni avec la gravité qu'il subit, et la vitesse de l'affichage.

    La vitesse de l'affichage, elle sera très dépendante du matériel, et tu ne seras sans doute pas très ravi si, sur un ordinateur A tes différents éléments bougent comme des limaces et si, sur un ordinateur B, ils bougent tellement vite que l'on n'arrive plus à les suivre : l'idée est d'arriver à faire en sorte que tes différents éléments se déplacent à la même vitesse sur les deux ordinateurs concernés.

    Et, pour ce faire, il faut savoir combien de temps s'est déroulé entre l'affichage précédant et celui que l'on s'apprête à occasionner, de manière à pouvoir déterminer la distance (horizontale et vertitcale) qui devrait avoir été parcourue, à une vitesse donnée, entre les deux affichages concernés.

    Si bien qu'il n'y a vraiment plus qu'une seule et unique chose sur laquelle tu puisse effectivement agir pour calculer la vitesse de déplacement : la force de propulsion subie par les différents élément que tu souhaites afficher

    Au fait, c'est quoi cet affreux return m_ForceX, m_ForceY; à la fin de ta fonction CalculeDistance question: Si tu veux pouvoir faire en sorte de renvoyer deux valeurs, tu devrais créer un agrégat de données (une structure par) qui pourrait représenter les différentes données calculées.

    D'ailleurs, à ce titre, tu aurais sans doute très largement intérêt à utiliser une telle structure pour tout ce qui est destiné à représenter les forces verticales et horizontales lorsqu'elles doivent être manipulées de manière commune, cela te faciliterait grandement la tâche

    Je t'ai expliqué en vitesse les grands principes en diagonale ici. A toi de voir comment tu pourras les mettre en place
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #9
    Membre éprouvé Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Points : 1 054
    Points
    1 054
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Ensuite, la gravité, c'est normalement une constante (égale à 9.807 m/s² sur la terre), et tu ne devrais donc jamais modifier cette valeur tant que tu reste dans un système bien spécifique : tu peux passer de 9.807 sur terre à 1.622 sur la lune ou à 3.711 sur mars, mais, tant que tu es soumis à un système de gravité donné (dépendant dans les exemples que je donne de la planète sur laquelle elle est calculée), tu n'as absolument aucune raison d'aller y chipoter.
    Je dirais même plus. Dans sa formule il n'est pas question de l’accélération de la pesanteur qui varie entre la Terre est la Lune, mais de la constante de gravitation universelle qui est la même partout, sur la Lune comme sur Jupiter (ou le soleil). Cette valeur peut donc être définie comme une constante dans le programme.

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 39
    Points : 31
    Points
    31
    Par défaut
    Merci à vous deux pour vos réponse mais en modifiant n'importe qu'elle valeur, cela augmente la valeur incrémenté à la vitesse ce qui fait que lorsque la collision est proche, les points se dépasse et la distance n'a pas le temps d'être en dessous de 0.001 ce qui donne un résultat totalement wtf

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

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Le fait est que tu ne dois pas tout simplement tester la position de tes deux éléments: tu dois tenir compte de la forme et de la taille de chacun des éléments.

    Je m'explique : Mettons que tu aies deux billes qui sont affichées : la bille A, qui a un diamètre de 1cm et la bille B qui a un diamètre de 2cm.

    Ce que tu veux savoir, ce n'est pas si le centre de la bille A se trouve "suffisamment près" du centre de la bille B que pour pouvoir être confondu : ce que tu veux savoir, c'est si elles sont suffisamment proches que pour que l'on puisse considérer qu'elle se touche. Et, pour y arriver, tu vas "tout simplement" t'intéresser à la distance qui sépare le centre de tes deux billes : si cette distance est plus grande que la somme de la taille des deux billes (3cm, selon mon exemple), c'est qu'elles ne se touchent pas; par contre, si cette distance est plus petite que la somme de la taille des deux billes, c'est que les deux billes se touchent, c'est qu'il y a eu collision entre elles.

    Dans la plupart des cas, on peut se contenter de calculer la distance entre nos deux billes; du moins, tant que notre bille A ne se déplacera pas de plus de 1cm (pour rester proche de mon exemple) et que notre bille B ne se déplacera pas de plus de 2cm dans n'importe quelle direction entre deux calculs.

    Après, il y a des situations "extrêmes" : de (très) petits éléments ou des éléments se déplaçant particulièrement vite, ou, du moins, trop vite pour que l'on puisse se rendre compte, à un instant donné, que la distance qui sépare deux éléments est "trop petite" par rapport "à l'espace vital indispensable" pour chacun des éléments.

    Dans ces situations, Nous devrons donc connaitre la position "avant le déplacement" et la position "après le déplacement" afin de pouvoir tracer des segments de droites correspondant au déplacements des deux éléments, et donc de voir si les deux segments de droites se croisent. Si ils se croisent, c'est que nos deux éléments ont du entrer en collision durant le déplacement, autrement, c'est qu'ils ont pu "poursuivre leur route" comme si de rien n'était

    Après, tu peux agir sur les forces qui permettent à tes différents éléments de se déplacer (gravité, attraction quelconque, force de propulsion, que sais-je), mais la vitesse dans une direction donnée qui en résultera ne devrait avoir absolument aucun impact sur ta recherche de collision
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    Membre éprouvé Avatar de fenkys
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 376
    Points : 1 054
    Points
    1 054
    Par défaut
    Citation Envoyé par martantoine Voir le message
    Merci à vous deux pour vos réponse mais en modifiant n'importe qu'elle valeur, cela augmente la valeur incrémenté à la vitesse ce qui fait que lorsque la collision est proche, les points se dépasse et la distance n'a pas le temps d'être en dessous de 0.001 ce qui donne un résultat totalement wtf
    C'est normal qu'elle se dépassent. Le mouvement est continue mais tu calcules des positions discrètes. Le temps nécessaire avant la collision n'est pas un multiple entier de ton unité de temps. Il serait peut être une bonne idée de calculer le temps nécessaire à la collision avant de calculer tes points. Ou alors tu vérifie l'inversion du vecteur (changement du signe) qui relie tes deux particules.

  13. #13
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Gard (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 39
    Points : 31
    Points
    31
    Par défaut
    Ok merci beaucoup à vous tous vous vous m'aurez éclairé et bien aidé sur mon problème
    Reste plus qu'à terminer le programme qui m'aura bien cassé la tête

    Franchement je vous remercie tous pour ce forum juste superbe !

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

Discussions similaires

  1. [JDOM] Element Text non souhaité dans la construction
    Par alex.nd dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 24/10/2006, 14h38
  2. suppression de context non souhaité
    Par 205 dans le forum Tomcat et TomEE
    Réponses: 14
    Dernier message: 26/09/2006, 14h27
  3. Appel de procedure non souhaité
    Par DURVILLE dans le forum Delphi
    Réponses: 2
    Dernier message: 24/09/2006, 16h19
  4. [Débutant] Enregistrement non souhaité.
    Par Monsieur Peck dans le forum Access
    Réponses: 1
    Dernier message: 11/06/2006, 14h40
  5. Raffraichissement de Combobox non souhaité
    Par Kara dans le forum Composants VCL
    Réponses: 12
    Dernier message: 04/11/2005, 09h44

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