曾几何时自己写了读取dxf的方法,当时只是对Line,Arc,Circle和eplise的解析。
对于多线POLYLINE和LWPOLYLINE的解析最终是放弃了。
现在又一次找回了当时的代码,而且多线结构势在必行。网上找了很久,没有让人信服的方法,大部分都是只考虑直线的情况,要不然就是不负责任的照搬DXF中的描述。
对于直线、弧线顺序相连的多线结构,网上基本上没有。
而弧线的计算最大的问题就是凸度(也就是42后面的内容),由于每个人定义的结构体不同,所以下面只提供凸度的处理。
//具体就是把i-1的点定为起点,i为终点
if( 0 ==Tudegree[i-1] )//如果凸度
{
//则为直线,
_swLine temp; //自定义的直线结构体,有起点和终点 struct _swLine { dfPoint startPoint; dfPoint endPoint;};
temp.startPoint = point[i-1]; //point 为自定义点结构体,struct dfPoint { double x ; double y;};
temp.endPoint = point[i];
}
else
{
_swArc temp; //自定义的弧线结构体,含有startPoint,endPoint,CenterPoint,clockwise.
if( 0 > Tudegree[i-1]. ) //如果凸度小于0则为顺时针,clockwise为true
{
temp.clockwise = true;
}
else
{
temp.clockwise = false;
}
temp.startPoint = point[i-1].;
temp.endPoint = point[i-1].;
//则最重要的是计算圆弧的中心和半径。
double x1 = temp.startPoint.x;
double y1 = temp.startPoint.y;
double x2 = temp.endPoint.x;
double y2 = temp.endPoint.y;
//凸度为四分之一圆角的正切值
double theta_arc = atan(Tudegree[i-1]) * 4;
double theta_degree = fRadToDegree(theta_arc);//角度
if( fabs(180 - fabs(theta_degree)) < 0.1 ) //半圆,直接计算中心
{
temp.center.x = (x1+x2)/2;
temp.center.y = (y1+y2)/2;
}
else
{
double length = sqrt(pow((x1 - x2),2) + pow((y1 - y2),2)); //弦长
double dfR = length/(2.0*sin(fabs(theta_arc)/2.0)); //半径
_point cen1,cen2; //暂存两个圆心
if (y2 == y1) //中垂线平行与y轴
{
//中垂线为 x = (x1 + x2)/2
//以x1,y1为圆心,dfR为半径作圆,求中垂线与圆交点
//(x-x1)*(x-x1) + (y-y1)*(y-y1) = dfR*dfR
double dfDiff = pow(dfR,2) - pow(((x2-x1)/2),2);
if (dfDiff < 0)
{
return false;
}
cen1.x = (x2+x1)/2;
cen2.x = (x2+x1)/2;
cen1.y = y1 + sqrt(dfDiff);
cen2.y = y1 - sqrt(dfDiff);
}
else
{
//中垂线 y = kx + bk
double k = -(x2-x1)/(y2-y1); //中垂线斜率
double bk = 0.5 * (pow(y2,2) - pow(y1,2) + pow(x2,2) - pow(x1,2))/(y2-y1);
//以x1,y1为圆心,dfR为半径作圆,求中垂线与圆交点
//(x-x1)*(x-x1) + (y-y1)*(y-y1) = dfR*dfR
double a = pow(k,2) + 1;
double b = 2 *(k*(bk-y1)-x1);
double c = pow(x1,2) + pow((bk-y1),2) - pow(dfR,2);
double delta = pow(b,2) - 4*a*c;
if (delta < 0)
{
return false;
}
cen1.x = (-b + sqrt(delta))/(2*a);
cen1.y = k*cen1.x + bk;
cen2.x = (-b - sqrt(delta))/(2*a);
cen2.y = k*cen2.x + bk;
}
//根据矢量判断 P0为起点,P2为终点,P1为圆心(即判断P1P0 差乘 P1P2)
//P1P0 X P1P2 = lP1P0l*lP1P2l*Sin(theta) = (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
//那么该值应该与弧度方向一致,在弧度大于PI(3.14159265)的时候为另外一种情况
_point p0 = cen1;
_point p2 = temp.endPoint;
_point p1 = temp.startPoint;
double dfDiff = (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
if (fabs(theta_arc) < PI)
{
if (dfDiff * theta_arc > 0)
{
temp.center = cen1;
}
else
{
temp.center = cen2;}
}
else
{
if (dfDiff * theta_arc < 0)
{
temp.center = cen1;
}
else
{
temp.center = cen2;
}
}