Skip to content

Commit

Permalink
Merge pull request #46392 from qgis/backport-46372-to-release-3_22
Browse files Browse the repository at this point in the history
[Backport release-3_22] Fix triangle angles
  • Loading branch information
lbartoletti committed Dec 7, 2021
2 parents e9554eb + 55010fc commit fc74cd3
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 23 deletions.
40 changes: 21 additions & 19 deletions src/core/geometry/qgstriangle.cpp
Expand Up @@ -373,9 +373,9 @@ QVector<double> QgsTriangle::lengths() const
if ( isEmpty() )
return lengths;

lengths.append( vertexAt( 0 ).distance( vertexAt( 1 ) ) );
lengths.append( vertexAt( 1 ).distance( vertexAt( 2 ) ) );
lengths.append( vertexAt( 2 ).distance( vertexAt( 0 ) ) );
lengths.append( vertexAt( 0 ).distance( vertexAt( 1 ) ) ); // c = |AB|
lengths.append( vertexAt( 1 ).distance( vertexAt( 2 ) ) ); // a = |BC|
lengths.append( vertexAt( 0 ).distance( vertexAt( 2 ) ) ); // b = |AC|

return lengths;
}
Expand All @@ -385,22 +385,24 @@ QVector<double> QgsTriangle::angles() const
QVector<double> angles;
if ( isEmpty() )
return angles;
double ax, ay, bx, by, cx, cy;

ax = vertexAt( 0 ).x();
ay = vertexAt( 0 ).y();
bx = vertexAt( 1 ).x();
by = vertexAt( 1 ).y();
cx = vertexAt( 2 ).x();
cy = vertexAt( 2 ).y();

const double a1 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( cx, cy, ax, ay, bx, by ), M_PI );
const double a2 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( ax, ay, bx, by, cx, cy ), M_PI );
const double a3 = std::fmod( QgsGeometryUtils::angleBetweenThreePoints( bx, by, cx, cy, ax, ay ), M_PI );

angles.append( ( a1 > M_PI_2 ? a1 - M_PI_2 : a1 ) );
angles.append( ( a2 > M_PI_2 ? a2 - M_PI_2 : a2 ) );
angles.append( ( a3 > M_PI_2 ? a3 - M_PI_2 : a3 ) );

QVector<double> l = lengths();

const double a = l[1];
const double b = l[2];
const double c = l[0];

const double a2 = a * a;
const double b2 = b * b;
const double c2 = c * c;

const double alpha = acos( ( b2 + c2 - a2 ) / ( 2 * b * c ) );
const double beta = acos( ( a2 + c2 - b2 ) / ( 2 * a * c ) );
const double gamma = M_PI - alpha - beta; // acos((a2 + b2 - c2)/(2*a*b)); but ensure that alpha+beta+gamma = 180.0

angles.append( alpha );
angles.append( beta );
angles.append( gamma );

return angles;
}
Expand Down
50 changes: 46 additions & 4 deletions tests/src/core/geometry/testqgstriangle.cpp
Expand Up @@ -787,17 +787,59 @@ void TestQgsTriangle::angles()
{
QgsTriangle tr( QgsPoint( 0, 0 ), QgsPoint( 0, 5 ), QgsPoint( 5, 5 ) );

QVector<double> a_tested, a_t7 = tr.angles();
QVector<double> a_tested;
QVector<double> angles = tr.angles();
a_tested.append( M_PI / 4.0 );
a_tested.append( M_PI / 2.0 );
a_tested.append( M_PI / 4.0 );

QGSCOMPARENEAR( a_tested.at( 0 ), a_t7.at( 0 ), 0.0001 );
QGSCOMPARENEAR( a_tested.at( 1 ), a_t7.at( 1 ), 0.0001 );
QGSCOMPARENEAR( a_tested.at( 2 ), a_t7.at( 2 ), 0.0001 );
QGSCOMPARENEAR( a_tested.at( 0 ), angles.at( 0 ), 0.0001 );
QGSCOMPARENEAR( a_tested.at( 1 ), angles.at( 1 ), 0.0001 );
QGSCOMPARENEAR( a_tested.at( 2 ), angles.at( 2 ), 0.0001 );

QVector<double> a_empty = QgsTriangle().angles();
QVERIFY( a_empty.isEmpty() );

// From issue #46370
tr = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 1, sqrt( 3 ) ), QgsPoint( 2, 0 ) );
angles = tr.angles();
QGSCOMPARENEAR( angles.at( 0 ), M_PI / 3.0, 0.0001 );
QGSCOMPARENEAR( angles.at( 1 ), M_PI / 3.0, 0.0001 );
QGSCOMPARENEAR( angles.at( 2 ), M_PI / 3.0, 0.0001 );

tr = QgsTriangle( QgsPoint( 2, 0 ), QgsPoint( 1, sqrt( 3 ) ), QgsPoint( 0, 0 ) );
angles = tr.angles();
QGSCOMPARENEAR( angles.at( 0 ), M_PI / 3.0, 0.0001 );
QGSCOMPARENEAR( angles.at( 1 ), M_PI / 3.0, 0.0001 );
QGSCOMPARENEAR( angles.at( 2 ), M_PI / 3.0, 0.0001 );

tr = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 0, 3 ), QgsPoint( 4, 0 ) );
angles = tr.angles();
QGSCOMPARENEAR( angles.at( 0 ), M_PI / 2.0, 0.0001 );
QGSCOMPARENEAR( angles.at( 1 ), 0.9272952, 0.0001 );
QGSCOMPARENEAR( angles.at( 2 ), 0.6435011, 0.0001 );
tr = QgsTriangle( QgsPoint( 4, 0 ), QgsPoint( 0, 3 ), QgsPoint( 0, 0 ) );
angles = tr.angles();
QGSCOMPARENEAR( angles.at( 0 ), 0.6435011, 0.0001 );
QGSCOMPARENEAR( angles.at( 1 ), 0.9272952, 0.0001 );
QGSCOMPARENEAR( angles.at( 2 ), M_PI / 2.0, 0.0001 );

tr = QgsTriangle( QgsPoint( 0, 0 ), QgsPoint( 1, 3 ), QgsPoint( 3, 0 ) );
angles = tr.angles();
QGSCOMPARENEAR( angles.at( 0 ), 1.2490457, 0.0001 );
QGSCOMPARENEAR( angles.at( 1 ), 0.9097531, 0.0001 );
QGSCOMPARENEAR( angles.at( 2 ), 0.9827937, 0.0001 );
tr = QgsTriangle( QgsPoint( 3, 0 ), QgsPoint( 1, 3 ), QgsPoint( 0, 0 ) );
angles = tr.angles();
QGSCOMPARENEAR( angles.at( 0 ), 0.9827937, 0.0001 );
QGSCOMPARENEAR( angles.at( 1 ), 0.9097531, 0.0001 );
QGSCOMPARENEAR( angles.at( 2 ), 1.2490457, 0.0001 );

tr = QgsTriangle( QgsPoint( 78598.328125, 330538.375, 0 ), QgsPoint( 78606.3203125, 330544, 0 ), QgsPoint( 78601.46875, 330550.90625, 0 ) );
angles = tr.angles();
QGSCOMPARENEAR( angles.at( 0 ), 0.7119510, 0.0001 );
QGSCOMPARENEAR( angles.at( 1 ), 1.5716821, 0.0001 );
QGSCOMPARENEAR( angles.at( 2 ), 0.8579596, 0.0001 );
}

void TestQgsTriangle::lengths()
Expand Down

0 comments on commit fc74cd3

Please sign in to comment.