c++ - ¿Ángulo del vector de unidades 2D?
angle (3)
Dado el vector de unidad 0.5, 0.5 ¿cómo podría encontrar el ángulo (su dirección),
Lo es
cos (x) + sin (y)?
Buenas respuestas ya publicadas, desafortunadamente nadie abordó el código que OP quería para calcular la dirección, siendo más bien un ángulo global. Déjame arreglar esto.
atan
(mencionado en otras respuestas) le daría un ángulo de ± 0..90 °. Luego, necesitarás averiguar en qué cuadrante está el vector y modificar el ángulo en consecuencia; ¡Y no olvide los casos especiales de x o y igual a cero! Aquí hay un código ligeramente modificado que uso:
#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
Sin embargo, en el código real, si usa mucho grados y radianes (por ejemplo, porque recibe una entrada con grados y luego las funciones de C ++ usan radianes) , recomiendo usar envoltorios alrededor de ellos para no intercambiarlos ocasionalmente (lo que me pasó a mí) . A continuación, se incluye un fragmento de código relevante de mi bot para un juego de autos, utilícelo como desee :)
#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;
}
Dados y y x, el ángulo con el eje x viene dado por:
atan2(y,x)
Con (0.5, 0.5) el ángulo es:
radianes
In [2]: math.atan2(0.5,0.5)
Out[2]: 0.7853981633974483
grados
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;