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 :

Calcul de distance pour un cylindre


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Head of Service Delivery
    Inscrit en
    Janvier 2003
    Messages
    2 891
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Head of Service Delivery
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 891
    Par défaut Calcul de la hauteur d'un cylindre
    Bonjour

    Petit problème de trigonométrie pour le week-end.
    Dans mon code, j'ai 2 sphères que je veux joindre par un cylindre. Le calcul de mon angle est correct, le calcul de la distance de mon cylindre semble aussi correct à la console mais à la visualisation, mon cylindre est trop court !
    Voici mon code complet:
    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
     
    import java.awt.event.MouseWheelEvent;
    import javax.media.opengl.GLAutoDrawable;
    import javax.swing.*;
     
    import javax.media.opengl.GL;
    import javax.media.opengl.glu.GLU;
     
    import com.sun.opengl.util.GLUT;
    import java.awt.Point;
    import java.awt.event.MouseWheelListener;
    import javax.media.opengl.*;
     
    public class Test extends JFrame{
     
        GLJPanel canvas;
     
        public Test(){
            super();
            this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            canvas = new GLJPanel();
            canvas.addGLEventListener(new Renderer(this));
            this.getContentPane().add(canvas);
            canvas.requestFocusInWindow();
            this.setPreferredSize(new java.awt.Dimension(800, 600));
            this.setMinimumSize(new java.awt.Dimension(800, 600));
        }
     
        public void refresh(){
            canvas.updateUI();
        }
     
        public static void main(String[]args){
            new Test().setVisible(true);
        }
     
    }
     
    class Renderer implements GLEventListener, MouseWheelListener{
     
        private float zoom = 1;
        private final float zoom_inc = 0.05f;
        private final float c = 0.025f;
        private Test mw;
     
        public Renderer(Test test){
            this.mw = test;
        }
     
        public void init(GLAutoDrawable arg0) {
            GL gl = arg0.getGL();
            GLUT glut = new GLUT();
     
            float ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
            float diffuse[] = { 0.0f, 0.0f, 1.0f, 1.0f };
            float diff_pos[] = {0, 0, zoom, 0f};
            float amb_pos[] = {zoom, zoom, zoom, 0f};
            gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient, 0);
            gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, diff_pos, 0);
            gl.glLightfv(GL.GL_LIGHT1, GL.GL_SPECULAR, diffuse, 0);
            gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, amb_pos, 0);
     
            gl.glFrontFace(GL.GL_CW);
            gl.glEnable(GL.GL_LIGHTING);
            gl.glEnable(GL.GL_LIGHT0);
            gl.glEnable(GL.GL_LIGHT1);
            gl.glEnable(GL.GL_AUTO_NORMAL);
            gl.glEnable(GL.GL_NORMALIZE);
            gl.glEnable(GL.GL_DEPTH_TEST);
            gl.glDepthFunc(GL.GL_LESS);
     
            gl.glShadeModel(GL.GL_SMOOTH); // Enable Smooth Shading
            gl.glClearColor(1f, 1f, 1f, 1f);
            gl.glClearDepth(1.0f);
     
            arg0.addMouseWheelListener(this);
        }
     
        public void display(GLAutoDrawable arg0) {
            float mat[] = new float[4];
            GL gl = arg0.getGL();
            GLUT glut = new GLUT();
            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
     
            gl.glTranslatef(0, 0, -5f * zoom);
     
            gl.glPushMatrix();
            mat[0] = (float) 0;
            mat[1] = (float) 0;
            mat[2] = (float) 0;
            mat[3] = 1.0f;
            gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, mat, 0);
            mat[0] = (float) 0;
            mat[1] = (float) 0;
            mat[2] = (float) 1;
            gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, mat, 0);
            Point p1 = new Point(-1, 1);
            Point p2 = new Point(1, -1);
            Point p1p = new Point(-1, -1);
            gl.glTranslatef(-1f, 1f, 0);
            glut.glutSolidSphere(c*2, 40, 32);
            gl.glTranslatef(1f, -1f, 0);
            gl.glTranslatef(1f, -1f, 0);
            glut.glutSolidSphere(c*2, 40, 32);
            gl.glTranslatef(-1f, 1f, 0);
            double d1 = p1.distance(p2.x, p2.y);
            double d2 = p1.distance(p1p.x, p1p.y);
            double angler = Math.acos(d2/d1);
            float angled = (float)Math.toDegrees(angler);
            gl.glTranslatef(-1f, 1f, 0);
            gl.glRotatef(angled, 1f, 1f, 0f);
            float distance = (float)Math.sqrt(((p2.x-p1.x)*(p2.x-p1.x)) + ((p2.y-p1.y)*(p2.y-p1.y)));
            glut.glutSolidCylinder(c, distance, 40, 32);
            gl.glPopMatrix();
     
            gl.glFlush();
        }
     
        public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int w, int h) {
            GL gl = arg0.getGL();
            gl.glMatrixMode(GL.GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glOrtho(-2.5*w/h*zoom, 2.5*w/h*zoom, -2.5*zoom, 2.5*zoom, -5f * zoom, 5f * zoom);
            gl.glMatrixMode(GL.GL_MODELVIEW);
            gl.glLoadIdentity();
        }
     
        public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) {
        }
     
        public void mouseWheelMoved(MouseWheelEvent arg0) {
            if (arg0.getWheelRotation() == 1) {
                zoom += zoom_inc;
            } else {
                zoom -= zoom_inc;
            }
            this.mw.refresh();
        }
     
    }
    C'est un code Java 5 utilisant JOGL.
    Merci d'avance à qui voudra bien m'expliquer et résoudre ce petit mystère.

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  2. #2
    Membre Expert

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Par défaut
    gl.glRotatef(angled, 1f, 1f, 0f);
    Si tu veux une rotation dans le plan (X,Y), c'est pas plutot
    gl.glRotatef(angled, 0f, 0f, 1f); // ou -1f, suivant l'orientation de ton plan
    ?

    Ceci dit cela fait longtemps que je n'ai plus fait d'OpenGL.

    Mon site web | Mon blog | Mes photos | Groupe USA
    > BONJOUR, JE SUIS NOUVEAU SUR CE FORUM
    > presse la touche caps lock, stp
    > OH.. MERCI C EST BEAUCOUP PLUS FACILE COMME CA

  3. #3
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Head of Service Delivery
    Inscrit en
    Janvier 2003
    Messages
    2 891
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Head of Service Delivery
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 891
    Par défaut
    Bonjour LeGreg

    Malheureusement, ta solution ne fonctionne pas.
    Merci quand même de ta contribution.

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  4. #4
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Head of Service Delivery
    Inscrit en
    Janvier 2003
    Messages
    2 891
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Head of Service Delivery
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 891
    Par défaut
    Bonjour

    Bon, j'ai refait mon code et en ai discuté avec mes collègues, on a pas plus d'explication
    Voici mon code où j'ai écrit mes fonctions me retournant l'angle et la distance:
    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
     
    import java.awt.event.MouseWheelEvent;
    import javax.media.opengl.GLAutoDrawable;
    import javax.swing.*;
     
    import javax.media.opengl.GL;
    import javax.media.opengl.glu.GLU;
     
    import com.sun.opengl.util.GLUT;
    import java.awt.Point;
    import java.awt.event.MouseWheelListener;
    import java.awt.geom.Point2D;
    import javax.media.opengl.*;
     
    public class Test extends JFrame{
     
        GLJPanel canvas;
     
        public Test(){
            super();
            this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            canvas = new GLJPanel();
            canvas.addGLEventListener(new Renderer(this));
            this.getContentPane().add(canvas);
            canvas.requestFocusInWindow();
            this.setPreferredSize(new java.awt.Dimension(800, 600));
            this.setMinimumSize(new java.awt.Dimension(800, 600));
        }
     
        public void refresh(){
            canvas.updateUI();
        }
     
        public static void main(String[]args){
            new Test().setVisible(true);
        }
     
    }
     
    class Renderer implements GLEventListener, MouseWheelListener{
     
        private float zoom = 1;
        private final float zoom_inc = 0.025f;
        private final float c = 0.025f;
        private Test mw;
     
        public Renderer(Test test){
            this.mw = test;
        }
     
        public void init(GLAutoDrawable arg0) {
            GL gl = arg0.getGL();
            GLUT glut = new GLUT();
     
            float ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
            float diffuse[] = { 0.0f, 0.0f, 1.0f, 1.0f };
            float diff_pos[] = {0, 0, zoom, 0f};
            float amb_pos[] = {zoom, zoom, zoom, 0f};
            gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, ambient, 0);
            gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, diff_pos, 0);
            gl.glLightfv(GL.GL_LIGHT1, GL.GL_SPECULAR, diffuse, 0);
            gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, amb_pos, 0);
     
            gl.glFrontFace(GL.GL_CW);
            gl.glEnable(GL.GL_LIGHTING);
            gl.glEnable(GL.GL_LIGHT0);
            gl.glEnable(GL.GL_LIGHT1);
            gl.glEnable(GL.GL_AUTO_NORMAL);
            gl.glEnable(GL.GL_NORMALIZE);
            gl.glEnable(GL.GL_DEPTH_TEST);
            gl.glDepthFunc(GL.GL_LESS);
     
            gl.glShadeModel(GL.GL_SMOOTH); // Enable Smooth Shading
            gl.glClearColor(1f, 1f, 1f, 1f);
            gl.glClearDepth(1.0f);
     
            arg0.addMouseWheelListener(this);
        }
     
        private double calculateAngle(double p1x, double p1y, double p2x, double p2y){
            Point2D.Double p1 = new Point2D.Double(p1x, p1y);
            Point2D.Double p2 = new Point2D.Double(p2x, p2y);
            Point2D.Double p1p = new Point2D.Double(p1x, -p1y);
            double d1 = p1.distance(p2.x, p2.y);
            double d2 = p1.distance(p1p.x, p1p.y);
            return Math.acos(d2/d1);
        }
     
        private double calculateDistance(double p1x, double p1y, double p2x, double p2y){
            return Math.sqrt( ((p1x-p2x)*(p1x-p2x)) + ((p1y-p2y)*(p1y-p2y)));
        }
     
        private void drawOrigin(GL gl){
            float mat[] = new float[4];
            mat[0] = (float) 0;
            mat[1] = (float) 0;
            mat[2] = (float) 0;
            mat[3] = 1.0f;
            gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, mat, 0);
            mat[0] = (float) 1;
            mat[1] = (float) 0;
            mat[2] = (float) 0;
            gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, mat, 0);
            GLUT glut = new GLUT();
            glut.glutSolidSphere(c*2, 40, 32);
        }
     
        public void display(GLAutoDrawable arg0) {
            float mat[] = new float[4];
            GL gl = arg0.getGL();
            GLUT glut = new GLUT();
            gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
     
            gl.glTranslatef(0, 0, -5f * zoom);
     
            drawOrigin(gl);
     
            mat[0] = (float) 0;
            mat[1] = (float) 0;
            mat[2] = (float) 0;
            mat[3] = 1.0f;
            gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, mat, 0);
            mat[0] = (float) 0;
            mat[1] = (float) 0;
            mat[2] = (float) 1;
            gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, mat, 0);
     
            //First sphere
            gl.glPushMatrix();
            gl.glTranslatef(-1f, 1f, 0);
            glut.glutSolidSphere(c*2, 40, 32);
            gl.glPopMatrix();
     
            //Second sphere
            gl.glPushMatrix();
            gl.glTranslatef(1f, -1f, 0);
            glut.glutSolidSphere(c*2, 40, 32);
            gl.glPopMatrix();
     
            //Cylinder
            gl.glPushMatrix();
            float angled = (float)Math.toDegrees(calculateAngle(-1, 1, 1, -1));
            float distance = (float)calculateDistance(-1, 1, 1, -1);
            System.out.println(angled+"\t"+distance);
            gl.glTranslatef(-1f, 1f, 0);
            gl.glRotatef(angled, 1f, 1f, 0f);
            glut.glutSolidCylinder(c, distance, 40, 32);
            gl.glPopMatrix();
     
            gl.glFlush();
        }
     
        public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int w, int h) {
            GL gl = arg0.getGL();
            gl.glMatrixMode(GL.GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glOrtho(-2.5*w/h*zoom, 2.5*w/h*zoom, -2.5*zoom, 2.5*zoom, -5f * zoom, 5f * zoom);
            gl.glMatrixMode(GL.GL_MODELVIEW);
            gl.glLoadIdentity();
        }
     
        public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) {
        }
     
        public void mouseWheelMoved(MouseWheelEvent arg0) {
            if (arg0.getWheelRotation() == 1) {
                zoom += zoom_inc;
            } else {
                zoom -= zoom_inc;
            }
            this.mw.refresh();
        }
     
    }
    Bon, les valeurs retournées par mes fonctions sont correctes. Néanmoins, mon cylindre ne fait toujours pas la jonction entre ma première sphère et la seconde.
    Toutefois, si je met comme paramètre une longueur de 4 pour mon cylindre, alors, cela fonctionne Or la distance prédite est de racine de 8. Il y a manifestement un problème mais je ne vois pas du tout où ?

    Merci d'avance de vos réponses.

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

  5. #5
    Membre éprouvé Avatar de Harooold
    Homme Profil pro
    Ingénieur 3D temps réel
    Inscrit en
    Mars 2008
    Messages
    136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2008
    Messages : 136
    Par défaut
    Salut,

    Met un petit glLoadIdentity() après gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

    Histoire de réinitialiser ta modelview, sinon les transformations s'accumulent ... ( sauf celles entre push et popMatrix ).

    En gros, pour moi, à chaque raffraichissement, toute ta scène "recule" de -5. * zoom sur l'axe Z.
    Mais comme toute la scène subit cette transformation ça n'est pas le problème.

    Ensuite je dirais que ton cylindre n'est pas trop court, mais juste mal orienté.
    Quand tu le dessines il est orienté vers les Z positifs.
    Il faut donc faire une rotation de 90 sur l'axe Y. pour le mettre dans le le plan X Y puis une rotation de angled sur l axe Z pour l'orienter vers l autre point.

    En gros quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    gl.glTranslatef(-1f, 1f, 0); // pour le faire partir de la premiere sphere
    gl.glRotatef(90., 0f, 1f, 0f); // place dans le plan X Y 
    gl.glRotatef(angled, 0., 0., 1.); // pointe vers l'autre sphere
    glut.glutSolidCylinder(c, distance, 40, 32); // et on dessine
    Et normallement c'est bon

  6. #6
    Membre expérimenté
    Avatar de GLDavid
    Homme Profil pro
    Head of Service Delivery
    Inscrit en
    Janvier 2003
    Messages
    2 891
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Head of Service Delivery
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 891
    Par défaut
    Salut Harooold

    Merci à toi C'était ça. Il y a juste un problème avec ta solution, j'obtiens un cylindre parallèle aux abscisses. Pour corriger le tir, il faut alors faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    gl.glRotatef(90, 1f, 1f, 0f);
    gl.glRotatef(angled, 0, 0, 1);
    Et la vie est belle ainsi
    Un grand merci à toi

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code :tagcode: ni le tag :resolu:

    Je ne répond à aucune question technique par MP.

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

Discussions similaires

  1. custom field pour le calcul de distance entre utilisteur
    Par ITParty dans le forum Développement Sharepoint
    Réponses: 7
    Dernier message: 31/05/2013, 22h39
  2. Réponses: 2
    Dernier message: 11/03/2010, 14h53
  3. Calcul de tangente pour un mesh
    Par derferic dans le forum DirectX
    Réponses: 3
    Dernier message: 24/05/2008, 01h53
  4. [GEOMETRIE] calcul de distance dans un triangle
    Par gronaze dans le forum Mathématiques
    Réponses: 10
    Dernier message: 29/06/2006, 10h04
  5. [MySQL] Fonctions calculs SQL/PHP pour projet football
    Par spamyx dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 25/04/2006, 16h16

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