Partage
  • Partager sur Facebook
  • Partager sur Twitter

Angle entre un vecteur et un point dans l'espace

Sujet résolu
29 décembre 2016 à 1:35:33

Bonjour / Bonsoir,

cela fait déjà quelques mois que je me demande comment calculer l'angle entre un vecteur et un point dans un espace 2d (voir image).

Le vecteur est donc la direction dans laquelle se dirige un objet (ici une voiture), et je cherche à connaître l'angle que doit avoir la voiture pour rejoindre un point quelconque.

Je souhaite appliquer cela à de petits jeux 2D, j'ai donc trouvé comment diriger un objet dans une direction suivant les axes x et y (peut-être que cela peut vous aider à trouver la formule mathématique que je cherche) :

this.x += this.speed * Math.cos(angle * Math.PI / 180);
this.y += this.speed * Math.sin(angle * Math.PI / 180);

Mais pour cela, il faut avoir l'angle.

Merci d'avance.

  • Partager sur Facebook
  • Partager sur Twitter
Mon CV/portfolio : adrien.lucbert.com
29 décembre 2016 à 9:41:51

Yo!

Je peux te proposer cette méthode : (COURS ICI)

Je ne sais pas si c'est la plus rapide ou la plus efficace, ou celle utilisée en générale,

Mais en considérant les vecteurs Voiture-Objectif(VO) et le vecteur direction(D),

||VO^D|| = ||VO||.||D||.sin(Theta) (avec theta ton angle),

donc apres il suffit de faire angle = asin(Theta)? Je pense que ça marche, mais d'autres confirmeront (et me taperont peut-être sur les doigts?)

REEDIT :
Il y a sans doute plus facile selon le lien que j'ai mis (c'était un autre cours que j'ai mis avant :)

Si tu travailles en 2D, ce qui semble être le cas,

angle = acos( dotproduct(VO, D))...

-
Edité par KirbXCoucou 29 décembre 2016 à 11:20:25

  • Partager sur Facebook
  • Partager sur Twitter

« Je n’ai pas besoin de preuve. Les lois de la nature, contrairement aux lois de la grammaire, ne permettent aucune exception. »
D. Mendeleïev

29 décembre 2016 à 10:59:30

Juste pour un peu de 'rigueur', tu parles d'angle entre un vecteur et un point... ce qui n'a pas vraiment de sens.  

Mais si on se réfère à ton dessin, tu as un point A (l'automobile), un point O (l'Objectif) et ce que tu cherches, c'est l'angle entre le vecteur D (Direction) et le vecteur AO ; et un angle entre 2 vecteurs, ça a un sens.

  • Partager sur Facebook
  • Partager sur Twitter
29 décembre 2016 à 12:01:06

Tu n'as pas besoin de l'angle mais de leur cosinus et sinus. Et ça, c'est encore plus simple à calculer (pas besoin d'arc sinus et arc cosinus ou de conversion pi/180).

Ici il y a deux vecteurs, mettons que je les note u et v (par exemple u est le vecteur D, v est le vecteur AO, pour reprendre la notation de tbc92). On a :

\[ \cos(u,v) = \frac{u \cdot v}{ \|u\| \|v\| } \]

