已知三点求圆心与半径
在计算机图像图形学中,经常会用到求圆心或圆半径的情况,本文介绍一种已知三个点求圆心和圆半径的方法(当然三个点不能共线,共线的三个点不能构成圆)。
原理:相互连接三个点,选取其中的任意两条直线,通过对这两条直线的中心做垂线,两条垂线的交点就是圆心,以此点为圆心,以此点到任意一点的距离为半径画圆。
三个点分别计为pt1, pt2, pt3:取直线p1p2和p1p3(也可以取其他直线),直线的中点则分别为:
CvPoint midPt1, midPt2;
midPt1.x = (pt2.x + pt1.x)/2;
midPt1.y = (pt2.y + pt1.y)/2;
midPt2.x = ( pt3.x + pt1.x)/2;
midPt2.y = ( pt3.y + pt1.y)/2;
由于p1p2和p1p3的垂线与其自身的斜率的乘积为-1,则其垂线的斜率分别为:
float k1 = -(pt2.x - pt1.x)/(pt2.y - pt1.y);
float k2 = -(pt3.x - pt1.x)/(pt3.y - pt1.y);
那么对应的垂线的直线可以表示为:
y - midPt1.y = k1( x - midPt1.x);
y = midPt2.y = k2( x - midPt2.x);
对上面两条直线表达式进行联解,则可以分别求出其交点x, y的值,其中:
center.x = (midPt2.y - midPt1.y- k2* midPt2.x + k1*midPt1.x)/(k1 - k2);
center.y = midPt1.y + k1*( midPt2.y - midPt1.y - k2*midPt2.x + k2*midPt1.x)/(k1-k2);
x、y就是圆的圆心。圆心与任意一个顶点的距离即为圆的半径,表达为:
float radius = sqrtf((center.x - pt1.x)*(center.x - pt1.x) + (center.y - pt1.y)*(center.y - pt1.y));
完整的代码如下:
typedef struct
{
CvPoint center;
int radius;
}CircleData;
CircleData findCircle( CvPoint pt1, CvPoint pt2, CvPoint pt3)
{
CvPoint midPt1, midPt2;
midPt1.x = (pt2.x + pt1.x)/2;
midPt1.y = (pt2.y + pt1.y)/2;
midPt2.x = ( pt3.x + pt1.x)/2;
midPt2.y = ( pt3.y + pt1.y)/2;
float k1 = -(pt2.x - pt1.x)/(pt2.y - pt1.y);
float k2 = -(pt3.x - pt1.x)/(pt3.y - pt1.y);
CircleData CD;
CD.center.x = (midPt2.y - midPt1.y- k2* midPt2.x + k1*midPt1.x)/(k1 - k2);
CD.center.y = midPt1.y + k1*( midPt2.y - midPt1.y - k2*midPt2.x + k2*midPt1.x)/(k1-k2);
CD.radius = sqrtf((CD.center.x - pt1.x)*(CD.center.x - pt1.x) + (CD.center.y - pt1.y)*(CD.center.y - pt1.y));
return CD;
}
测试效果如图所示:
作者:侯相,出处http://blog.csdn.net/kezunhai或http://www.feiyuntech.com/:欢迎转载或分享,但请务必声明文章出处。