我有两行:Line1和Line2。每行由两个点(P1L1(x1, y1), P2L1(x2, y2)
和P1L1(x1, y1), P2L3(x2, y3))
定义。我想知道这两条线定义的内角。
为此,我用横坐标计算每条线的角度:
double theta1 = atan(m1) * (180.0 / PI);
double theta2 = atan(m2) * (180.0 / PI);
知道角度后,我计算出以下内容:
double angle = abs(theta2 - theta1);
我的问题或怀疑是:有时我会获得正确的角度,但有时我会获得互补角度(对我来说是外部的)。我怎么知道什么时候减去
180º
才能知道内角?有没有更好的算法可以做到这一点?因为我尝试了一些方法:点积,公式如下:
result = (m1 - m2) / (1.0 + (m1 * m2));
但是我总是有同样的问题。我不知道什么时候有外角或内角!
最佳答案
我认为您正在寻找的是两个角度的inner product(您可能还希望查看dot product条目)。在您的情况下,可以通过以下方式获得:
float dx21 = x2-x1;
float dx31 = x3-x1;
float dy21 = y2-y1;
float dy31 = y3-y1;
float m12 = sqrt( dx21*dx21 + dy21*dy21 );
float m13 = sqrt( dx31*dx31 + dy31*dy31 );
float theta = acos( (dx21*dx31 + dy21*dy31) / (m12 * m13) );
答案以弧度为单位。
编辑:这是一个完整的实现。将有问题的值替换为p1,p2和p3,然后让我知道您得到了什么。根据您对两条线的定义,点p1是两条线相交的顶点。
#include <math.h>
#include <iostream>
template <typename T> class Vector2D
{
private:
T x;
T y;
public:
explicit Vector2D(const T& x=0, const T& y=0) : x(x), y(y) {}
Vector2D(const Vector2D<T>& src) : x(src.x), y(src.y) {}
virtual ~Vector2D() {}
// Accessors
inline T X() const { return x; }
inline T Y() const { return y; }
inline T X(const T& x) { this->x = x; }
inline T Y(const T& y) { this->y = y; }
// Vector arithmetic
inline Vector2D<T> operator-() const
{ return Vector2D<T>(-x, -y); }
inline Vector2D<T> operator+() const
{ return Vector2D<T>(+x, +y); }
inline Vector2D<T> operator+(const Vector2D<T>& v) const
{ return Vector2D<T>(x+v.x, y+v.y); }
inline Vector2D<T> operator-(const Vector2D<T>& v) const
{ return Vector2D<T>(x-v.x, y-v.y); }
inline Vector2D<T> operator*(const T& s) const
{ return Vector2D<T>(x*s, y*s); }
// Dot product
inline T operator*(const Vector2D<T>& v) const
{ return x*v.x + y*v.y; }
// l-2 norm
inline T norm() const { return sqrt(x*x + y*y); }
// inner angle (radians)
static T angle(const Vector2D<T>& v1, const Vector2D<T>& v2)
{
return acos( (v1 * v2) / (v1.norm() * v2.norm()) );
}
};
int main()
{
Vector2D<double> p1(215, 294);
Vector2D<double> p2(174, 228);
Vector2D<double> p3(303, 294);
double rad = Vector2D<double>::angle(p2-p1, p3-p1);
double deg = rad * 180.0 / M_PI;
std::cout << "rad = " << rad << "\tdeg = " << deg << std::endl;
p1 = Vector2D<double>(153, 457);
p2 = Vector2D<double>(19, 457);
p3 = Vector2D<double>(15, 470);
rad = Vector2D<double>::angle(p2-p1, p3-p1);
deg = rad * 180.0 / M_PI;
std::cout << "rad = " << rad << "\tdeg = " << deg << std::endl;
return 0;
}
上面的代码产生:
rad = 2.12667 deg = 121.849
rad = 0.0939257 deg = 5.38155
关于c++ - 两线之间的内角,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2946327/