赞
踩
选用一种高级计算机程序设计语言,编写一个软件,实现列表曲线或曲面的绘制及其刀具加工路径、数控加工程序的生成。软件功能要求:
软件的开发环境为 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样条递推定义:
{
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\{
齐次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+⋯+ls−2,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[
其中:
{
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\{
边界条件:抛物线条件
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)}
an−1=−(Δn−1+Δn)(Δn−1+Δn−1+Δ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)
bn−1=Δn−1+ΔnΔn(Δn−1+Δn−1+ΔnΔnΔn−1+ΔnΔn−1)
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
cn−1=(Δn−1+Δn)2Δn−1Δn−1
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)
en−1=−31(qn+2qn−1)
相关代码如下:
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样条
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。