DXF文件中将多段线凸度转换成圆弧
2015-09-09 16:43
411 查看
在数控系统中,我们常常会将DXF文件转换成G代码,主要涉及到 直线、多段线、圆、圆弧、椭圆、样条曲线、点,七大类,在转换成G代码过程中,其中样条曲线和多段线中凸度问题是比较复杂一些,而样条曲线的转换网上有很多源代码,而处理凸度问题的源代码似乎少很多。最近刚好我也在解析DXF文件,遇到了处理凸度的问题。我花了两天时间集中完成这个难题。通过大量的测试代码基本没有什么问题,凸度问题完美解决了。(其中主要的方法是运用了数学推导出来的方程计算的)
本文章只供参考,希望不要用在商业性质上。
double dConvexityDegree=0; //凸度 long nSumLines = dxf_code.size(); double theta_arc; double theta_degree ;//角度,包角 double dAngle;//起点到终点的弦向量与X正方向之间的倾斜角 double dStarX=0,dStarY=0;//圆弧起始点 double dEndX=0,dEndY=0; //圆弧终止点 double dStarC=0,dEndC=0; //圆弧起始角度,终止角度 double dmiddleX=0,dmiddleY=0;//起始点和终止点连接线的中点横纵坐标 double dCenterX=0,dCenterY=0;//圆心坐标 double dCenterX1=0,dCenterY1=0;//圆心坐标1 double dCenterX2=0,dCenterY2=0;//圆心坐标2 double dLength; //弦长 double dfR; //半径 double dH; //圆心到弦的距离 //double k; //起始点和终止点连线的中垂线斜率 double dAmass; //弦向量与X轴正向单位向量的叉积 double dDirectionAngel;//弦中点到圆心的直线向量的方向角(0-2PI之间) double dD; //圆心到弦长的距离 double dNslope;////弦的斜率 double dK; //弦中垂线的斜率 double dNAngel;//中垂线的倾斜角 double dX,dY; //圆心相对于弦中心点的坐标偏移量 double num1,num2; //x方向矢量和圆心到弧线起点和终点的矢量的叉乘的z double k = 0.0;//弦的斜率 double k_verticle = 0.0;//弦的中垂线的斜率 double mid_x = 0.0,mid_y = 0.0;//弦的中点坐标 double a = 1.0; double b = 1.0; double c = 1.0; double angleChordX=0;//弦向量X正方向的角度 int direction=0;//判断是G02还是G03 bool isMinorArc=TRUE;//圆弧半径是否为较小的 double dStartVale=0; //起始角的cos(dStarC)值 double dEndVale=0; //终止角的cos(dEndC)值
dConvexityDegree=code.r1; //当凸度dConvexityDegree不等于0时,表示为圆弧 if (0!=dConvexityDegree) { theta_degree = 4*atan(fabs(dConvexityDegree)); //起始点,终止点 dStarX = code.x1; dStarY = code.y1; dEndX = code.x2; dEndY = code.y2; //弦长 dLength = sqrt(pow(dStarX-dEndX,2)+pow(dStarY-dEndY,2)); //圆弧半径 dfR = fabs(0.5*dLength/sin(0.5*theta_degree)); k = (dEndY - dStarY) / (dEndX - dStarX); if(k == 0) { dCenterX1 = (dStarX + dEndX) / 2.0; dCenterX2 = (dStarX + dEndX) / 2.0; dCenterY1 = dStarY + sqrt(dfR * dfR -(dStarX - dEndX) * (dStarX - dEndX) / 4.0); dCenterY2 = dEndY - sqrt(dfR * dfR -(dStarX - dEndX) * (dStarX - dEndX) / 4.0); } else { k_verticle = -1.0 / k; mid_x = (dStarX + dEndX) / 2.0; mid_y = (dStarY + dEndY) / 2.0; a = 1.0 + k_verticle * k_verticle; b = -2 * mid_x - k_verticle * k_verticle * (dStarX + dEndX); c = mid_x * mid_x + k_verticle * k_verticle * (dStarX + dEndX) * (dStarX + dEndX) / 4.0 - (dfR * dfR - ((mid_x - dStarX) * (mid_x - dStarX) + (mid_y - dStarY) * (mid_y - dStarY))); dCenterX1 = (-1.0 * b + sqrt(b * b -4 * a * c)) / (2 * a); dCenterX2 = (-1.0 * b - sqrt(b * b -4 * a * c)) / (2 * a); dCenterY1 = k_verticle*dCenterX1 -k_verticle*mid_x+mid_y; dCenterY2 = k_verticle*dCenterX2 -k_verticle*mid_x+mid_y; } //凸度绝对值小于1表示圆弧包角小于180°,凸度绝对值大于1表示圆弧包角大于180° if (fabs(dConvexityDegree)<=1) isMinorArc=TRUE; else isMinorArc=FALSE; //确定圆弧的顺逆 if (0>dConvexityDegree) direction=2; else direction=3; //确定圆心 angleChordX=acos((1*(dEndX-dStarX)+0*(dEndY-dStarY))/dLength)*180/PI; if ((dEndY-dStarY)<0) { angleChordX*=-1; } if ((angleChordX>0 && angleChordX<180)||angleChordX==180) { if (direction==2)//顺圆 { if(isMinorArc) { dCenterX=dCenterX1; dCenterY=dCenterY1; } else { dCenterX=dCenterX2; dCenterY=dCenterY2; } } else if (direction==3)//逆圆 { if (isMinorArc) { dCenterX=dCenterX2; dCenterY=dCenterY2; } else { dCenterX=dCenterX1; dCenterY=dCenterY1; } } } else { if (direction==2)//顺圆 { if(isMinorArc) { dCenterX=dCenterX2; dCenterY=dCenterY2; } else { dCenterX=dCenterX1; dCenterY=dCenterY1; } } else if (direction==3)//逆圆 { if (isMinorArc) { dCenterX=dCenterX1; dCenterY=dCenterY1; } else { dCenterX=dCenterX2; dCenterY=dCenterY2; } } } //起始角度、终止角度 dStartVale=(dStarX-dCenterX)/dfR; //在C++中,浮点型中的结果1可能是1.00000000000000001,避免这种情况出现。 if (dStartVale>1) dStartVale=1; if (dStartVale<-1) dStartVale=-1; dStarC = acos(dStartVale); //x方向矢量和圆心到弧线起点和终点的矢量的叉乘的z num1=dStarY-dCenterY; if(num1<0) dStarC=2*PI-dStarC; //终止角度、终止角度 dEndVale=(dEndX-dCenterX)/dfR; //在C++中,浮点型中的结果1可能是1.00000000000000001,避免这种情况出现。 if (dEndVale>1) dEndVale=1; if (dEndVale<-1) dEndVale=-1; dEndC = acos(dEndVale); //x方向矢量和圆心到弧线起点和终点的矢量的叉乘的z num2=dEndY-dCenterY; if(num2<0) dEndC=2*PI-dEndC; //将DXF_LWPOLYLINE转换成ARC code.mStyle=DXF_ARC; //如果凸度小于0则为顺时针,clockwise为true if (0>dConvexityDegree) code.bWise=TRUE; else code.bWise=FALSE; code.x1 = dCenterX; code.y1 = dCenterY; code.x2 = dStarC; code.y2 = dEndC; code.r1 = dfR; }
本文章只供参考,希望不要用在商业性质上。
相关文章推荐
- C++中的友元 friend
- Class.forName
- 常用的几个提高iOS开发效率的开源类库及工具
- 题目10 统计同成绩学生人数
- 类型转换
- linux 安装jdk
- 多行文字溢出显示省略号函数
- linux文本编辑三剑客之sed
- NoClassDefFoundError
- 先用权人的制造和使用
- Ehcache学习
- HDU 1828 Picture(矩形周长的并+扫描线+离散化)
- [整理]Android测试日志文件抓取与分析
- addChildViewController 用法
- 笔记-大话设计模式-28 访问者模式
- CRC
- WAMP环境搭建
- android task栈和activity的关系
- java之 ------ 类反射【详解】
- 解析ajax核心XMLHTTPRequest对象的创建与浏览器的兼容问题