您当前的位置: 首页 > 

phymat.nico

暂无认证

  • 5浏览

    0关注

    1967博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

B样条数据点反求控制点绘制曲线(源码)

phymat.nico 发布时间:2020-01-16 14:19:01 ,浏览量:5

一、软件功能需求

1)所设计的软件应具有图形化用户界面(GUI);

2)用户在软件界面上可用随机数方式或手工方式输入若干曲线或曲面的数据点,例如起点、终点、列表型值点等,对于曲线,还可设置步长参数;对于曲面,还可设置步长与行距参数;曲线或曲面的类型不限。

3)具有“绘制理想图形”按钮,用户完成数据点与参数输入后,点击该按钮,软件可绘制出理想的曲线或曲面,若该曲线或曲面有特征多边形,则还能通过型值点反算出控制顶点,并绘制出对应的特征多边形;

4)具有“生成加工路径”按钮,点击该按钮,可根据设定的步长与行距参数自动生成加工该曲线或曲面的刀具路径;

5)具有“生成加工程序”按钮,点击该按钮,可自动生成一个实现该曲线或曲面加工的G代码数控加工程序文件。 二、B样条反求控制点原理

 

参考书籍:计算机辅助几何设计与非均匀有理B样条(一般学校的电子图书馆可以在线阅读)

P212页:B样条递推定义

P237页:齐次B样条曲线的节点矢量

P257页:反算三次B样条插值曲线的控制顶点

P259页:边界条件:抛物线条件

二、软件实现

软件平台:Windows7   Qt5.9.3     语言:C++

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

    QPainter* painter = new QPainter(this);         painter->setWindow(-width()/2,height()/2,width(),-height());  //设置坐标原点在屏幕的正中心           //    painter->drawLine(-296,0,296,0);     //    painter->drawLine(0,296,0,-296);         //绘制x轴         QPointF startPoint(-295,0);         QPointF endPoint(295,0);         double x1, y1, x2, y2; //箭头的两点坐标         //求得箭头两点坐标         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);         //求得箭头两点坐标         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);//绘制箭头另一半      

    void Palette::calcVertexes(double start_x, double start_y, double end_x, double end_y, double& x1, double& y1, double& x2, double& y2)     {     double arrow_lenght_ = 10;//箭头长度,一般固定     double arrow_degrees_ = 0.5;//箭头角度,一般固定           double angle = atan2(end_y - start_y, end_x - start_x) + 3.1415926;//           x1 = end_x + arrow_lenght_ * cos(angle - arrow_degrees_);//求得箭头点1坐标     y1 = end_y + arrow_lenght_ * sin(angle - arrow_degrees_);     x2 = end_x + arrow_lenght_ * cos(angle + arrow_degrees_);//求得箭头点2坐标     y2 = end_y + arrow_lenght_ * sin(angle + arrow_degrees_);     }

    采用随机数生成8个随机点,对第一组随机数进行排序,第二组随机数不排序,填充到QTableWidget。

    void MainWindow::on_general_random_clicked()     {         QVector a;    //定义一个vector容器         srand((int)time(NULL));  //时间作为种子         for (int i=0;isetItem(i,0,new QTableWidgetItem(QString("%1").arg(a[i])));         }         a.remove(0,8);  //删去第一列               srand((int)time(NULL));         for (int i=0;isetItem(i,1,new QTableWidgetItem(QString("%1").arg(a[i])));             ui->model->setItem(i,2,new QTableWidgetItem(QString("%1").arg(0)));         }     }

 

    获取数据点,根据数据点反求控制点。

    void MainWindow::on_general_curve_clicked()     {         QPoint point;         QPoint start,end;         QString QTW_data1,QTW_data2;         double a1,a2;         //提取数据表中数据           for(int i=0; imodel->item(i, 0)->text();               QTW_data2=ui->model->item(i, 1)->text();                     a1=QTW_data1.toDouble();               a2=QTW_data2.toDouble();                     point.setX(a1);               point.setY(a2);               if(i==0)               {                   start.setX(a1);                   start.setY(a2);               }               if(i==7)               {                   end.setX(a1);                   end.setY(a2);               }                     palette->typepoints.append(point);                      }           /*             此段程序将数据点反求出控制点,八个数据点           */           double l[7];  //存放数据点之间的距离,l[0]代表第一个数据点到第二个数据点之间的距离           double L=0;//存放总长度           for(int i=0;itypepoints[i+1].x()-palette->typepoints[i].x()),2)+                       pow((palette->typepoints[i+1].y()-palette->typepoints[i].y()),2)); //两点之间距离公式                      L=L+l[i];           }           //节点矢量计算           for(int i=0;iu[i]=0;           }           for(int i=0;iu[i+10]=1;           }           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;           for(int i=0;i

关注
打赏
1659628745
查看更多评论
立即登录/注册

微信扫码登录

0.0846s