void QgsGeometryUtils::circleCenterRadius( const QgsPointV2& pt1, const QgsPointV2& pt2, const QgsPointV2& pt3, double& radius, double& centerX, double& centerY ) { double dx21, dy21, dx31, dy31, h21, h31, d; //closed circle if ( qgsDoubleNear( pt1.x(), pt3.x() ) && qgsDoubleNear( pt1.y(), pt3.y() ) ) { centerX = pt2.x(); centerY = pt2.y(); radius = sqrt( pow( pt2.x() - pt1.x(), 2.0 ) + pow( pt2.y() - pt1.y(), 2.0 ) ); return; } // Using cartesian circumcenter eguations from page https://en.wikipedia.org/wiki/Circumscribed_circle dx21 = pt2.x() - pt1.x(); dy21 = pt2.y() - pt1.y(); dx31 = pt3.x() - pt1.x(); dy31 = pt3.y() - pt1.y(); h21 = pow( dx21, 2.0 ) + pow( dy21, 2.0 ); h31 = pow( dx31, 2.0 ) + pow( dy31, 2.0 ); // 2*Cross product, d<0 means clockwise and d>0 counterclockwise sweeping angle d = 2 * (dx21 * dy31 - dx31 * dy21); // Check colinearity, Cross product = 0 if ( qgsDoubleNear( fabs( d ), 0.0, 0.00000000001 ) ) { radius = -1.0; return; } // Calculate centroid coordinates and radius centerX = pt1.x() + ( h21 * dy31 - h31 * dy21 ) / d; centerY = pt1.y() - ( h21 * dx31 - h31 * dx21 ) / d; radius = sqrt( pow( centerX - pt1.x(), 2.0 ) + pow( centerY - pt1.y(), 2.0 ) ); }