Le produit scalaire \( u \cdot v \) est facile à calculer avec les coordonnées (c'est x.x' + y.y').

\[ \sin(u,v) = \frac{u \wedge v}{ \|u\| \|v\| } \]

et là encore, le produit vectoriel se calcule à l'aide des coordonnées (un poil plus compliqué).

Bon, KirbXCoucou l'avait déjà dit, mais j'interviens surtout pour insister : on n'a pas besoin de l'angle, juste du cosinus et du sinus, donc des deux expressions à droite du signe égal.

-
Edité par robun 29 décembre 2016 à 12:03:35

  • Partager sur Facebook
  • Partager sur Twitter
29 décembre 2016 à 15:19:32

Merci à tous!

J'ai travaillé sur la question depuis ce matin, avec ce que vous m'avez dit, et j'ai enfin réussi!

Je suis passé par trois fonctions différentes, car les 2 premières avaient un problème, elles donnaient à chaque fois un angle positif, et ne pouvaient jamais donner d'angle négatif, ce qui est normal puisqu'on calculait les longueurs avec des sqrt et des carré, donc c'était positif...

Voici donc les différentes fonctions. C'est en JavaScript, mais je n'utilise que des fonctions mathématiques, donc si vous avez les bases en algo, vous devriez comprendre facilement :

function angle(A,C) {
    var B = [C[0],A[1]];
    // on détermine le point B du triangle rectangle ABC (en supposant qu'il a la même abscisse que A et la même ordonnée que C : c'est déjà une erreur)
    var AB = Math.sqrt(Math.pow((A[0]-B[0]),2)+Math.pow((A[1]-B[1]),2));
    var BC = Math.sqrt(Math.pow((B[0]-C[0]),2)+Math.pow((B[1]-C[1]),2));
    // calcul des distances AB et BC, qui sont ici forcément positives...
    var rad = Math.atan2(BC,AB);
    var deg = rad*(180/Math.PI);
    return deg;
}

Vous voyez donc déjà la grosse erreur de déterminer B, on suppose qu'on a toujours une direction horizontale pour AB, ce qui n'est pas toujours le cas...

function angle(A,B,C) {
    // 3 paramètres : A, B et C, c'est déjà mieux
    var AB = [
        B[0]-A[0],
        B[1]-A[1]
    ];
    // définition du vecteur AB
    var AC = [
        C[0]-A[0],
        C[1]-A[1]
    ];
    // définition du vecteur AC
    var prod_scal = AB[0]*AC[0]+AB[1]*AC[1];
    // calcul du produit scalaire
    var AB_L = Math.sqrt(Math.pow(AB[0],2)+Math.pow(AB[1],2));
    // norme du vecteur AB
    var AC_L = Math.sqrt(Math.pow(AC[0],2)+Math.pow(AC[1],2));
    // norme du vecteur AC
    // encore une fois, les normes ne peuvent pas être négatives, donc on se retrouve avec le même problème...
    var rad = Math.acos(prod_scal/(AB_L*AC_L));
    var deg = rad*(180/Math.PI);
    return deg;
}

Donc même problème, la valeur de dégrés ne peut pas être négative.

function angle(A,B,C) {
    var AB = [
        B[0]-A[0],
        B[1]-A[1]
    ];
    var AC = [
        C[0]-A[0],
        C[1]-A[1]
    ];
    var rad = Math.atan2(AC[1],AC[0])-Math.atan2(AB[1],AB[0]);
    // solution du cours donné par KirbXCoucou : angle of 2 relative to 1= atan2(v2.y,v2.x) - atan2(v1.y,v1.x)
    var deg = rad*(180/Math.PI);
    return deg;
}

On a enfin, grâce à la formule qui se trouve dans le cours donné par KirbXCoucou, une valeur positive ou négative de degrés.

Merci à tous pour votre participation, vous m'avez tous été très utiles! :D


  • Partager sur Facebook
  • Partager sur Twitter
Mon CV/portfolio : adrien.lucbert.com
29 décembre 2016 à 15:42:49

Je t'avoue que je trouve ça bizarre que tu puisses avoir des valeurs négatives de degrés, et je trouve ça plus normal d'avoir que des valeurs positives.
Enfin, c'est pas possible d'avoir un angle de degré négatif :/

  • Partager sur Facebook
  • Partager sur Twitter

« Je n’ai pas besoin de preuve. Les lois de la nature, contrairement aux lois de la grammaire, ne permettent aucune exception. »
D. Mendeleïev

29 décembre 2016 à 16:03:32

Oui un angle négatif ça n'existe pas, mais il me fallait quand même des degrés négatifs si je voulais que le voiture aille vers le bas, sinon on avait une symétrie et la voiture ne pouvait se diriger que vers le haut... Je sais pas si tu vas bien comprendre ce que j'ai dit ^^'

Mais c'est comme si notre voiture suivait le trajet d'une sinusoïde, et qu'on appliquait une valeur absolue sur notre sinusoïde, donc la voiture ne fait que rebondir sur l'axe des abscisses, sans jamais pouvoir le dépasser pour passer dessous.. C'est à peu près ça..

Merci quand même ^^

  • Partager sur Facebook
  • Partager sur Twitter
Mon CV/portfolio : adrien.lucbert.com
29 décembre 2016 à 16:42:57

Il est normal ici d'avoir des angles entre -180° et +180°, ou entre 0° et 360°. Ce sont des angles de vecteurs, pas des angles de droite. Et c'est bien ce que donnent les formules basées sur le produit scalaire et le produit vectoriel.

Dwaaren : donc tu n'as pas suivi mon conseil d'utiliser juste le cosinus et le sinus ? C'est utile s'il y a beaucoup de calculs à effectuer, car un calcul d'arc cosinus ou d'arc sinus prend plus de temps que les opérations élémentaires.

-
Edité par robun 29 décembre 2016 à 16:43:46

  • Partager sur Facebook
  • Partager sur Twitter
29 décembre 2016 à 18:44:12

Non robun, désolé mais je n'ai pas réussi à appliquer ce que tu me disais.. J'ai galéré toute la journée pour enfin avoir un système qui marche, donc je le garde comme ça pour l'instant.. Si j'ai le temps un jour, à tête reposée, je le reprendrai.

Merci quand même car tes conseils m'ont permis de comprendre ce que d'autres m'expliquaient! :D

Il faut savoir que je ne suis qu'en Première S, et on n'a survolé la trigonométrie qu'en 3ème, et on l'a à peine survolée en une demi-douzaine d'heures... Donc j'avais à peu près tout oublié, alors ça a été un défi et à la fois une remise à niveau de comprendre ce que vous me disiez ^^

Je vous remercie tous beaucoup!! :D

PS : Si vous voulez voir le résultat avec la voiture, c'est disponible sur mon site : http://adrien.lucbert.com/games/algocar/

La voiture suit votre souris ^^

On peut donc imaginer ça avec plein d'autres objets, des missiles guidés dans des jeux de style Super Meat Boy, des acolytes ou familiers qui vous suivent dans un RPG, etc... ^^

Encore merci pour votre aide qui a permis cela !

Enjoy

-
Edité par Dwaaren 29 décembre 2016 à 19:14:47

  • Partager sur Facebook
  • Partager sur Twitter
Mon CV/portfolio : adrien.lucbert.com
30 décembre 2016 à 12:54:03

Ce que je disais était pourtant très simple ! Mais je vais essayer d'être plus clair...

Ce que tu fais : (en gros et sans tenir compte du sinus)

angle = arccos(machintruc) {car cos(angle) = machintruc}

x = speed * cos(angle)

Ce que tu devrais faire :

x = speed * machintruc

Ainsi tu économises un calcul d'arc cosinus et un calcul de cosinus, qui sont les opérations les plus coûteuses en temps.

(Mais en effet ça marche bien et c'est rigolo...) 

-
Edité par robun 30 décembre 2016 à 12:57:11

  • Partager sur Facebook
  • Partager sur Twitter
31 décembre 2016 à 15:21:44

Donc il faudrait que ma fonction angle retourne machintruc au lieu de retourner l'angle? machintruc étant le cosinus pour x et le sinus pour y?

C'est là qu'interviennent les formules que tu m'as données : 

robun a écrit:

\[ \cos(u,v) = \frac{u \cdot v}{ \|u\| \|v\| } \]

et

\[ \sin(u,v) = \frac{u \wedge v}{ \|u\| \|v\| } \]


Sauf que le produit scalaire je ne l'ai pas encore vu, mais ça va encore, alors que le produit vectoriel ne se voit pas en lycée, même en S...

Et c'est là que je bloque : d'après ce site, le produit vectoriel donne un vecteur \[u \wedge v\]. Or comment peut-on obtenir un nombre réel (sinus) avec la division d'un vecteur par un nombre?

Aussi, lorsque je tente de calculer le cosinus avec la première formule (produit scalaire), j'obtiens toujours 0 ou -0...

// en considérant
// var AB = [
//   x,
//   y
// ];
// et
// var AC = [
//   x',
//   y'
// ];

var cos = (AB[0]*AC[0]+AB[1]*AC[1])/(Math.sqrt(Math.pow(AB[0],2)+Math.pow(AB[1],2))*Math.pow(AC[0],2)+Math.pow(AC[1],2));
// cos(u,v) = ( xx'.yy' )/( sqrt(x²+y²) * sqrt(x'²+y'²) )
// cos est toujours égal à 0 ou -0



-
Edité par Dwaaren 31 décembre 2016 à 15:30:39

  • Partager sur Facebook
  • Partager sur Twitter
Mon CV/portfolio : adrien.lucbert.com
31 décembre 2016 à 15:27:47

Salut,

En fait, il faut prendre la norme du produit vectoriel et pas le produit vectoriel pour la formule du sinus.

  • Partager sur Facebook
  • Partager sur Twitter
Tutoriel Ruby - Bon tutoriel C - Tutoriel SDL 2 - Python avancé - Faîtes un zeste, devenez des zesteurs
31 décembre 2016 à 15:31:30

Merci! C'est l'idée que je venais d'avoir, je vais essayer ça.

Des idées pour le cos toujours égal à 0 ou -0?

Et le calcul pour le produit vectoriel de deux vecteurs u et v, c'est bien :

\[ u \wedge v = (yx'-xy' ; xy'-yx') \] ?

EDIT : Ok je viens de trouver.. Le sinus était aussi égal à 0... C'est parce que la norme de AB était toujours égale à 0... Je pense qu'après rectification de ce problème ça devrait mieux fonctionner ^^'

-
Edité par Dwaaren 31 décembre 2016 à 15:45:27

  • Partager sur Facebook
  • Partager sur Twitter
Mon CV/portfolio : adrien.lucbert.com
31 décembre 2016 à 16:51:35

Le produit vectoriel n'est défini qu'en dimension 3

Tes vecteurs de départ sont donc (x,y,z) et (x',y',z') avec z=0 et z'=0

Et le produit vectoriel est aussi un vecteur de dimension 3 : (yz'-y'z, zx'-z'x, xy'-x'y) 

Et comme z=0 et z'=0, ça se simplifie bien : (0,0,xy'-x'y)

Ce vecteur résultat est 'vertical' (perpendiculaire au plan de travail), mais on s'intéresse uniquement à sa norme (=|xy'-x'y|) et à sa direction (vers le haut ou le bas, selon le signe de xy'-x'y)

  • Partager sur Facebook
  • Partager sur Twitter
1 janvier 2017 à 10:46:51

Merci pour les infos!
  • Partager sur Facebook
  • Partager sur Twitter
Mon CV/portfolio : adrien.lucbert.com
18 février 2021 à 16:58:33

Dwaaren, je suis dans la même situation que toi, dans mon cas c'est un bateau et une destination, j'ai donc la position du bateau et sa direction (angle entre le bateau et l'axe des abscisses) et pour la destination j'ai que les coordonnées.

J'ai donc essayé ta 3ème fonction mais je ne vois pas comment t'as fait pour trouver les coordonnées du 3ème point (la projection).

  • Partager sur Facebook
  • Partager sur Twitter
18 février 2021 à 18:26:33

@GhadaAjimi Bonjour, merci de ne pas déterrer d'ancien sujet résolu.

Déterrage

Citation des règles générales du forum :

Avant de poster un message, vérifiez la date du sujet dans lequel vous comptiez intervenir.

Si le dernier message sur le sujet date de plus de deux mois, mieux vaut ne pas répondre.
En effet, le déterrage d'un sujet nuit au bon fonctionnement du forum, et l'informatique pouvant grandement changer en quelques mois il n'est donc que rarement pertinent de déterrer un vieux sujet.

Au lieu de déterrer un sujet il est préférable :

  • soit de contacter directement le membre voulu par messagerie privée en cliquant sur son pseudonyme pour accéder à sa page profil, puis sur le lien "Ecrire un message"
  • soit de créer un nouveau sujet décrivant votre propre contexte
  • ne pas répondre à un déterrage et le signaler à la modération

Je ferme ce sujet. En cas de désaccord, me contacter par MP.

  • Partager sur Facebook
  • Partager sur Twitter