52 votes

Comment calculer un angle à partir de trois points ?

Disons que vous avez ceci :

P1 = (x=2, y=50)
P2 = (x=9, y=40)
P3 = (x=5, y=20)

Supposons que P1 est le point central d'un cercle. Il est toujours le même. Je veux l'angle qui est formé par P2 y P3 ou, en d'autres termes, l'angle qui se trouve à côté de P1 . L'angle intérieur pour être précis. Il s'agira toujours d'un angle aigu, donc inférieur à -90 degrés.

J'ai pensé : Mec, c'est des maths simples de géométrie. Mais je cherche une formule depuis environ 6 heures maintenant, et je ne trouve que des gens qui parlent de trucs compliqués de la NASA comme des arccos et des trucs de produit scalaire vectoriel. J'ai l'impression que ma tête est dans un frigo.

Y a-t-il des gourous des mathématiques ici qui pensent que c'est un problème simple ? Je ne pense pas que le langage de programmation soit important ici, mais pour ceux qui le pensent : java et objective-c. J'en ai besoin pour les deux, mais je ne l'ai pas encore étiqueté pour ceux-ci.

7voto

shaman.sir Points 1056

Laissez-moi vous donner un exemple en JavaScript, je me suis beaucoup battu avec ça :

/**
 * Calculates the angle (in radians) between two vectors pointing outward from one center
 *
 * @param p0 first point
 * @param p1 second point
 * @param c center point
 */
function find_angle(p0,p1,c) {
    var p0c = Math.sqrt(Math.pow(c.x-p0.x,2)+
                        Math.pow(c.y-p0.y,2)); // p0->c (b)   
    var p1c = Math.sqrt(Math.pow(c.x-p1.x,2)+
                        Math.pow(c.y-p1.y,2)); // p1->c (a)
    var p0p1 = Math.sqrt(Math.pow(p1.x-p0.x,2)+
                         Math.pow(p1.y-p0.y,2)); // p0->p1 (c)
    return Math.acos((p1c*p1c+p0c*p0c-p0p1*p0p1)/(2*p1c*p0c));
}

Bonus : Exemple avec HTML5-canvas

6voto

En Objective-C, vous pourriez faire cela en

float xpoint = (((atan2((newPoint.x - oldPoint.x) , (newPoint.y - oldPoint.y)))*180)/M_PI) ;

Ou lire la suite ici

http://www.iphonedevsdk.com/forum/iphone-sdk-development/49847-how-find-angle-two-points.html

5voto

Marc Points 2019

J'ai rencontré un problème similaire récemment, sauf que je devais faire la différence entre un angle positif et un angle négatif. Si cela peut être utile à quelqu'un, je vous recommande le bout de code que j'ai récupéré sur cette liste de diffusion concernant la détection de la rotation sur un événement tactile pour Android : lien

 @Override
 public boolean onTouchEvent(MotionEvent e) {
    float x = e.getX();
    float y = e.getY();
    switch (e.getAction()) {
    case MotionEvent.ACTION_MOVE:
       //find an approximate angle between them.

       float dx = x-cx;
       float dy = y-cy;
       double a=Math.atan2(dy,dx);

       float dpx= mPreviousX-cx;
       float dpy= mPreviousY-cy;
       double b=Math.atan2(dpy, dpx);

       double diff  = a-b;
       this.bearing -= Math.toDegrees(diff);
       this.invalidate();
    }
    mPreviousX = x;
    mPreviousY = y;
    return true;
 }

4voto

peter.murray.rust Points 13406

Vous avez mentionné un angle signé (-90). Dans beaucoup d'applications, les angles peuvent avoir des signes (positifs et négatifs, cf. http://en.wikipedia.org/wiki/Angle ). Si les points sont (disons) P2(1,0), P1(0,0), P3(0,1), l'angle P3-P1-P2 est conventionnellement positif (PI/2) alors que l'angle P2-P1-P3 est négatif. L'utilisation des longueurs des côtés ne permet pas de faire la distinction entre + et -. Si cela est important, vous devrez utiliser des vecteurs ou une fonction telle que Math.atan2(a, b).

Les angles peuvent également s'étendre au-delà de 2*PI et bien que cela ne soit pas pertinent pour la question actuelle, c'était suffisamment important pour que j'écrive ma propre classe Angle (également pour m'assurer que les degrés et les radians ne soient pas confondus). La question de savoir si l'angle1 est inférieur à l'angle2 dépend essentiellement de la façon dont les angles sont définis. Il peut également être important de décider si une ligne (-1,0)(0,0)(1,0) est représentée par Math.PI ou -Math.PI.

1voto

antonio Points 23

enter image description here

Récemment, j'ai eu moi aussi le même problème... En Delphi est très similaire à Objective-C.

procedure TForm1.FormPaint(Sender: TObject);
var ARect: TRect;
    AWidth, AHeight: Integer;
    ABasePoint: TPoint;
    AAngle: Extended;
begin
  FCenter := Point(Width div 2, Height div 2);
  AWidth := Width div 4;
  AHeight := Height div 4;
  ABasePoint := Point(FCenter.X+AWidth, FCenter.Y);
  ARect := Rect(Point(FCenter.X - AWidth, FCenter.Y - AHeight),
    Point(FCenter.X + AWidth, FCenter.Y + AHeight));
  AAngle := ArcTan2(ClickPoint.Y-Center.Y, ClickPoint.X-Center.X) * 180 / pi;
  AngleLabel.Caption := Format('Angle is %5.2f', [AAngle]);
  Canvas.Ellipse(ARect);
  Canvas.MoveTo(FCenter.X, FCenter.Y);
  Canvas.LineTo(FClickPoint.X, FClickPoint.Y);
  Canvas.MoveTo(FCenter.X, FCenter.Y);
  Canvas.LineTo(ABasePoint.X, ABasePoint.Y);
end;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X