B样条生成,刀轨绘制,生成NC代码

功能需求说明

选用一种高级计算机程序设计语言,编写一个软件,实现列表曲线或曲面的绘制及其刀具加工路径、数控加工程序的生成。软件功能要求:

  • 所设计的软件应具有图形化用户界面(GUI);
  • 用户在软件界面上可用随机数方式或手工方式输入若干曲线或曲面的数据点,例如起点、终点、列表型值点等,对于曲线,还可设置步长参数;对于曲面,还可设置步长与行距参数;曲线或曲面的类型不限。
  • 具有“绘制理想图形”按钮,用户完成数据点与参数输入后,点击该按钮,软件可绘制出理想的曲线或曲面,若该曲线或曲面有特征多边形,则还能通过型值点反算出控制顶点,并绘制出对应的特征多边形;
  • 具有“生成加工路径”按钮,点击该按钮,可根据设定的步长与行距参数自动生成加工该曲线或曲面的刀具路径;(清楚起见,绘制理想图形与刀具路径需用不同颜色)
  • 具有“生成加工程序”按钮,点击该按钮,可自动生成一个实现该曲线或曲面加工的G代码数控加工程序文件。

开发环境说明

软件的开发环境为 win10 + QT 5.12.0;编程语言为C++;
参考书:计算机辅助几何设计与非均匀有理B样条

代码说明

坐标系设置

由于默认界面框的原点在左上角,并且向下为Y+,向右为x+,所以在画图或者鼠标捕捉时,要将其转化到正常的直角坐标系,并绘制坐标系。

