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 l'angle de vue haut/bas


Sujet :

OpenGL

  1. #1
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 274
    Points : 169
    Points
    169
    Par défaut Calcul de l'angle de vue haut/bas
    Bonjour,

    J'ai un petit problème de 3D:

    - A l'aide d'une heightmap, j'ai créé un univers 3D formé de collines.
    - Je me déplace dans cette univers, et je positionne ma hauteur en fonction du niveau de gris du point sur lequel je suis.
    - Chaque point de mon image heightmap représente un carré, en fait 2 triangles (B, C, D et A, B, D)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    A       B
     .____.
     |   /|
     |  / |
     | /  |
     ./___.
    D       C
    J'affiche une texture dans ces 2 triangles.
    Cependant il me reste un problème, j'aimerai orienter la camera vers le haut ou vers le bas suivant que je monte ou descend d'une colline.
    Je dispose de l'angle, de la position X et Y et de la hauteur des point A, B, C et D.
    Hors si je suis dans ce cas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    	   a 0° b
         .____.____.
         |   /|    |
    270° |  / |    | 90°
         | /  | \  |
         ./___.__X_.c
         |   d|    |
         |    |    |
         |    |    |
         .____.____.
               180°
    Je suis représenté par le X, et je regarde dans la direction du \, le point a a une hauteur de 2, et b, c et d ont une hauteur de 1, je devrais donc regarder vers le haut, me dirigeant d'un point c en hauteur=1 vers un point a avec hauteur = 2.
    Comment trouver l'angle de vu bas/haut en fonction de ma position dans le carré formé par a, b, c et d ?

    Cordialement !

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 395
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 395
    Points : 5 011
    Points
    5 011
    Par défaut
    bonjour,

    tu sais ou se trouve X, et tu connais la direction D' (sans tenir compte de la pente) vers laquelle tu voudrais regarder.

    grâce à la position de X tu peux déterminer le triangle sur lequel tu te trouve, donc tu peux calculer la normale N de ce triangle.

    il ne te reste plus qu'à projeter D' sur un plan de normale N pour avoir la direction réelle en fonction de la pente, et ayant un vecteur tu peux récupérer un angle assez facilement.

    j'espère que c'est assez clair ^^

    cordialement

  3. #3
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 274
    Points : 169
    Points
    169
    Par défaut Heu...
    Bonjour,

    Tu peux me donner un exemple concret ? Genre j'ai:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    (h=1)
    A_______B (h=2)
    |      /
    | !-> /
    |    /
    |   /
    |  /
    | /
    |/
    C (h=1)
    Donc si:
    h représente la hauteur du point
    A est en x = 0, y = 1
    B est en x = 1, y = 1
    C est en x = 0, y = 0
    Je suis représenté par le ! et je regarde à 90°, le 0° étant en haut, 180° en bas.
    On va dire que je suis en x = 0.2 et y = 0.7.
    Donc la normal se serai une droite perpendiculaire au triangle qui passe par mon point (!) ? Ta direction D' c'est aussi une droite ? Qui va de mon point ! jusqu'à l'intersection avec la droite BC ?

    J'ai un peu de mal avec les maths et c'est une sacrée lacune pour faire de la 3D...

    Cordialement.

  4. #4
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 395
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 395
    Points : 5 011
    Points
    5 011
    Par défaut
    bonjour,

    donc je récapitule :
    A(0, 1, 1)
    B(1, 1, 2)
    C(0, 0, 1)

    tu voudrais regardé dans la direction D'(1, 0, 0) en tenant compte de la pente (on appellera D ce vecteur corrigé)

    ensuite oui N la normale serait la droite perpendiculaire à ton plan en n'importe quel point de celui-ci, pour la calculer, il suffit de faire le produit vectoriel entre 2 "cotés" de ton triangle, par exemple entre AB et AC.

    calculons AB et AC (vecteur) :

    AB(1, 0, 1) et en le normalisant AB(0.707, 0, 0.707) (j'écris le vecteur normalisé juste pour illustrer le calcul)
    AC(0, -1, 0) qui a déjà une norme à 1, ok

    donc ensuite le produit vectoriel, rappel le produit vectoriel (cross product) entre 2 vecteur a et b se défini tel que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    a ^ b = ( a.y*b.z - b.y*a.z, 
              a.z*b.x - b.z*a.x,
              a.x*b.y - b.x*a.y)
    donc pour nos vecteurs AB et AC cela donne :
    N = AB ^ AC = (0.7, 0, -0.7)

    N est un vecteur normal, il ne montre pas forcément le "haut" du triangle, mais pour nous la normale suffit.


    donc ensuite je parlais de projection sur un plan de normale N, voici la formule (http://www.jdotec.net/s3i/Mecanique/...on_vecteur.php) :

    D = N ^ (D' ^ N) = (0.707, 0, 0.707) après normalisation du résultat, et donc ça c'est le vecteur de la direction vers laquelle tu regarde en tenant compte de la pente.

    ne sachant pas trop comment sont les angles que tu voudrais je m'arrèterai ici, mais tout est là pour calculer ce dont tu as besoin.

  5. #5
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 274
    Points : 169
    Points
    169
    Par défaut Alors ce que je trouve...
    Re,

    Donc j'ai fais ce bout de code:

    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
    	struct Point {
    		float x;
    		float y;
    		float z;
    	};
    	struct Point pointA;
    	struct Point pointB;
    	struct Point pointC;
     
    	struct Vecteur {
    		float x;
    		float y;
    		float z;
    	};
    	struct Vecteur vecteurAB;
    	struct Vecteur vecteurAC;
     
    	struct Normale {
    		float x;
    		float y;
    		float z;
    	};
    	struct Normale normale;
     
    	struct Direction {
    		float x;
    		float y;
    		float z;
    	};
    	struct Direction direction;
     
    	float magnitude;
     
    	// A(0, 1, 1)
    	pointA.x = 0.0f;
    	pointA.y = 1.0f;
    	pointA.z = 1.0f;	// hauteur
     
    	// B(1, 1, 2)
    	pointB.x = 1.0f;
    	pointB.y = 1.0f;
    	pointB.z = 2.0f;
     
    	// C(0, 0, 1)
    	pointC.x = 0.0f;
    	pointC.y = 0.0f;
    	pointC.z = 1.0f;
     
    	// Y
    	// ^
    	// |  ->
    	// |
    	// _______>X
    	direction.x = 1.0f;
    	direction.y = 0.0f;
    	direction.z = 0.0f;
     
    	vecteurAB.x = pointB.x - pointA.x;
    	vecteurAB.y = pointB.y - pointA.y;
    	vecteurAB.z = pointB.z - pointA.z;
     
    	printf ( "vecteurAB x=%f, y=%f, z=%f\n", vecteurAB.x, vecteurAB.y, vecteurAB.z );
     
    	vecteurAC.x = pointC.x - pointA.x;
    	vecteurAC.y = pointC.y - pointA.y;
    	vecteurAC.z = pointC.z - pointA.z;
     
    	printf ( "vecteurAC x=%f, y=%f, z=%f\n", vecteurAC.x, vecteurAC.y, vecteurAC.z );
     
    	// Calcul de la normale
     
    	normale.x = ( vecteurAB.y * vecteurAC.z ) - ( vecteurAB.z * vecteurAC.y );
    	normale.y = ( vecteurAB.z * vecteurAC.x ) - ( vecteurAB.x * vecteurAC.z );
    	normale.z = ( vecteurAB.x * vecteurAC.y ) - ( vecteurAB.y * vecteurAC.x );
     
    	printf ( "Normale x=%f, y=%f, z=%f\n", normale.x, normale.y, normale.z );
     
    	// Normalisation du vecteur ( Norme = 1 ) ???
    	magnitude = sqrt ( normale.x * normale.x + normale.y * normale.y + normale.z * normale.z );
    	normale.x /= magnitude;
    	normale.y /= magnitude;
    	normale.z /= magnitude;
     
    	printf ( "Normale normalise x=%f, y=%f, z=%f\n", normale.x, normale.y, normale.z );
    Qui me donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    vecteurAB x=1.000000, y=0.000000, z=1.000000
    vecteurAC x=0.000000, y=-1.000000, z=0.000000
    Normale x=1.000000, y=0.000000, z=-1.000000
    Normale normalise x=0.707107, y=0.000000, z=-0.707107
    Donc je trouve la même normale que toi, au passage ça consiste en quoi de "normaliser " ?

    C'est après je ne vois pas trop comment faire la projection, car tu écris:

    D = N ^ (D' ^ N)

    Mais D on le connait, c'est la direction, et N aussi c'est la normale, donc on cherche quoi ?

    J'aurais besoin d'une variable variant entre -90 et +90 en fonction de l'angle de vu, 0 étant l'horizontale.

    Merci beaucoup pour ton aide !

    Cordialement.

  6. #6
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 395
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 395
    Points : 5 011
    Points
    5 011
    Par défaut
    attention !!! (surement mes notations confuses)

    D' : vecteur direction du regard ne prenant pas en compte la pente
    D : vecteur direction du regard prenant en compte la pente, c'est celui là que l'on cherche à déterminer !!

    normaliser ça sert à ce que la norme (longueur) du vecteur soit égale à 1

    à quoi ça sert?
    en fait les formules du produit scalaire et du produit vectoriel donnent respectivement le cosinus et le sinus entre les 2 vecteurs d'entrée si ceux ci sont normalisés.
    de plus c'est une bonne habitude de normaliser les vecteurs car nombreuses sont les opérations nécessitant des vecteurs normalisés.

    ensuite tu veux un angle pour la verticale de la caméra entre -90 et +90, 0 étant l'horizontale, le +90 tu le veux pour la direction positive de l'axe?
    (un dessin serait plus clair pour savoir ce que tu veux)

    concernant ton code, juste une remarque, la normale et la direction sont tous les 2 des vecteurs, faire des types différents n'est, à mon avis, pas du tout conseillé.
    (pareil, différencier point et vecteur fait juste écrire du code en plus, mais ça se défend point de vue définition)

  7. #7
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 274
    Points : 169
    Points
    169
    Par défaut Autant pour moi
    Re,

    Oui j'avais pas vu qu'il n'y avait pas le ' au D

    En fait je fais un jeu en openGL dans lequel tu conduis un vélo. J'utilise une heightmap pour générer le terrain, qui est fait de triangles.

    Le but étant que quand je roule, suivant que je sois sur une montée ou une descente, la camera regarde vers le haut ou vers le bas.

    Comme mon terrain est généré à partir de triangle, je souhaite obtenir une variable qui représente mon angle de vu:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
              ___
             /   \
    --     !/
      \    /
       \--/
    Admettons que je sous le !, et que je monte, je voudrais qu'il me trouve l'angle de vu pour regarder vers le haut de la colline. Sachant que pour l'instant mon angle de vu est toujours à 0, ce qui correspond à un regard à l'horizontale, comme ce qu'il doit y avoir si je suis sur la partie plate en haut de la colline (représenté par des _).

    Par contre je dispose d'un angle de vu gauche-droite en degrés, c'est à dire qu'il me faut convertir un angle entre 0 et 360° en vecteur D, aurait-tu une idée ? Je pense qu'il me faut jouer avec les cos, sin ou tan mais je n'ai pas la formule en tête.

    Sinon, autre petites question comme tu as l'air de t'y connaitre en géométrie, soit deux triangles:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    A____B
    | . /|
    |  / |
    | /  |
    |/___|
    D    C
    Et un point situé dans l'un deux.
    Je connais les coordonnées du point, et celle de A, B, C et D, comment je fais pour savoir dans quel triangle se trouve le point ? Avec un carré c'est simple mais je ne voit pas avec deux triangles.

    Merci encore de ton aide !

    Cordialement.

  8. #8
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 395
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 395
    Points : 5 011
    Points
    5 011
    Par défaut
    pour avoir un angle à partir d'un vecteur donc on part de D la direction du regard dépendant de la pente (vecteur normalisé !!), le vecteur haut (par exemple prenons z) et on fait un produit scalaire entre les 2, le résultat de ce produit scalaire est le cosinus de l'angle a entre z et D :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        z        D
        |      /
        |     /
        |  a /
        |__ /
        |  /
        |/________________ plan horizontal

    ensuite si tu as un angle b et que tu veux un vecteur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        y     D (vu de dessus)
        |     /
        |    /
        |   /
        |  /\
        | / | b
        |/__|____________x
    x = cos(b)
    y = sin(b)


    ensuite pour savoir quel triangle dans le lequel tu te trouve, j'ai pas trop d'idée sur comment faire efficacement ça, si tu sais dans quel carré tu es, tu testes les 2 triangles mais sinon je sais pas trop désolé

  9. #9
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 274
    Points : 169
    Points
    169
    Par défaut Je vais tester tout ca.
    Bonjour,

    Bon pour savoir dans quel triangle se trouve un point, j'ai trouvé des éléments de réponse sur http://www.developpez.net/forums/d36...ieur-triangle/

    Je vais essayé de faire une fonction qui à partir des coordonnées d'un carré formé de 2 triangles me sort l'angle de vu haut/bas de l'utilisateur.

    Merci pour ton aide très précieuse

    Cordialement.

  10. #10
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 274
    Points : 169
    Points
    169
    Par défaut Bout de code
    Bonjour,

    Voici une fonction pour déterminer, à partir des 4 cotés d'un carré, l'angle de vue vertical.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       -Y 270°
          ^  -X
          | /_/_/         B___C
          |/ / /          |  /|
    0° -------> -Z 180°   |G/D|
         /|	               |/__|
        / |               A   D
      X   90°
    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
    #include <stdio.h>
    #include <cmath>
     
    #define PRECISION 1
     
    float angle2vue( float positionX, float positionZ, float hauteurPointA, float hauteurPointB, float hauteurPointC, float hauteurPointD, float angle )
    {
    	struct Point2D {
    		float x;
    		float y;
    	};
    	struct Point {
    		float x;
    		float y;
    		float z;
    	};
     
    	struct Point2D p1;
    	struct Point2D p2;
    	float temp;
    	unsigned char coteTriangle;
    	struct Point pointA;
    	struct Point pointB;
    	struct Point pointC;
    	struct Point direction;
    	struct Point vecteurAB;
    	struct Point vecteurAC;
    	struct Point normale;
    	float magnitude;
    	struct Point tempo;
    	struct Point _direction;
     
    	// Ramener la position sur un carre de PRECISION de cote
     
    	positionX = positionX-(((int)positionX/PRECISION)*PRECISION);
    	positionZ = positionZ-(((int)positionZ/PRECISION)*PRECISION);
     
    	// Teste si point est : à Gauche|Sur| à Droite de la droite (p1p2).
    	// La droite va de 0-0 vers PRECISION-PRECISION
     
    	p1.x = 0;
    	p1.y = 0;
    	p2.x = PRECISION;
    	p2.y = PRECISION;
    	temp = (p2.x - p1.x) * (positionZ - p1.y) - (positionX - p1.x) * (p2.y - p1.y);
    	if ( temp >= 0 )	// Point a gauche ou sur la droite p1-p2
    		coteTriangle = 'D';
    	else
    		coteTriangle = 'G';
     
    	printf ( "Point x=%f, z=%f triangle: %c\n", positionX, positionZ, coteTriangle );
     
    	// On fixe les 3 points du triangle
    	pointA.x = 0.0f;
    	pointA.y = hauteurPointA;
    	pointA.z = 0.0f;
     
    	pointC.x = PRECISION;
    	pointC.y = hauteurPointC;
    	pointC.z = PRECISION;
     
    	if ( coteTriangle == 'D' )	// Triangle de droite
    	{
    		// Point D
    		pointB.x = 0.0f;
    		pointB.y = hauteurPointD;
    		pointB.z = 1.0f;
    	}
    	else						// Ou celui de gauche
    	{
    		pointB.x = 1.0f;
    		pointB.y = hauteurPointB;
    		pointB.z = 0.0f;
    	}
     
    	// Converssion en radian
    	angle *= 0.017453292519943295769236907684886f;
     
    	// Le direction regarde est sur le plan X-Z
    	direction.x = sin(angle);
    	direction.y = 0.0f;
    	direction.z = cos(angle);
     
    	printf ( "Direction x=%f, y=%f, z=%f\n", direction.x, direction.y, direction.z );
     
    	// Creation de 2 vecteurs
     
    	vecteurAB.x = pointB.x - pointA.x;
    	vecteurAB.y = pointB.y - pointA.y;
    	vecteurAB.z = pointB.z - pointA.z;
     
    	// printf ( "vecteurAB x=%f, y=%f, z=%f\n", vecteurAB.x, vecteurAB.y, vecteurAB.z );
     
    	vecteurAC.x = pointC.x - pointA.x;
    	vecteurAC.y = pointC.y - pointA.y;
    	vecteurAC.z = pointC.z - pointA.z;
     
    	// printf ( "vecteurAC x=%f, y=%f, z=%f\n", vecteurAC.x, vecteurAC.y, vecteurAC.z );
     
    	// Calcul de la normale ( vecteurAB ^ vecteurAC )
    	normale.x = ( vecteurAB.y * vecteurAC.z ) - ( vecteurAB.z * vecteurAC.y );
    	normale.y = ( vecteurAB.z * vecteurAC.x ) - ( vecteurAB.x * vecteurAC.z );
    	normale.z = ( vecteurAB.x * vecteurAC.y ) - ( vecteurAB.y * vecteurAC.x );
     
    	// printf ( "Normale x=%f, y=%f, z=%f\n", normale.x, normale.y, normale.z );
     
    	// Normalisation du vecteur ( Norme = 1 )
    	magnitude = sqrt ( normale.x * normale.x + normale.y * normale.y + normale.z * normale.z );
    	normale.x /= magnitude;
    	normale.y /= magnitude;
    	normale.z /= magnitude;
     
    	// printf ( "Normale normalise x=%f, y=%f, z=%f\n", normale.x, normale.y, normale.z );
     
    	// D = N ^ (D' ^ N)
    	// tempo = (D' ^ N)
    	tempo.x = ( direction.y * normale.z ) - ( direction.z * normale.y );
    	tempo.y = ( direction.z * normale.x ) - ( direction.x * normale.z );
    	tempo.z = ( direction.x * normale.y ) - ( direction.y * normale.x );
    	// D = N ^ tempo
    	_direction.x = ( normale.y * tempo.z ) - ( normale.z * tempo.y );
    	_direction.y = ( normale.z * tempo.x ) - ( normale.x * tempo.z );
    	_direction.z = ( normale.x * tempo.y ) - ( normale.y * tempo.x );
     
    	printf ( "Vecteur prenant en compte la pente x=%f, y=%f, z=%f\n", _direction.x, _direction.y, _direction.z );
     
    	angle = _direction.y*90;
    	return( angle );
    }
     
    int main()
    {
    	float positionX = 5.5f;
    	float positionZ = 0.25f;
    	float hauteurP1 = 2.0f;
    	float hauteurP2 = 2.0f;
    	float hauteurP3 = 1.0f;
    	float hauteurP4 = 1.0f;
    	printf ( "  0 : %f\n", angle2vue( positionX, positionZ, hauteurP1, hauteurP2, hauteurP3, hauteurP4, 0   ) );
    	printf ( "________________________________________________________________________________\n" );
    	printf ( " 90 : %f\n", angle2vue( positionX, positionZ, hauteurP1, hauteurP2, hauteurP3, hauteurP4, 90  ) );
    	printf ( "________________________________________________________________________________\n" );
    	printf ( "180 : %f\n", angle2vue( positionX, positionZ, hauteurP1, hauteurP2, hauteurP3, hauteurP4, 180 ) );
    	printf ( "________________________________________________________________________________\n" );
    	printf ( "270 : %f\n", angle2vue( positionX, positionZ, hauteurP1, hauteurP2, hauteurP3, hauteurP4, 270 ) );
    	getchar(); 
    	return 0;
    }
    J'espère ne pas avoir fait d'erreur.

    Cordialement.

  11. #11
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 395
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 395
    Points : 5 011
    Points
    5 011
    Par défaut
    bonjour,

    ton code en l'état est difficilement réutilisable, il faut faire une fonction pour le produit vectoriel, scalaire ainsi que pour la normalisation d'un vecteur, ça améliorera la lisibilité de ton code ainsi que sa réutilisation.

    tu écris ça à la fin de ta première fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    angle = _direction.y*90;
    c'est faux, pour avoir l'angle, il faut utiliser le produit scalaire de la direction normalisée avec la direction verticale, ce qui te donne le cosinus de l'angle que tu cherche.

    dès que j'aurai quelques minutes supplémentaires je posterai un code.

  12. #12
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 274
    Points : 169
    Points
    169
    Par défaut Oui mais...
    Re bonjour,

    Oui OK mon code est uniquement fait pour mon besoin, d'où le manque de découpage. Pour le *90, en fait après plusieurs tests, en faisant un carre avec comme hauteur 1, 1, 2, 2, c'est à dire avec une pente de 45°, j'obtiens dans _direction.y 0.5 et -0.5 pour deux coté opposé (90° et 270° par exemple, suivant ou je regarde) et 0 pour les 2 autres cotés (0° et 180°), j'en ai donc déduit qu'en multipliant par 90 j'obtiendrais un angle en degrés, ou peut-être pas un angle mais une valeur représentative de l'angle de vue.
    Je n'ai besoin que d'un angle de vue vertical, donc en utilisant que le y du vecteur j'en ai assez ? le x-z représentant le plan. Et en tenant compte que je suis toujours vertical par rapport au plan.

    Cordialement.

  13. #13
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 395
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 395
    Points : 5 011
    Points
    5 011
    Par défaut
    le fait que tu obtiennes 45° est juste une incroyable coïncidence, le *90 ne représente rien de mathématique.
    ça marche peut être quand tu as 1, 1, 2 et 2 mais j'ai testé quand on prend 1, 1, 1.5 et 1.5 et on a une différence de 10° entre ta méthode et celle que je te propose.

  14. #14
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 274
    Points : 169
    Points
    169
    Par défaut Produit scalaire
    Bonjour,

    Effectivement, c'était une coïncidence. Donc je doit faire un produit scalaire entre la normal, qui est perpendiculaire au plan, et le vecteur résultat _direction qui prend en compte l'angle de vue, ou alors de ce même vecteur avec direction, vecteur parallele au plan si je ne me trompe pas. Je doit donc faire:

    ( normal = axe X, plan = axe Z )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
               | xd |          | xn |
    _direction | yd | X normal | yn | = ( xd * xn ) + ( yd * yn ) + ( zd * zn )
               | zd |          | zn |
    Dans ce cas j'aurais le cosinus de l'angle a (Axe Z = plan horizontale)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ^ X
    |   
    |a /<-vecteur _direction
    |-/
    |/________> Z
    ou

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
               | xd |             | x |
    _direction | yd | X direction | y | = ( xd * x ) + ( yd * y ) + ( zd * z )
               | zd |             | z |
    Et la j'aurais l'angle b

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ^ X
    |   
    |  /
    | /_b
    |/_|_______> Z
    Ensuite, que fais-je de ce nombre ? Est-il représentatif de l'angle ? Est-ce le cosinus de l'angle recherché ? Dans ce cas un acos de ce nombre me donnera l'angle ?

    Cordialement.

  15. #15
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 395
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 395
    Points : 5 011
    Points
    5 011
    Par défaut
    alors personnellement le premier truc qui m'ait venu à l'esprit c'est le produit scalaire entre ta direction tenant compte de la pente et un vecteur représentant l'axe verticale de ton monde, par exemple (0, 1, 0) comme sur mon dessin joint et ainsi obtenir le cosinus de l'angle en rouge, et tu n'auras plus qu'à faire un acos dessus (attention ça donne un angle en radian la fonction en c)
    Images attachées Images attachées  

  16. #16
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 274
    Points : 169
    Points
    169
    Par défaut Mais z'alors...
    Bonjour,

    Si je prend comme référence l'axe Y, en 0,1,0 l'angle est égal à _direction.y (avec _direction = vecteur tenant compte de la pente ) car:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
         | Xy |             | Xd |
    AxeY | Yy | X direction | Yd | = ( Xy * Xd ) + ( Yy * Yd ) + ( Zy * Zd )
         | Zy |             | Zd |
    Donc si AxeY est en 0,1,0 on obtient

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ( 0 * Xd ) + ( 1 * Yd ) + ( 0 * Zd ) = Yd
    Et le:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    angle = _direction.y*90;
    Si on ne tient pas compte du *90 est un nombre représentatif de l'angle, non ?
    Un acos de ce nombre me donnerai l'angle en radian ?

    Je joint l'univers 3D formé de carré eux même formé de triangle (rouge et bleu) pour lequel je cherche l'angle de vue:



    Cordialement.

  17. #17
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 274
    Points : 169
    Points
    169
    Par défaut Erratum
    Re,

    Non je ne suis pas daltonien, les triangles sont rouge et vert, pas rouge et bleu

    Cordialement.

  18. #18
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 395
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 395
    Points : 5 011
    Points
    5 011
    Par défaut
    Citation Envoyé par Lovmy Voir le message
    Et le:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    angle = _direction.y*90;
    Si on ne tient pas compte du *90 est un nombre représentatif de l'angle, non ?
    Un acos de ce nombre me donnerai l'angle en radian ?
    oui, mais toujours en ayant normalisé ton vecteur ^^

  19. #19
    Membre habitué
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 274
    Points : 169
    Points
    169
    Par défaut Normalisation
    Re,

    Normaliser un vecteur (0, 1, 0) me donne ce même vecteur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    plan.x = 0.0f;
    plan.y = 1.0f;
    plan.z = 0.0f;
     
    magnitude = sqrt ( plan.x * plan.x + plan.y * plan.y + plan.z * plan.z );
     
    plan.x /= magnitude;
    plan.y /= magnitude;
    plan.z /= magnitude;
    Je n'ai donc que _direction à normaliser avant d'effectuer le produit scalaire ?

    Cordialement.

  20. #20
    Expert confirmé

    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 395
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 395
    Points : 5 011
    Points
    5 011
    Par défaut
    oui le vecteur direction, j'ai pas précisé XD

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Réalité augmentée - Calculer l'angle de vue
    Par baton dans le forum Moteurs 3D
    Réponses: 2
    Dernier message: 04/05/2012, 19h17
  2. Calcul de l'angle entre trois points en fonction du sens
    Par NeraOne dans le forum Mathématiques
    Réponses: 4
    Dernier message: 10/07/2007, 18h27
  3. Effet d'ombre haut, bas, droite et gauche
    Par kaiser59 dans le forum Imagerie
    Réponses: 2
    Dernier message: 15/03/2007, 13h59
  4. calcul de l'angle dièdre
    Par hamoudasafira dans le forum Mathématiques
    Réponses: 12
    Dernier message: 21/02/2007, 18h00
  5. Calcul d'un angle
    Par adrien954 dans le forum C++Builder
    Réponses: 2
    Dernier message: 05/09/2006, 16h08

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