QgsGeometryUtils_circleCenterRadius.txt

Timo Iipponen, 2015-11-28 10:16 AM

Download (1.28 KB)

 
1
void QgsGeometryUtils::circleCenterRadius( const QgsPointV2& pt1, const QgsPointV2& pt2, const QgsPointV2& pt3, double& radius, double& centerX, double& centerY )
2
{
3
  double dx21, dy21, dx31, dy31, h21, h31, d;
4

    
5
  //closed circle
6
  if ( qgsDoubleNear( pt1.x(), pt3.x() ) && qgsDoubleNear( pt1.y(), pt3.y() ) )
7
  {
8
    centerX = pt2.x();
9
    centerY = pt2.y();
10
    radius = sqrt( pow( pt2.x() - pt1.x(), 2.0 ) + pow( pt2.y() - pt1.y(), 2.0 ) );
11
    return;
12
  }
13

    
14
  // Using cartesian circumcenter eguations from page https://en.wikipedia.org/wiki/Circumscribed_circle
15
  dx21 = pt2.x() - pt1.x();
16
  dy21 = pt2.y() - pt1.y();
17
  dx31 = pt3.x() - pt1.x();
18
  dy31 = pt3.y() - pt1.y();
19

    
20
  h21 = pow( dx21, 2.0 ) + pow( dy21, 2.0 );
21
  h31 = pow( dx31, 2.0 ) + pow( dy31, 2.0 );
22

    
23
  // 2*Cross product, d<0 means clockwise and d>0 counterclockwise sweeping angle
24
  d = 2 * (dx21 * dy31 - dx31 * dy21);
25

    
26
  // Check colinearity, Cross product = 0
27
  if ( qgsDoubleNear( fabs( d ), 0.0, 0.00000000001 ) )
28
  {
29
    radius = -1.0;
30
    return;
31
  }
32

    
33
  // Calculate centroid coordinates and radius
34
  centerX = pt1.x() + ( h21 * dy31 - h31 * dy21 ) / d;
35
  centerY = pt1.y() - ( h21 * dx31 - h31 * dx21 ) / d;
36
  radius = sqrt( pow( centerX - pt1.x(), 2.0 ) + pow( centerY - pt1.y(), 2.0 ) );
37
}