BOOL CPline::FindIncircle(double a)//这是一个多段线类的成员函数,把其中的点设成参数就可以满足别的需求了
{
int Max=500;//设置最大循环次数
int i1,i2; //记录最小和次小的位置
double sumx,sumy;
sumx=sumy=0; //其中,A点是距离最近的点,B点是次近的点
PointStruct A, B,C,O,O1,tempPt; //A,B,分别为最小,和次小距离的两个垂足,o为设定初始计算圆心
float distf,dists,dist;
float distfn,distsn;// a 为步长因子
m_PointList[m_Number]=m_PointList[0]; //
O.x=(m_PointList[0].x+m_PointList[2].x)/2; //这里取了第一点和第三点连线的中点 //
O.y=(m_PointList[0].y+m_PointList[2].y)/2;
for(int i=0;i
sumx+=m_PointList[i].x;
sumy+=m_PointList[i].y;
}
O.x=sumx/m_Number;
O.y=sumy/m_Number;
do {
Max--;
distf=dists=10.0E10; //循环获取圆心离每个边的距离,获得最小和次小距离,并且保存各个垂足
for(int i=0; i
dist=CalRealDist(O.x,O.y,m_PointList[i].x,m_PointList[i].y,m_PointList[i+1].x,m_PointList[i+1].y,tempPt);
if(dist
dists=distf; distf=dist; i2=i1; //保存最小
i1=i;
}
if(distdistf) {
dists=dist;
i2=i;
}
}
CalRealDist(O.x,O.y,m_PointList[i1].x,m_PointList[i1].y, m_PointList[i1+1].x,m_PointList[i1+1].y, A);
CalRealDist(O.x,O.y,m_PointList[i2].x,m_PointList[i2].y, m_PointList[i2+1].x,m_PointList[i2+1].y, B); //其中C点是参考点
C.x=A.x+distf/(distf+dists)*(B.x-A.x);
C.y=A.y+distf/(distf+dists)*(B.y-A.y);
do { //计算新的内切园圆心坐标
distfn=distsn=10.0E10;
if(C.x==O.x&&C.y==O.y) //判断圆心是否和AB共线
{
C.x=A.x;
C.y=A.y;
}
O1.x=O.x+a*(O.x-C.x)/sqrt((O.x-C.x)*(O.x-C.x)+(O.y-C.y)*(O.y-C.y));
O1.y=O.y+a*(O.y-C.y)/sqrt((O.x-C.x)*(O.x-C.x)+(O.y-C.y)*(O.y-C.y)); //重新计算内切圆的最小半径 for (i=0; i
dist=CalRealDist(O1.x,O1.y,m_PointList[i].x,m_PointList[i].y, m_PointList[i+1].x, m_PointList[i+1].y, tempPt);
if(dist
distfn=dist; //保存最小
}
}
if(distfn
} while(distfn0.00001); //这里判断说明了
//将新计算的O1点赋值给O点
O.x=O1.x; O.y=O1.y;
} while(a>0.00001&&Max>0);
m_center.x=O1.x;
m_center.y=O1.y;
m_radius=distfn;
retur
n TRUE;
}