判断并求出两个圆的交点(平面几何)
参考Knut Andreas Lie的Unstructured PEBI-grids Adapting to Geological Features in Subsurface Reservoirs这篇文章,用C++实现了判断并求圆交点的函数。
——式(1)
对于圆C1,可以看作是圆C0偏移距离d得到。根据勾股定理可以得到上述2个式子。其中h⊥d,a是C0到垂足的距离。
如果d==0或R0==R1,说明圆C0和C1的交点为空,或者是重合的。
式(1)转换成式(2),将a和h表示出来:
——式(2)
当 a² > R0² 时,没有交点;
当 a² == R0² 时,有一个交点,为两圆的切点;
当 a² < R0² 时,有2个交点;
交点用向量方法来求:
首先,定义C0→C1的单位方向向量
其次,定义是n||的单位法向量,则交点可以由下列式子计算
——式(3)
实现代码如下,根据返回的容器大小可以判断相交情况,没有交点返回空容器
/* 1.Point2D是自定义的点类, 例Point2D p; p[0] == 1;//表示横坐标为1 p[1] == 2; //表示纵坐标为2 2. double dist(const Point2D &p1,const Point2D &p2)//求出返回2个点的距离; */ vector<Point2D> intersectionofcircles(const Point2D &C1, const double &R1, const Point2D &C2, const double &R2) { vector<Point2D> i_Result; i_Result.clear(); double d = dist(C1, C2);//圆心距d if (abs(d) < 1e-3){}//重合,返回空 else//不重合,计算a { double a = (d*d + R1*R1 - R2*R2) / (2 * d); if (abs(a*a-R1*R1)<1e-3)//相切 { Point2D target; double t = R1 / d; target[0] = C1[0] * (1 - t) + C2[0] * t; target[1] = C1[1] * (1 - t) + C2[1] * t; i_Result.push_back(target); } else if (a*a<R1*R1)//相交 { double h = pow((R1*R1 - a*a), 0.5f); //C1->C2的单位方向向量计算 Point2D Dv((C2[0] - C1[0])/d, (C2[1] - C1[1])/d); //C1->C2的单位法向量计算 Point2D Nv; if (Dv[0]==0) { Nv[0] = 1; Nv[1] = 0; } else if (Dv[1] == 0) { Nv[0] = 0; Nv[1] = 1; } else { Nv[0] = -1 / Dv[0]; Nv[1] = 1 / Dv[1]; double unify = sqrt(Nv[0]*Nv[0]+Nv[1]*Nv[1]); Nv[0] = Nv[0] / unify; Nv[1] = Nv[1] / unify; Point2D p1, p2; p1[0] = C1[0] + a*Dv[0] + h*Nv[0]; p1[1] = C1[1] + a*Dv[1] + h*Nv[1]; p2[0] = C1[0] + a*Dv[0] - h*Nv[0]; p2[1] = C1[1] + a*Dv[1] - h*Nv[1]; i_Result.push_back(p1); i_Result.push_back(p2); } } else//a*a>R1*R1,相离 { } } return i_Result; }
在MFC中可视化结果如下黑点为圆心,粗黑线为半径,红点为交点
[1]Unstructured PEBI-grids Adapting to Geological Features in Subsurface Reservoirs. 2016.
上一篇:
IDEA上Java项目控制台中文乱码