11
votes

Trouvez l'angle entre deux roulements

donné à deux roulements, comment puis-je trouver le plus petit angle entre eux?

Donc, par exemple, si une position est de 340 degrés et la seconde est de 10 degrés, le plus petit angle sera de 30 degrés.

J'ai attaché une image pour montrer ce que je veux dire. J'ai essayé de soustraire l'un de l'autre mais cela n'a pas fonctionné à cause de l'effet d'un cercle. J'ai également essayé d'utiliser des degrés négatifs (180 - 359 étant -180 à 0) mais qui ont été gâchés lorsque vous essayez de calculer l'angle entre le nombre positif et négatif.

Je suis sûr qu'il doit y avoir un moyen plus facile d'avoir beaucoup de si déclarations.

Merci pour votre aide. Adam

BTW. Ceci est une question de navigation afin que le rayon du cercle est inconnu.

Trouver l'angle entre deux titres


1 commentaires

L'opérateur MOD vous aidera ici. Beaucoup.


6 Réponses :


12
votes
float getDifference(float a1, float a2) {
    return Math.min((a1-a2)<0?a1-a2+360:a1-a2, (a2-a1)<0?a2-a1+360:a2-a1)
}

3 commentaires

Merci qui a travaillé un régal. J'ai essayé de résoudre cela pendant 6 heures!


équivalent: math.min ((A1 - A2 + 360)% 360, (A2 - A1 + 360)% 360) (Utiliser FMOD , Ieremainder , etc., pour d'autres langues où % ne prend pas en charge les valeurs de point flottant.)


Génial, tu as fait ma journée.



6
votes

Quoi de:

angle = Math.abs(a1-a2);
if (angle > 180)
    angle = 360 - angle;


2 commentaires

Je crois que votre réponse est équivalente à la mienne, mais peut-être un peu plus facile à comprendre. Une autre option qui ressemble à une croix entre les deux que nous avons déjà reçues est math.min (math.abs (A1-A2), 360 - MATH.ABS (A1-A2));


Ils sont équivalents dans le sens qu'ils sont à la fois corrects et valides. À mon avis, votre implémentation traite la question comme un problème de l'exactitude de l'algorithme de l'OP, alors que je pensais à cela comme un problème de formatage d'une valeur déjà correcte. Les deux sont des moyens valides de regarder le problème et je pense qu'il y a suffisamment de différence d'approche que les deux sont de valeur.



0
votes

Vous devez envisager la différence dans les deux directions.

public static double bearingDiff(double a, double b) {
    double maxBearing = Math.max(a, b);
    double minBearing = Math.min(a, b);
    double antiClockwiseDiff = maxBearing - minBearing;
    double clockwiseDiff = minBearing + 360 - maxBearing;
    return Math.min(antiClockwiseDiff, clockwiseDiff);
}


0 commentaires

16
votes

J'ai fini par utiliser la formule suivante trouvée sur Ce tableau parce que je nécessaire le résultat doit être signé en fonction de la direction (dans le sens des aiguilles d'une montre ou dans le sens anti-horaire). Il a une bonne explication de ce qui se passe exactement. XXX


1 commentaires

L'initial % 360 est inutile si | roulement - Rubrique | <= 360 =: lié. Peut également ajouter un multiple de 360 ​​à 540 si la liaison est plus grande.



1
votes

Si la direction d'angle est nécessaire, cela fonctionnera:

    int maxBearing = Math.max(bearing0, bearing1);
    int minBearing = Math.min(bearing0, bearing1);
    int firstDir = maxBearing - minBearing;  
    int secondDir = minBearing + 360 - maxBearing;  
    int diff = Math.min(firstDir, secondDir);

    boolean anticlock_dir = false;

    int anticlock = bearing1 + diff;
    if (anticlock >= 360)
        anticlock = anticlock - 360;

    if (anticlock ==  bearing0)
        anticlock_dir = true;


0 commentaires

2
votes

Pour la navigation, vous voudrez peut-être savoir si B1 est laissé ou à droite de B2, alors c'est ici dans une belle fonction. (Suppose exactement 0 n'est pas un cas d'utilisation)

function isBearing1LeftOrRightOfBearing2 (b1, b2) {
  if (Math.sign(((b1 - b2 + 540) % 360) - 180) > 0) {
    return 'left'
  } else {
    return 'right'
  }
}


0 commentaires