Question

J'ai cette méthode pour comprendre la différence entre les 2 0-360 boussole en-têtes.

Bien que cela fonctionne pour déterminer dans quelle mesure absolument (comme dans, toujours de sortie positive) hors je suis, j'ai du mal à déterminer ce qui doit être fait pour introduire le signe sur la sortie.

Idéalement, si la distance la plus courte à partir de l'initiale de la tête à la finale de la rubrique est en allant dans le sens horaire, j'aimerais que la error pour avoir un signe positif, si la distance la plus courte entre les en-têtes implique d'aller autour dans le sens antihoraire, j'aimerais que la error pour avoir un signe négatif.

Quelques exemples d'entrées/sorties

initial -- final -- error

0 .................... 30 .......... 30

30 .................... 0 .......... -30

360 .................... 1 .......... 1

1 .................... 360 .......... -1

Code:

    /// <summary>
    /// Calculate the error from a given initial heading to a final heading
    /// </summary>
    /// <param name="inital"></param>
    /// <param name="final"></param>
    /// <returns></returns>
    private double GetHeadingError(double initial, double final)
    {
        double directionA = final - initial;
        double directionB = 360 - (final + initial);
        double error = 0;

        if (Math.Abs(directionA) < Math.Abs(directionB))
        {
            error = directionA;
        }
        else
        {
            error = directionB;
        }

        return error;
    }
Était-ce utile?

La solution

Éditer: Ajout de vérification du moment où la différence est exactement de 180 degrés. Auparavant, cela retournait 180 ou -180 selon que la finale était plus grande ou inférieure à l'initiale. Je l'ai modifié pour qu'il revienne positif 180 dans les deux cas.


Alors voici ma tentative ...

private static double GetHeadingError(double initial, double final)
        {
            if (initial > 360 || initial < 0 || final > 360 || final < 0)
            {
                //throw some error
            }

            var diff = final - initial;
            var absDiff = Math.Abs(diff);

            if (absDiff <= 180)
            {
                //Edit 1:27pm
                return absDiff == 180 ? absDiff : diff;
            }

            else if (final > initial)
            {
                return absDiff - 360;
            }

            else
            {
                return 360 - absDiff;
            }
        }

Autres conseils

Si je comprends correctement à la question, je pense que le code suivant devrait fonctionner:

private double GetHeadingError(double initial, double final)
{
            if(initial == 360) initial = 0;
            if(final == 360) final = 0;
            double clockWise = (final - initial);
            double counterClockWise = (360 - final + initial);
            return (Math.Abs(clockWise) <= Math.Abs(counterClockWise)) ? clockWise : -counterClockWise;
}

En gros je suis le traitement de 360 degrés la même chose que 0, je crois que c'est ok.Ce code va produire les mêmes résultats figurant dans le tableau ci-dessus.Le Code ne fait pas de vérification des limites, il s'attend à des valeurs entre 0 et 360.

Je pense que votre tableau des résultats souhaités est incorrect. Voici ma manière klunky:

private double MyGetHeadingError(double initial, double final)
{
    initial += 1000;
    final += 1000;

    bool flipped = false;
    if (initial > final)
    {
        double temp;
        temp = final;
        final = initial;
        initial = temp;
        flipped = true;
    }
    double error;
    if (final - initial > 180)
        final = final - 360;

    error = final - initial;

    if (flipped == true)
        error = -error;
    return error;
}
Degree_Diff = (MIN(ABS(ENDCOMPASS-STARTCOMPASS),ABS(360-ENDCOMPASS+STARTCOMPASS),ABS(360-STARTCOMPASS+ENDCOMPASS))) 

Voici une solution simple, bien que nommée un peu différemment et en fléchette. Basé sur Cette réponse avionique.

/// The difference of two headings in degrees such that it is always in the range
/// (-180, 180]. A negative number indicates [h2] is to the left of [h1].
double headingDiff(double h1, double h2) {
  double left = h1 - h2;
  double right = h2 - h1;
  if (left < 0) left += 360;
  if (right < 0) right += 360;
  return left < right ? -left : right;
}

Edit: il y a une réponse encore plus concise ici, mais je ne l'ai pas essayé moi-même:

double headingDiff(double h1, double h2) => (h2 - h1 + 540) % 360 - 180;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top