A more earthy but useful method of drawing the heart

background

Using a picture, slowly draw a heart shape in the window.

I searched the Internet, but I didn’t find a relatively ready-made algorithm, and I found a function that looks very beautiful: f(x)=x^(2/3)+(0.9*√(8-x^2)) sin(pi*a*x), the effect can be seen here: https://www.zhihu.com/question/267069065 and https://www.bilibili.com/video/BV1DT4y1E7xW?p=1&share_medium=android&share_plat=android&share_source= COPY&share_tag=s_i×tamp=1592660301&unique_k=kCeiSJ

But the effect I showed with the above function is still not up to my expectations. I can only find a way to write a very low heart shape, only to blame myself for forgetting the math:

Code

// 参数分别是:gdi+的Graphics, 图像信息,绘制的起始位置的横、纵坐标,绘制偏移量,图片宽,高
void drawHeart(::Graphics * graphics, Image* image, int startx, int starty, int offset, int drawWidth, int drawHeight) {
    double posx = startx, posy = starty;
    double pi = acos(-1);
    // 这里可以画心的上半截
    for (double angle = 90; angle > -90;) {
        if (angle > 0) {
            angle -= (8 + max(pow(angle, 2) / 1000, 1));
            posx += offset * cos(pi / 180 * angle);
            posy -= offset * sin(pi / 180 * angle);
        }
        else if (angle > -90) {
            if (angle > -30) {
                angle -= 5;
            }
            else {
                angle -= 10;
            }
            angle = -angle;
            posx += offset * cos(pi / 180 * angle);
            posy += offset * sin(pi / 180 * angle);
            angle = -angle;
        }
        graphics->DrawImage(image, posx, posy, drawWidth, drawHeight);
        graphics->DrawImage(image, sw / 2 - (posx - sw / 2) - drawWidth, posy, drawWidth, drawHeight);
        pause();
    }

    // 这是画心的下半截
    while (posx > startx) {
        posx -= offset * cos(pi / 180 * 30);
        posy += offset * sin(pi / 180 * 60);
        graphics->DrawImage(image, posx, posy, drawWidth, drawHeight);
        graphics->DrawImage(image, sw / 2 - (posx - sw / 2) - drawWidth, posy, drawWidth, drawHeight);

        if (posy > sh) {
            break;
        }
    }
}

In fact, it's me, piece by piece, to spell out my heart.

The big red heart in the middle is just the final result of my painting. I just set the window to full screen with a translucent effect, so I can see the code behind, which has nothing to do with the drawing of the heart. Of course, the above parameters can be adjusted in size, and the result is different, but they are all heart-shaped.

In fact, the above code can only draw a heart with an outer circle, and I am lazy to save trouble, and I am also lazy about how to draw the lower half of the heart, so there is no arc, just a straight line. And I cycled 10 times, and kept reducing the offset to get such an effect. If I cycled again a few times, the heart would be filled up, just like the following cycle many times.

            int offset = drawWidth /5 * 3;
            for (int i = 0; i < 10; i++) {
                drawHeart(&graphics, &image, startx, starty, offset, drawWidth, drawHeight);
                starty += drawHeight / 2 + i;
                offset -= min(2 * i, 2);
            }

 

Guess you like

Origin blog.csdn.net/x763795151/article/details/107308556