效果图
心形函数(也可以使用其他的)
x = 16sin(t) ^ 3
y = 13cos(t) - 5cos(2t) - 2cos(3t) - cos(4t)
完整代码
#include <easyx.h>
#include <cmath>
#include <random>
#ifndef PI
#define PI 3.14159265
#endif
#define WIDTH 800 // 画布宽
#define HEIGHT 600 // 画布高
#define HEART_DC_SIZE 10 // 爱心尺寸直流量
#define HEART_AC_SIZE 2 // 爱心尺寸交流量
// 粒子内部扩散率
#define INNER_SPREAD1 0.05
#define INNER_SPREAD2 0.10
// 膨胀阈值尺寸
#define EXPAND_CUTOFF 11
// 轮廓膨胀率
#define OUTLINE_EXPAND 0.2
// 粒子外部扩散率
#define OUTER_SPREAD1 0.05
#define OUTER_SPREAD2 0.10
#define PINK RGB(255,20,147)
#define LIGHT_PINK RGB(255,105,180)
void heart(double _Size, COLORREF _Color, COLORREF _HighLight) {
#define PIXEL_NUM 1024 // 轮廓像素数
#pragma warning(push)
#pragma warning(disable:26451)
double x, y, t[4], step[4], xm, ym[4] = { -13,5,2,1 }, spread, rho, rm;
BYTE i, j;
bool flag;
BeginBatchDraw();
clearrectangle(-WIDTH >> 1, -HEIGHT >> 1, WIDTH >> 1, HEIGHT >> 1);
// 随机数引擎
_STD random_device rd;
_STD mt19937_64 gen(rd());
_STD exponential_distribution<double> dist(1.0);
t[0] = 2 * PI;
step[0] = PI / PIXEL_NUM;
for (i = 1; i < 4; i++) {
j = i + 1;
step[i] = step[0] * j;
t[i] = t[0] * j;
}
xm = 16 * _Size;
for (i = 0; i < 4; i++)
ym[i] *= _Size;
rm = 17 * HEART_DC_SIZE;
for (; t[0] >= 0;) {
// 轮廓
x = xm * pow(sin(t[0]), 3);
y = 0;
for (i = 0; i < 4; i++) {
y += ym[i] * cos(t[i]);
t[i] -= step[i];
}
// 轮廓膨胀
rho = t[0] * 180 / PI;
if (_Size > EXPAND_CUTOFF && 100 <= rho && rho <= 260) {
rho = (rho - 100) / 160 * 2 * PI;
rho = sin(rho);
rho *= rho;
rho = 1 + OUTLINE_EXPAND * rho * (EXPAND_CUTOFF - _Size) / (EXPAND_CUTOFF - HEART_DC_SIZE);
x *= rho;
y *= rho;
}
flag = abs(x / xm) < 0.01;
// 第一层内部扩散
spread = 1 - INNER_SPREAD1 * dist(gen) / (flag ? 3 : 1);
putpixel(x * spread, y * spread, _Color);
// 第二层内部扩散
spread = 1 - INNER_SPREAD2 * dist(gen) / (flag ? 3 : 1);
putpixel(x * spread, y * spread, _Color);
// 第一层外部扩散
spread = 1 + OUTER_SPREAD1 * dist(gen) / (flag ? 3 : 1);
putpixel(x * spread, y * spread, _HighLight);
// 第二层外部扩散
spread = 1 + OUTER_SPREAD2 * dist(gen) / (flag ? 3 : 1);
putpixel(x * spread, y * spread, _HighLight);
}
EndBatchDraw();
#pragma warning(pop)
#undef PIXEL_NUM
}
void play() {
double t = 2 * PI, step = t / 200;
while (1) {
heart(HEART_DC_SIZE + HEART_AC_SIZE * pow(sin(t), 2), PINK, LIGHT_PINK);
if ((t -= step) < 0)
t = 2 * PI;
}
}
int main() {
initgraph(WIDTH, HEIGHT);
setorigin(WIDTH >> 1, HEIGHT >> 1);
play();
return 0;
}