DXF中polyline的凸度计算

曾几何时自己写了读取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;

}

      }

 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值