既然要画正弦波形,那就得先来了解正弦波,要绘制正弦波,其函数必须要了解。下面重拾高中知识,再一次再进正弦函数
(资料图)
正弦函数的物理意义:
y = A * sin(ωx + φ) ,A叫做振幅,T = 2π/ω叫做周期,f = 1/T = ω/2π叫做频率,ω叫角频率,ωx + φ叫做相位,x = 0时的相位φ称为初相
由y = sin(x)的图像通过变换得到y = A * sin(ωx + φ)
1.振幅变换:
y = Asin(x)的图像可以看座把正弦曲线上的所有点的纵坐标伸长(A>1)或缩短(0<ω<1)原来的A倍得到的(横坐标不变),它的值域为[-A, A],最大值是A,最小值是-A。如A<0可先作y = -Asin(x)的图像,再以x轴为对称轴翻折。A称为振幅
2.周期变换:
y = sin(ωx)的图像,可看作把正弦曲线上的所有点的横坐标缩短(ω>1)或伸长(0<ω<1)到原来的1/ω倍(纵坐标不变)。若ω<0则可用诱导公式将符号“提出”再作图。ω决定了函数的周期
3.相位变换:
y = sin(x + φ)的图像,可以看作把正弦曲线上所有点向左(当φ>0时)或向右(当φ<0时)平行移动|φ|个单位长度而得到。(即左加右减)
一般的,函数y = A * sin(ωx + φ)的图像可以看作是用下面的方法得到的:
(1)先把y = sin(x)的图像上所有的点向左(φ>0)或向右(φ<0)平行移动|φ|个单位
(2)再把所得的点的横坐标缩短(ω>1)或伸长(0<ω<1)到原来的1/ω倍(纵坐标不变)
(3)再把所得的各点的纵坐标伸长(A>1)或缩短(0
了解了正弦函数的物理意义之后,就可以开始结合我们的场景进行画图
首先qt画图的坐标系是x向右,y向下为正方向,假设屏幕就显示一个周期,即2π/ω = 屏幕的宽,振幅A可自行定义选择,通过改变相位φ的值实现左右移动的动画效果,这样就能以像素为单位的一个正弦图,函数为y = A * sin(ωx + φ),x和y的单位为像素,把整个图像向下移动就得到y = A * sin(ωx + φ) + k;
有了函数图像就可以画图了
以一个周期为例,以屏幕的宽的像素为x值,遍历从0->屏幕的宽,就可以得到对应的y的坐标,把所得的y的坐标画线连起来,就得到对应的图形。动画效果就是不断按顺序改变相位φ就能得到连续变化的正弦图。
这就是整个绘制正弦图的原理。
下面看代码:
void WavePlotAnimal::initUi(){m_pTimer = new QTimer(this);m_pTimer->setInterval(160);connect(m_pTimer, &QTimer::timeout, this, &WavePlotAnimal::onTimeout);QPushButton *startBtn = new QPushButton(this);connect(startBtn, &QPushButton::clicked, this, [=](){m_pTimer->start();});}void WavePlotAnimal::paintEvent(QPaintEvent *event){QPainter painter(this);(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);(QColor("#87CEFA"));(Qt::NoPen);(this->rect());// (QRect(0, 0, this->width(), 768), m_bg);// (QRect(width()/2 - 111, 270, 222, 164), m_logoBg);// (QRect(width()/2 - 119, 447, 237, 81), m_nameBg);//起始点坐标和结束点坐标int startX = 0;// int startY = 300;int endX = width() - 0;int endY = height() - 0;//第一条波浪路径集合QPainterPath waterPath1;//第二条波浪路径集合QPainterPath waterPath2;//第三条波浪路径集合QPainterPath waterPath3;QPainterPath waterPath4;//移动到左上角起始点(startX, endY);(startX, endY);(startX, endY);(startX, endY);//正弦曲线公式 y = A * qSin(ωx + φ) + k//A表示振幅,可以理解为水波的高度//k表示y轴偏移,控制在垂直方向显示的位置//φ控制x轴偏移,通过定时器控制实现动画效果//w表示周期,可以理解为水波的密度,值越大密度越大(浪越密集 ^_^),取值 密度*M_PI/宽度double w = Density*M_PI/this->width();offset += ;for(int i = 0; i <= this->width(); i++){double y1 = (double)(50 * sin(-w * i + offset)) + 718;double y2 = (double)(60 * sin(-w * i + offset + 200*w)) + 688;double y3 = (double)(60 * sin(-w/2*i + offset + 400*w)) + 728;double y4 = (double)(60 * sin(-w * i + offset - 300*w)) + 708;(i, y1);(i, y2);(i, y3);(i, y4);}//形成闭合路径(endX, endY);(endX, endY);(endX, endY);(endX, endY);//颜色及透明度设置QColor waterColor1 = Qt::white;(255);QColor waterColor2 = QColor("#7cc4c9");(85);QColor waterColor3 = QColor("#1c8584");(150);QColor waterColor4 = QColor("#d4fdd8");(70);//绘制(waterColor2);(waterPath2);(waterColor3);(waterPath3);(waterColor4);(waterPath4);(waterColor1);(waterPath1);QWidget::paintEvent(event);}void WavePlotAnimal::onTimeout(){update();}
【领 QT开发教程 学习资料, 点击下方链接莬费领取↓↓ ,先码住不迷路~】
点击这里:
Copyright @ 2015-2022 华东家电网版权所有 备案号: 京ICP备2022016840号-41 联系邮箱:2 913 236 @qq.com