Étant donné le vecteur unitaire 0,5, 0,5, comment pourrais-je trouver l'angle (sa direction),
est-ce
cos (x) + sin (y)?
Étant donné y et x, l'angle avec l'axe x est donné par:
atan2(y,x)
Avec (0,5, 0,5) l'angle est:
radians:
In [2]: math.atan2(0.5,0.5)
Out[2]: 0.7853981633974483
degrés:
In [3]: math.atan2(0.5, 0.5)*180/math.pi
Out[3]: 45.0
#include <cmath>
double x = 0.5;
double y = 0.5;
double angleInRadians = std::atan2(y, x);
double angleInDegrees = (angleInRadians / M_PI) * 180.0;
Bonnes réponses déjà publiées, malheureusement personne ne s'est adressé au fait que OP voulait du code pour calculer la direction, étant plutôt un angle global. Permettez-moi de résoudre ce problème.
atan
(mentionné dans d'autres réponses) vous donnerait un angle ± 0..90 °. Ensuite, vous devrez déterminer dans quel quadrant le vecteur se trouve et modifier l'angle en conséquence; et n'oubliez pas les cas particuliers de x ou y égaux à zéro! Voici un code légèrement modifié que j'utilise:
#include <cmath>
#include <iostream>
using namespace std;
constexpr int radToDeg(float rad) { return rad*(180/M_PI); }
int vectorAngle(int x, int y) {
if (x == 0) // special cases
return (y > 0)? 90
: (y == 0)? 0
: 270;
else if (y == 0) // special cases
return (x >= 0)? 0
: 180;
int ret = radToDeg(atanf((float)y/x));
if (x < 0 && y < 0) // quadrant Ⅲ
ret = 180 + ret;
else if (x < 0) // quadrant Ⅱ
ret = 180 + ret; // it actually substracts
else if (y < 0) // quadrant Ⅳ
ret = 270 + (90 + ret); // it actually substracts
return ret;
}
int main() {
cout << vectorAngle(1,0) << endl
<< vectorAngle(1,1) << endl
<< vectorAngle(0,1) << endl
<< vectorAngle(-1,1) << endl
<< vectorAngle(-1,0) << endl
<< vectorAngle(-1,-1) << endl
<< vectorAngle(0,-1) << endl
<< vectorAngle(1,-1) << endl
<< endl;
}
$ g++ test2.cpp -o a -g3 -O0 && ./a
0
45
90
135
180
225
270
315
Dans le vrai code, cependant, si vous utilisez beaucoup les degrés et les radians (par exemple parce que vous obtenez une entrée avec des degrés, et que les fonctions C++ utilisent des radians), je recommanderais d'utiliser des wrappers autour d'eux pour ne pas les échanger de temps en temps (ce qui m'est arrivé). Par souci d'exhaustivité ci-dessous, voici un extrait du code pertinent de mon bot pour un jeu de voiture, utilisez-le comme vous le souhaitez :)
#include <cmath>
#include <iostream>
using namespace std;
struct Point {
int x, y;
bool operator==(const Point& p) const {
return p.x == x && p.y == y;
}
bool operator!=(const Point& p) const {
return !(p == *this);
}
Point operator+(const Point& rhs) const {
return {x + rhs.x, y + rhs.y};
}
Point operator-(const Point& rhs) const {
return {x - rhs.x, y - rhs.y};
}
void operator+=(const Point& rhs) {
x += rhs.x;
y += rhs.y;
}
friend ostream& operator<<(ostream& os, const Point& p) {
os << "x = " << p.x << ", y = " << p.y;
return os;
}
};
template<typename T>
struct NumWrapper {
T val;
friend ostream& operator<<(ostream& os, const NumWrapper& w) {
os << w.val;
return os;
}
friend istream& operator>>(istream& is, NumWrapper& w) {
is >> w.val;
return is;
}
NumWrapper operator-(const T rhs) const {
return {val - rhs};
}
NumWrapper operator-(const NumWrapper rhs) const {
return {val - rhs.val};
}
NumWrapper operator-() const {
return {-val};
}
NumWrapper operator+(const T rhs) const {
return {val + rhs};
}
NumWrapper operator+(const NumWrapper rhs) const {
return {val + rhs.val};
}
};
using Degree = NumWrapper<int>;
using Radian = NumWrapper<float>;
constexpr Radian degToRad(Degree degree) { return {degree.val*(M_PI/180)}; }
constexpr Radian degToRad(int degree) { return {degree*(M_PI/180)}; }
constexpr Degree radToDeg(Radian rad) { return {rad.val*(180/M_PI)}; }
constexpr Degree radToDeg(float rad) { return {rad*(180/M_PI)}; }
Degree vectorAngle(const Point& vec) {
if (vec.x == 0) // special cases
return (vec.y > 0)? Degree{90}
: (vec.y == 0)? Degree{0}
: Degree{270};
else if (vec.y == 0) // special cases
return (vec.x >= 0)? Degree{0}
: Degree{180};
Degree ret = radToDeg(atanf((float)vec.y/vec.x));
if (vec.x < 0 && vec.y < 0) // quadrant Ⅲ
ret.val = 180 + ret.val;
else if (vec.x < 0) // quadrant Ⅱ
ret.val = 180 + ret.val; // it actually substracts
else if (vec.y < 0) // quadrant Ⅳ
ret.val = 270 + (90 + ret.val); // it actually substracts
return ret;
}
int main() {
cout << vectorAngle({1,0}) << endl
<< vectorAngle({1,1}) << endl
<< vectorAngle({0,1}) << endl
<< vectorAngle({-1,1}) << endl
<< vectorAngle({-1,0}) << endl
<< vectorAngle({-1,-1}) << endl
<< vectorAngle({0,-1}) << endl
<< vectorAngle({1,-1}) << endl
<< endl;
}