void Palette::paintEvent(QPaintEvent *event)//绘图事件
{
    QPainter* painter = new QPainter(this);
    painter->setWindow(-width()/2,height()/2,width(),-height());  //设置窗口,坐标原点在屏幕的正中心

    //绘制x轴
    QPointF startPoint(-295,0);
    QPointF endPoint(295,0);
    double x1, y1, x2, y2; //箭头的两点坐标
    this->calcVertexes(startPoint.x(), startPoint.y(), endPoint.x(), endPoint.y(), x1, y1, x2, y2);//求得箭头两点坐标
    painter->drawLine(startPoint, endPoint);//绘制线段
    painter->drawLine(endPoint.x(), endPoint.y(), x1, y1);//绘制箭头
    painter->drawLine(endPoint.x(), endPoint.y(), x2, y2);//绘制箭头

    //绘制Y轴
    startPoint.setX(0);
    startPoint.setY(-295);
    endPoint.setX(0);
    endPoint.setY(295);

B样条绘制数学原理

B样条递推定义:

{ N i , 0 ( u ) = { 1 , π 4 i u i ⩽ u < u i + 1 0 , 其 他 N i , k ( u ) = u − u i u i + 2 − u i N i , k − 1 ( u ) + u i + u + 1 u i + k + 1 − u i + 1 N i + 1 , k − 1 ( u ) 规 定 = 0 0 = 0 \left\{\begin{array}{l}{\mathrm{N}_{i, 0}(u)=\left\{\begin{array}{ll}{1,} & {\frac{\pi}{4 i} u_{i} \leqslant u<u_{i}+1} \\ {0,} & {\mathbb{其他}}\end{array}\right.} \\ {\mathrm{N}_{i, k}(u)=\frac{u-u_{i}}{u_{i+2}-u_{i}} \mathrm{N}_{i, k-1}(u)+\frac{u_{i}+u+1}{u_{i+k+1}-u_{i+1}} \mathrm{N}_{i+1, k-1}(u)} \\ {\mathrm{规定}=\frac{0}{0}=0}\end{array}\right. Ni,0(u)={1,0,4iπuiu<ui+1Ni,k(u)=ui+2uiuuiNi,k1(u)+ui+k+1ui+1ui+u+1Ni+1,k1(u)=00=0

齐次B样条的节点矢量:

U = [ 0 , 0 , 0 , 0 , l 1 + l 2 L , l 1 + l 2 + l 3 L , ⋯   , l 1 + l 2 + ⋯ + l s − 2 L , 1 , 1 , 1 , 1 ] \mathbf{U}=\left[0,0,0,0, \frac{l_{1}+l_{2}}{L}, \frac{l_{1}+l_{2}+l_{3}}{L}, \cdots, \frac{l_{1}+l_{2}+\cdots+l_{s-2}}{L}, 1,1,1,1\right] U=[0,0,0,0,Ll1+l2,Ll1+l2+l3,,Ll1+l2++ls2,1,1,1,1]

根据数据点反求控制点:

[ b 1 c 1 a 1 a 2 b 2 c 2 ⋱ ⋱ a n − 3 b n − 3 c n − 3 c n − 2 a n − 2 b n − 2 ] [ d 1 d 2 ⋮ d n − 3 d n − 2 ] = [ e 1 e 2 ⋮ e n − 3 e n − 2 ] \left[\begin{array}{ccccc}{b_{1}} & {c_{1}} & {} & {a_{1}} \\ {a_{2}} & {b_{2}} & {} & {c_{2}} \\ {} & {\ddots} & {} & {\ddots} & {} & {} \\ {} & {} & {a_{n-3}} & {} & {b_{n-3}} & {c_{n-3}} \\ {c_{n-2}} & {} & {} & {a_{n-2}} & {b_{n-2}}\end{array}\right]\left[\begin{array}{c}{d_{1}} \\ {d_{2}} \\ {\vdots} \\ {d_{n-3}} \\ {d_{n-2}}\end{array}\right]=\left[\begin{array}{c}{e_{1}} \\ {e_{2}} \\ {\vdots} \\ {e_{n-3}} \\ {e_{n-2}}\end{array}\right] b1a2cn2c1b2an3a1c2an2bn3bn2cn3d1d2dn3dn2=e1e2en3en2
其中:
{ a i = ( Δ i + 2 ) 2 Δ i + Δ i + 1 + Δ i + 2 b i = Δ i + 2 ( Δ i + Δ i + 1 ) Δ i + Δ i + 1 + Δ i + 2 + Δ i + 1 ( Δ 1 + 2 + Δ i + 3 ) Δ i + 1 + Δ i + 2 + Δ i + 3 , i = 1 , 2 , ⋯   , n − 2 c i = ( Δ i + 1 ) 2 Δ i + 1 + Δ i + 2 + Δ i + 3 e i = ( Δ i + 1 + Δ i + 2 ) q i − 1 \left\{\begin{array}{l}{a_{i}=\frac{\left(\Delta_{i+2}\right)^{2}}{\Delta_{i}+\Delta_{i+1}+\Delta_{i+2}}} \\ {b_{i}=\frac{\Delta_{i+2}\left(\Delta_{i}+\Delta_{i+1}\right)}{\Delta_{i}+\Delta_{i+1}+\Delta_{i+2}}+\frac{\Delta_{i+1}\left(\Delta_{1}+2+\Delta_{i+3}\right)}{\Delta_{i+1}+\Delta_{i+2}+\Delta_{i+3}}, \quad i=1,2, \cdots, n-2} \\ {c_{i}=\frac{\left(\Delta_{i+1}\right)^{2}}{\Delta_{i+1}+\Delta_{i+2}+\Delta_{i+3}}} \\ {e_{i}=\left(\Delta_{i+1}+\Delta_{i+2}\right) q_{i-1}}\end{array}\right. ai=Δi+Δi+1+Δi+2(Δi+2)2bi=Δi+Δi+1+Δi+2Δi+2(Δi+Δi+1)+Δi+1+Δi+2+Δi+3Δi+1(Δ1+2+Δi+3),i=1,2,,n2ci=Δi+1+Δi+2+Δi+3(Δi+1)2ei=(Δi+1+Δi+2)qi1

边界条件:抛物线条件

a 1 = 1 − Δ 3 Δ 4 ( Δ 3 + Δ 4 ) 2 a_{1}=1-\frac{\Delta_{3} \Delta_{4}}{\left(\Delta_{3}+\Delta_{4}\right)^{2}} a1=1(Δ3+Δ4)2Δ3Δ4
b 1 = Δ 3 Δ 3 + Δ 4 ( Δ 4 Δ 3 + Δ 4 − Δ 3 Δ 3 + Δ 4 + Δ 5 ) b_{1}=\frac{\Delta_{3}}{\Delta_{3}+\Delta_{4}}\left(\frac{\Delta_{4}}{\Delta_{3}+\Delta_{4}}-\frac{\Delta_{3}}{\Delta_{3}+\Delta_{4}+\Delta_{5}}\right) b1=Δ3+Δ4Δ3(Δ3+Δ4Δ4Δ3+Δ4+Δ5Δ3)
c 1 = ( Δ 3 ) 2 ( Δ 3 + Δ 4 ) ( Δ 3 + Δ 4 + Δ 3 ) c_{1}=\frac{\left(\Delta_{3}\right)^{2}}{\left(\Delta_{3}+\Delta_{4}\right)\left(\Delta_{3}+\Delta_{4}+\Delta_{3}\right)} c1=(Δ3+Δ4)(Δ3+Δ4+Δ3)(Δ3)2
e 1 = 1 3 ( q 0 + 2 q 1 ) e_{1}=\frac{1}{3}\left(q_{0}+2 q_{1}\right) e1=31(q0+2q1)
a n − 1 = − ( Δ n ) 2 ( Δ n − 1 + Δ n ) ( Δ n − 1 + Δ n − 1 + Δ n ) a_{n-1}=-\frac{\left(\Delta_{n}\right)^{2}}{\left(\Delta_{n-1}+\Delta_{n}\right)\left(\Delta_{n-1}+\Delta_{n-1}+\Delta_{n}\right)} an1=(Δn1+Δn)(Δn1+Δn1+Δn)(Δn)2
b n − 1 = Δ n Δ n − 1 + Δ n ( Δ n Δ n − 1 + Δ n − 1 + Δ n Δ n − 1 Δ n − 1 + Δ n ) b_{n-1}=\frac{\Delta_{n}}{\Delta_{n-1}+\Delta_{n}}\left(\frac{\Delta_{n}}{\Delta_{n-1}+\Delta_{n-1}+\Delta_{n}} \quad \frac{\Delta_{n-1}}{\Delta_{n-1}+\Delta_{n}}\right) bn1=Δn1+ΔnΔn(Δn1+Δn1+ΔnΔnΔn1+ΔnΔn1)
c n − 1 = Δ n − 1 Δ n ( Δ n − 1 + Δ n ) 2 − 1 c_{n-1}=\frac{\Delta_{n-1} \Delta_{n}}{\left(\Delta_{n-1}+\Delta_{n}\right)^{2}}-1 cn1=(Δn1+Δn)2Δn1Δn1
e n − 1 = − 1 3 ( q n + 2 q n − 1 ) e_{n-1}=-\frac{1}{3}\left(q_{n}+2 q_{n-1}\right) en1=31(qn+2qn1)

相关代码如下:

B样条递推定义:

void Palette::generateCurve()//生成曲线,根据B样条定义
{
    curvePoints.clear();
    int i=3;
    for(double u1=0; u1<1; u1+=0.001)
    {
        QPointF tmp(0,0);
        if (u1 > u[i+1])
        {
            i=i+1;
        }
        for(int k=0; k<4;k++)
        {
            QPointF t = ctrlPoints[i-k];

            t=t*Nu(i-k,u1,3);

            tmp=tmp+t;
        }
        curvePoints.push_back(tmp);//尾部插入数据tmp
    }
}

齐次B样条的节点矢量:

//节点向量设置
     //u[0]-u[3]赋值为0
     for(int i=0;i<4;i++)
       {
          palette->u[i]=0;
       }

     //u[10]-u[13]赋值为1
     for(int i=0;i<4;i++)
       {
          palette->u[i+10]=1;
       }

     //u[4]-u[9]的值:
     palette->u[4]=l[0]/L;
     palette->u[5]=(l[0]+l[1])/L;
     palette->u[6]=(l[0]+l[1]+l[2])/L;
     palette->u[7]=(l[0]+l[1]+l[2]+l[3])/L;
     palette->u[8]=(l[0]+l[1]+l[2]+l[3]+l[4])/L;
     palette->u[9]=(l[0]+l[1]+l[2]+l[3]+l[4]+l[5])/L;

根据数据点反求控制点以及抛物线条件:

     double detal[13];

     //对u[0]-u[12]进行u[i+1]-u[i],前后之差放入detal[i]
     for(int i=0;i<13;i++)
     {
         detal[i]=palette->u[i+1]-palette->u[i];   //detl[i]=u[i+1]-u[i]
     }

     //抛物线条件a[0]->f[0]
     double a[8],b[8],c[8],e[8],f[8];  //角标0-8
     a[0]=1-(detal[3]*detal[4])/pow((detal[3]+detal[4]),2);
     b[0]=(detal[3]/(detal[3]+detal[4]))*(detal[4]/(detal[3]+detal[4])-detal[3]/(detal[3]+detal[4]+detal[5]));
     c[0]=(pow((detal[3]),2))/((detal[3]+detal[4])*(detal[3]+detal[4]+detal[5]));
     e[0]=(1.0/3)*(palette->typepoints[0].x()+2*palette->typepoints[1].x());  //X轴坐标
     f[0]=(1.0/3)*(palette->typepoints[0].y()+2*palette->typepoints[1].y());  //Y轴坐标

     //抛物线条件a[7]->f[7]
     a[7]=-(pow((detal[9]),2))/((detal[8]+detal[9])*(detal[8]+detal[8]+detal[9]));
     b[7]=(detal[9]/(detal[8]+detal[9]))*(detal[9]/(detal[8]+detal[8]+detal[9])-detal[8]/(detal[8]+detal[9]));
     c[7]=detal[8]*detal[9]/pow((detal[8]+detal[9]),2)-1;
     e[7]=-(1.0/3)*(palette->typepoints[7].x()+2*palette->typepoints[6].x());
     f[7]=-(1.0/3)*(palette->typepoints[7].y()+2*palette->typepoints[6].y());

     //抛物线条件a[1]->f[1]....a[6]->f[6]
     for(int i=1;i<7;i++)
     {
         a[i]=(pow((detal[i+3]),2))/(detal[i+1]+detal[i+2]+detal[i+3]);
         b[i]=detal[i+3]*(detal[i+1]+detal[i+2])/(detal[i+1]+detal[i+2]+detal[i+3])+detal[i+2]*(detal[i+3]+detal[i+4])/(detal[i+2]+detal[i+3]+detal[i+4]);
         c[i]=pow((detal[i+2]),2)/(detal[i+2]+detal[i+3]+detal[i+4]);
         e[i]=(detal[i+2]+detal[i+3])*palette->typepoints[i].x();
         f[i]=(detal[i+2]+detal[i+3])*palette->typepoints[i].y();
     }

     //8*8矩阵置0
     double matrix[8][8];//定义8*8矩阵
     for(int i=0;i<8;i++)
     {
        for(int j=0;j<8;j++)
        {
            matrix[i][j]=0;
        }
     }

     //对系数矩阵赋值
     matrix[0][0]=a[0];
     matrix[0][1]=b[0];
     matrix[0][2]=c[0];
     for(int i=1;i<7;i++)
     {
         matrix[i][i-1]=a[i];
         matrix[i][i]=b[i];
         matrix[i][i+1]=c[i];
     }

     matrix[7][5]=a[7];
     matrix[7][6]=b[7];
     matrix[7][7]=c[7];

最终效果

生成曲线
在这里插入图片描述
[1]: https://blog.csdn.net/qq_32059343/article/details/86408359
[2]: 计算机辅助几何设计与非均匀有理B样条

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值