一、软件功能需求
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
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?