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)))
où 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.
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;
}
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!
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.
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
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));
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;
}
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)