Calculer l'angle entre deux lignes sans avoir à calculer la pente? (Java)

j'ai deux lignes: L1 et L2. Je veux calculer l'angle entre les deux lignes. L1 a des points:<!-Et L2 a des points:{(x3, y3), (x4, y4)}.

Comment puis-je calculer l'angle formé entre ces deux lignes, sans avoir à calculer les pentes? Le problème que j'ai actuellement est que parfois j'ai des lignes horizontales (des lignes le long de l'axe des x) et la formule suivante échoue (diviser par zéro exception):

arctan((m1 - m2) / (1 - (m1 * m2)))

m1 et m2 sont les pentes de ligne 1 et ligne 2 respectivement. Est-il une formule/algorithme qui peut calculer les angles entre les deux lignes sans jamais se diviser par zéro exceptions? Toute aide serait très appréciée.

Voici mon extrait de code:

// Calculates the angle formed between two lines
public static double angleBetween2Lines(Line2D line1, Line2D line2)
{
    double slope1 = line1.getY1() - line1.getY2() / line1.getX1() - line1.getX2();
    double slope2 = line2.getY1() - line2.getY2() / line2.getX1() - line2.getX2();
    double angle = Math.atan((slope1 - slope2) / (1 - (slope1 * slope2)));
    return angle;
}

Merci.

33
demandé sur Hannele 2010-07-29 21:06:14

7 réponses

atan2 function soulage la douleur de traiter avec atan.

Il est déclaré comme double atan2(double y, double x) et convertit les coordonnées rectangulaires (x,y) à l'angle theta coordonnées polaires (r,theta)

alors je réécrirais votre code comme

public static double angleBetween2Lines(Line2D line1, Line2D line2)
{
    double angle1 = Math.atan2(line1.getY1() - line1.getY2(),
                               line1.getX1() - line1.getX2());
    double angle2 = Math.atan2(line2.getY1() - line2.getY2(),
                               line2.getX1() - line2.getX2());
    return angle1-angle2;
}
95
répondu brainjam 2015-07-01 14:24:20

produit scalaire est probablement plus utile dans ce cas. Ici vous pouvez trouver un paquet de géométrie pour Java qui fournit quelques aides utiles. Voici leur calcul pour déterminer l'angle entre deux points 3D. Nous espérons qu'il vous permettra de commencer:

public static double computeAngle (double[] p0, double[] p1, double[] p2)
{
  double[] v0 = Geometry.createVector (p0, p1);
  double[] v1 = Geometry.createVector (p0, p2);

  double dotProduct = Geometry.computeDotProduct (v0, v1);

  double length1 = Geometry.length (v0);
  double length2 = Geometry.length (v1);

  double denominator = length1 * length2;

  double product = denominator != 0.0 ? dotProduct / denominator : 0.0;

  double angle = Math.acos (product);

  return angle;
}

Bonne chance!

13
répondu Joseph Weissman 2010-07-29 17:16:18
dx1 = x2-x1;
dy1 = y2-y1;
dx2 = x4-x3;
dy2 = y4-y3;

d = dx1*dx2 + dy1*dy2;   // dot product of the 2 vectors
l2 = (dx1*dx1+dy1*dy1)*(dx2*dx2+dy2*dy2) // product of the squared lengths

angle = acos(d/sqrt(l2));

Le produit de points de 2 vecteurs est égal au cosinus du temps d'angle la longueur des deux vecteurs. Ce calcule le produit scalaire, divise par la longueur des vecteurs et utilise la fonction cosinus inverse pour récupérer l'angle.

10
répondu phkahler 2010-07-29 20:16:18

peut-être que mon approche pour le système de coordonnées Android sera utile pour quelqu'un (a utilisé la classe Android PointF pour stocker des points)

/**
 * Calculate angle between two lines with two given points
 *
 * @param A1 First point first line
 * @param A2 Second point first line
 * @param B1 First point second line
 * @param B2 Second point second line
 * @return Angle between two lines in degrees
 */

public static float angleBetween2Lines(PointF A1, PointF A2, PointF B1, PointF B2) {
    float angle1 = (float) Math.atan2(A2.y - A1.y, A1.x - A2.x);
    float angle2 = (float) Math.atan2(B2.y - B1.y, B1.x - B2.x);
    float calculatedAngle = (float) Math.toDegrees(angle1 - angle2);
    if (calculatedAngle < 0) calculatedAngle += 360;
    return calculatedAngle;
}

il renvoie une valeur positive en degrés pour n'importe quel quadrant: 0 <= x < 360

Vous pouvez visiter mon classe utilitaire ici

6
répondu Dehimb 2017-02-22 21:42:21

La formule pour obtenir l'angle est tan a = (slope1-slope2)/(1+slope1*slope2)

Vous utilisez:

tan a = (slope1 - slope2) / (1 - slope1 * slope2)

Donc il devrait être:

double angle = Math.atan((slope1 - slope2) / (1 + slope1 * slope2));
3
répondu AliveStar 2016-09-19 21:02:23

tout d'Abord, êtes-vous sûr que les crochets sont dans le bon ordre? Je pense (peut être à tort) qu'il doit être ceci:

   double slope1 = (line1.getY1() - line1.getY2()) / (line1.getX1() - line1.getX2());
   double slope2 = (line2.getY1() - line2.getY2()) / (line2.getX1() - line2.getX2());

deuxièmement, il y a deux choses que vous pourriez faire pour la div par zéro: vous pourriez attraper l'exception et la gérer

double angle;
try
{
    angle = Math.atan((slope1 - slope2) / (1 - (slope1 * slope2)));
catch (DivideByZeroException dbze)
{
    //Do something about it!
}

...ou vous pouvez vérifier que votre diviseurs sont jamais zéro avant vous tentez l'opération.

if ((1 - (slope1 * slope2))==0)
{
    return /*something meaningful to avoid the div by zero*/
}
else 
{
    double angle = Math.atan((slope1 - slope2) / (1 - (slope1 * slope2)));
    return angle;
 }
0
répondu FrustratedWithFormsDesigner 2010-07-29 17:11:45

Vérifier ce code Python:

import math
def angle(x1,y1,x2,y2,x3,y3):

  if (x1==x2==x3 or y1==y2==y3):
    return 180
  else:
    dx1 = x2-x1
    dy1 = y2-y1
    dx2 = x3-x2
    dy2 = y3-y2
    if x1==x2:
      a1=90
    else:
      m1=dy1/dx1
      a1=math.degrees(math.atan(m1))
    if x2==x3:
      a2=90
    else:
      m2=dy2/dx2
      a2=math.degrees(math.atan(m2))
    angle = abs(a2-a1)
    return angle

print angle(0,4,0,0,9,-6)
0
répondu Tirtha Chetry 2018-05-29 10:05:22