8
votes

Obtenez l'angle d'une ligne d'horizon

Je veux savoir comment obtenir un angle d'une ligne A-B à partir de l'axe horizontal X. Autres questions à ce que cela soit aussi entre deux lignes. Je suis au courant que je peux toujours dessiner deuxième ligne A-C et calculer mais je me demande s'il y a une méthode plus rapide.

Edit: Je suis vraiment sûr que je ne fais pas d'optimisation prématurée.


8 commentaires

Se méfier de l'optimisation prématurée. Avez-vous profilé le code?


Je ne peux pas comprendre les votes en panne. Est-ce une question idiote? ou est-il si offensant? Hmm..


@Vox - Postez vos résultats de profilage. Prouvez-vous à vous que vous avez besoin d'une solution plus rapide.


@Charlie, imaginez une situation que vous devez avoir les dizaines d'angle de milliers de fois dans un appareil mobile .NET CF, vous voudrez le rendre aussi rapide que possible.


"Vous voulez que le problème est le problème. Tout d'abord, vous devriez vouloir le faire fonctionner. Ensuite, si cela ne fonctionne pas de manière satisfaisante, vous découvrez ce qui cause le problème et le réparer.


Merci pour des commentaires quand même. Deux personnes ont déjà répondu à ma question sans discuter que je devrais poser la question ou non. Je suis assez avec leur réponse. :)


Je suis à peu près sûr que c'est une question légitime. La réponse est si simple et facile à comprendre qu'il n'y a aucune raison pas pour l'utiliser. Ce n'est pas un cas où l'optimisation prématurée rend les choses plus difficiles à comprendre ou plus compliquées. Cela simplifie réellement les choses.


Dernières fois, tout le monde m'a demandé cela, il s'est avéré que la seule chose qu'ils ait faite avec l'angle plus tard était de calcul une fonction de trigle, comme sin ou cos . Si cela est vrai dans ce cas et que vous vous souciez de la performance, il est probable que vous ne devriez pas réellement calculer l'angle. Mais il est seulement possible de faire une recommandation basée sur ce que vous avez l'intention de faire avec l'angle.


6 Réponses :


0
votes

L'axe des x est en fait une ligne avec l'équation

y = 0

Vous pouvez donc utiliser la solution que vous avez déjà.


1 commentaires

Je cherchais une méthode plus rapide (moins de CPU) s'il y en a.



12
votes

Vous pouvez utiliser Atan code> pour cela.

angle = atan((By-Ay)/(Bx-Ax))


0 commentaires

1
votes

si

  1. L'angle est petit,
  2. Vous pouvez vivre avec de petites inexactitudes et
  3. Vous pouvez utiliser l'angle dans les radians et non degrés,

    Il y a ensuite une solution rapide: dans ces conditions, vous pouvez supposer que TAN (a) = A = Atan (a), et donc omettre juste l'appel ATAN ().


4 commentaires

"Tan (a) = A = Atan (a)" Eh ... Quoi?


@Bart van Heukelom: Oui, comme je l'ai écrit, ce n'est pas exact, mais une bonne approximation pour petits angles. Par exemple. Tan (0,1) = 0,1003, TAN (0,2) = 0,203 Donc, pour les angles de cette plage, si vous n'avez pas besoin de précision absolue, vous pouvez enregistrer certains efforts de calcul.


Oui, cela semble être vrai. Les inexactitudes deviennent déjà trop grandes une fois que l'angle est supérieur à environ 10 degrés, et je pense que si vous traitez de petits angles, vous voudrez généralement la plus haute précision.


@Bart: Comme l'OP a déclaré que les performances avec des ressources limitées sont très importantes, je voulais juste lui faire prendre conscience de cette possibilité d'optimisation qui peut être une solution pour le problème, car il n'a rien indiqué sur le type typique ou pire taille de cas des angles.



1
votes

Vous pouvez également utiliser arccosine, si votre ligne est sous la forme [r_x, r_y] code>, où r_x code> est la modification des x et r_y code> est le changement de y.

[r_x,r_y] / (r_x^2+r_y^2)


0 commentaires

10
votes
    private double Angulo(int x1, int y1, int x2, int y2)
    {
        double degrees;

        // Avoid divide by zero run values.
        if (x2 - x1 == 0)
        {
            if (y2 > y1)
                degrees = 90;
            else
                degrees = 270;
        }
        else
        {
            // Calculate angle from offset.
            double riseoverrun = (double)(y2 - y1) / (double)(x2 - x1);
            double radians = Math.Atan(riseoverrun);
            degrees = radians * ((double)180 / Math.PI);

            // Handle quadrant specific transformations.       
            if ((x2 - x1) < 0 || (y2 - y1) < 0)
                degrees += 180;
            if ((x2 - x1) > 0 && (y2 - y1) < 0)
                degrees -= 180;
            if (degrees < 0)
                degrees += 360;
        }
        return degrees;
    }

0 commentaires

1
votes

Si vous avez besoin de quatre quadrants, Atan2 est plus approprié qu'Atan. XXX


0 commentaires