用一张图片,在窗口内慢慢的画出一个心形。
在网上搜了下,竟然也没找到一个比较现成的算法,找到一个看起来很漂亮的函数:f(x)=x^(2/3)+(0.9*√(8-x^2))sin(pi*a*x),效果可以看这:https://www.zhihu.com/question/267069065和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
但是我用上面这个函数展示的效果还是不合我预期,我只能自己想办法硬写了个很low的心形,只怪自己数学忘完了:
// 参数分别是: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;
}
}
}
其实就是我一截一截,把心拼出来的。
中间这个大红心就是了,这算是我画的最终结果了,我只是设置了窗口全屏,半透明效果了,所以能看见后面的代码,这和这个心的画法没有关心。当然了上面参数,大小都可以调整,结果是不一样的,但都是一个心形。
其实上面的代码只能画出一个外圈的心,并且我图懒省事,心的下半截也懒的想怎么画,所以连弧度都没有,就是一条直线了。并且我是循环了10次,一直减小偏移量才弄出来个这么效果的,如果再循环几遍,这个心就填满了,就下面这样循环了多次的效果
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);
}