Since you want to draw sine wave, you must first understand sine wave. To draw sine wave, its function must be understood. Let's pick up the knowledge of high school and enter the sinusoidal function again
Physical meaning of sine function:
y = A * sin( ω x + φ) , A is called amplitude, T = 2 π/ ω It's called a period, f = 1/T= ω/ 2 π is called frequency, ω It's called angular frequency, ω x + φ It's called phase, the phase at x = 0 φ It is called primary phase
From the image of y = sin(x), y = a * sin is obtained by transformation( ω x + φ)
1. Amplitude conversion:
The image of y = Asin(x) can be viewed by extending (a > 1) or shortening (0) the ordinates of all points on the sinusoidal curve< ω< 1) It is obtained by multiplying the original a times (the abscissa remains unchanged). Its value range is [- A, A], the maximum value is a and the minimum value is - A. If a < 0, the image of y = -Asin(x) can be made first, and then folded with the X axis as the symmetry axis. A is called amplitude
2. Periodic transformation:
y = sin( ω x) The image can be regarded as shortening the abscissa of all points on the sinusoidal curve( ω> 1) Or elongation (0)< ω< 1) To the original 1/ ω Times (ordinate unchanged). if ω< 0, the symbol can be "raised" by the induction formula and then plotted. ω Determines the period of the function
3. Phase conversion:
y = sin(x + φ) The image can be regarded as turning all points on the sinusoidal curve to the left (when φ> 0) or right (when φ< 0) parallel movement| φ| A unit length. (i.e. left plus right minus)
In general, the function y = a * sin( ω x + φ) The image can be regarded as obtained by the following method:
(1) First, turn all points on the image with y = sin(x) to the left( φ> 0) or right( φ< 0) parallel movement| φ| Units
(2) Then shorten the abscissa of the obtained point( ω> 1) Or elongation (0)< ω< 1) To the original 1/ ω Times (ordinate unchanged)
(3) Then extend (A > 1) or shorten (0 < A < 1) the ordinate of each point to the original A times (the abscissa remains unchanged)
After understanding the physical meaning of sinusoidal function, we can start drawing combined with our scene
First of all, the coordinate system of qt drawing is x to the right and y to the down as the positive direction. Suppose that the screen displays A period, that is, 2 π/ ω = The screen width and amplitude A can be defined and selected by changing the phase φ To achieve the animation effect of moving left and right, so that A sinusoid in pixels can be obtained, and the function is y = A * sin( ω x + φ), The units of X and y are pixels. Move the whole image downward to get y = A * sin( ω x + φ) + k;
With the function image, you can draw the picture
Take a cycle as an example, take the wide pixels of the screen as the x value, traverse from 0 - > the width of the screen, you can get the corresponding y coordinates, and connect the obtained y coordinates with lines to get the corresponding graphics. The animation effect is to constantly change the phases in order φ You can get a sinusoidal graph that changes continuously.
This is the principle of drawing sine diagram.
Look at the code below:
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); painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); painter.setBrush(QColor("#87CEFA")); painter.setPen(Qt::NoPen); painter.drawRect(this->rect()); // painter.drawPixmap(QRect(0, 0, this->width(), 768), m_bg); // painter.drawPixmap(QRect(width()/2 - 111, 270, 222, 164), m_logoBg); // painter.drawPixmap(QRect(width()/2 - 119, 447, 237, 81), m_nameBg); //Start point coordinates and end point coordinates int startX = 0; // int startY = 300; int endX = width() - 0; int endY = height() - 0; //First wave path set QPainterPath waterPath1; //Second wave path set QPainterPath waterPath2; //Third wave path set QPainterPath waterPath3; QPainterPath waterPath4; //Move to top left starting point waterPath1.moveTo(startX, endY); waterPath2.moveTo(startX, endY); waterPath3.moveTo(startX, endY); waterPath4.moveTo(startX, endY); //Sinusoidal formula y = a * qsin( ω x + φ) + k //A represents the amplitude, which can be understood as the height of the water wave //k represents the y-axis offset and controls the position displayed in the vertical direction //φ Control the x-axis offset and realize the animation effect through timer control //w represents the period, which can be understood as the density of water wave. The greater the value, the greater the density (the denser the wave ^ ^ ^), and the value is density * M_PI / width double w = Density*M_PI/this->width(); offset += 0.6; 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; waterPath1.lineTo(i, y1); waterPath2.lineTo(i, y2); waterPath3.lineTo(i, y3); waterPath4.lineTo(i, y4); } //Form a closed path waterPath1.lineTo(endX, endY); waterPath2.lineTo(endX, endY); waterPath3.lineTo(endX, endY); waterPath4.lineTo(endX, endY); //Color and transparency settings QColor waterColor1 = Qt::white; waterColor1.setAlpha(255); QColor waterColor2 = QColor("#7cc4c9"); waterColor2.setAlpha(85); QColor waterColor3 = QColor("#1c8584"); waterColor3.setAlpha(150); QColor waterColor4 = QColor("#d4fdd8"); waterColor4.setAlpha(70); //Draw path painter.setBrush(waterColor2); painter.drawPath(waterPath2); painter.setBrush(waterColor3); painter.drawPath(waterPath3); painter.setBrush(waterColor4); painter.drawPath(waterPath4); painter.setBrush(waterColor1); painter.drawPath(waterPath1); QWidget::paintEvent(event); } void WavePlotAnimal::onTimeout() { update(); }