Permalink
Browse files

angle between lines

More unit tests
Clearer behavior for obtuse / accute angles and angle signess.
  • Loading branch information...
jlblancoc committed Feb 4, 2019
1 parent 4779d77 commit 8e145cddbce420fb1ef262c8d8e581fe4a3c4fd3
@@ -181,13 +181,15 @@ namespace mrpt
return getAngle(p2,r1);
}
/**
* Computes the angle between two 3D lines or segments (implicit constructor will be used if passing a segment instead of a line).
*/
double BASE_IMPEXP getAngle(const TLine3D &r1,const TLine3D &r2);
/**
* Computes the angle between two 2D lines or segments (implicit constructor will be used if passing a segment instead of a line).
*/
double BASE_IMPEXP getAngle(const TLine2D &r1,const TLine2D &r2);
* Computes the accute relative angle (range: [-PI/2,PI/2]) between two lines.
* \note Implicit constructor allows passing a segment as argument too.
*/
double BASE_IMPEXP getAngle(const TLine3D &r1, const TLine3D &r2);
/**
* Computes the relative angle (range: [-PI,PI]) of line 2 wrt line 1.
* \note Implicit constructor allows passing a segment as argument too.
*/
double BASE_IMPEXP getAngle(const TLine2D &r1, const TLine2D &r2);
/** @}
*/

@@ -763,16 +763,9 @@ double math::getAngle(const TLine3D &r1,const TLine3D &r2) {
}

double math::getAngle(const TLine2D &r1,const TLine2D &r2) {
double c=0,n1=0,n2=0;
for (size_t i=0;i<2;i++) {
c+=r1.coefs[i]*r2.coefs[i];
n1+=r1.coefs[i]*r1.coefs[i];
n2+=r2.coefs[i]*r2.coefs[i];
}
double s=sqrt(n1*n2);
if (s<geometryEpsilon) throw std::logic_error("Invalid line(s)");
if (abs(s)<abs(c)) return (c/s<0)?M_PI:0;
else return acos(c/sqrt(n1*n2));
const double ang1 = std::atan2(-r1.coefs[0], r1.coefs[1]);
const double ang2 = std::atan2(-r2.coefs[0], r2.coefs[1]);
return mrpt::math::wrapToPi(ang2 - ang1);
}

//Auxiliary method
@@ -37,6 +37,46 @@ TEST(Geometry, Line2DIntersect)
EXPECT_NEAR(i.y, 0.5, 1e-9);
}

TEST(Geometry, Line2DAngle)
{
const TLine2D l1(TPoint2D(0, 0), TPoint2D(1, 0));
const TLine2D l2(TPoint2D(-1, -1), TPoint2D(5, 5));

// Angles in 2D do have sign:
EXPECT_NEAR(RAD2DEG(mrpt::math::getAngle(l1, l2)), +45.0, 1e-5);
EXPECT_NEAR(RAD2DEG(mrpt::math::getAngle(l2, l1)), -45.0, 1e-5);

EXPECT_NEAR(RAD2DEG(mrpt::math::getAngle(l1, l1)), 0.0, 1e-5);
EXPECT_NEAR(RAD2DEG(mrpt::math::getAngle(l2, l2)), 0.0, 1e-5);

const TLine2D l3(TPoint2D(1, 0), TPoint2D(0, 0));
EXPECT_NEAR(RAD2DEG(std::abs(mrpt::math::getAngle(l1, l3))), 180.0, 1e-5);
EXPECT_NEAR(RAD2DEG(std::abs(mrpt::math::getAngle(l3, l1))), 180.0, 1e-5);
}

TEST(Geometry, Line3DAngle)
{
const TLine3D l1(TPoint3D(0, 0, 0), TPoint3D(1, 0, 0));
const TLine3D l2(TPoint3D(-1, -1, 0), TPoint3D(5, 5, 0));

// Angles in 3D don't have sign:
EXPECT_NEAR(RAD2DEG(mrpt::math::getAngle(l1, l2)), 45.0, 1e-5);
EXPECT_NEAR(RAD2DEG(mrpt::math::getAngle(l2, l1)), 45.0, 1e-5);

EXPECT_NEAR(RAD2DEG(mrpt::math::getAngle(l1, l1)), 0.0, 1e-5);
EXPECT_NEAR(RAD2DEG(mrpt::math::getAngle(l2, l2)), 0.0, 1e-5);

const TLine3D l3(TPoint3D(1, 0, 0), TPoint3D(0, 0, 0));
EXPECT_NEAR(RAD2DEG(std::abs(mrpt::math::getAngle(l1, l3))), 180.0, 1e-5);
EXPECT_NEAR(RAD2DEG(std::abs(mrpt::math::getAngle(l3, l1))), 180.0, 1e-5);

const TLine3D l4(
TPoint3D(0, 0, 0), TPoint3D(cos(DEG2RAD(30.0)), sin(DEG2RAD(30.0)), 0));
EXPECT_NEAR(RAD2DEG(mrpt::math::getAngle(l1, l4)), 30.0, 1e-5);
EXPECT_NEAR(RAD2DEG(mrpt::math::getAngle(l4, l1)), 30.0, 1e-5);
}


TEST(Geometry, Segment2DIntersect)
{
{

0 comments on commit 8e145cd

Please sign in to comment.