C++跳动的心-使用easyx实现

效果图

请添加图片描述

心形函数(也可以使用其他的)

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;
}
  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
``` <!DOCTYPE html> <html> <head> <title></title> </head> <style> * { padding: 0; margin: 0; } html, body { height: 100%; padding: 0; margin: 0; background: #000; } canvas { position: absolute; width: 100%; height: 100%; } .aa { position: fixed; left: 50%; bottom: 10px; color: #ccc; } </style> <body> <canvas id="pinkboard"></canvas> <script> /* * Settings */ var settings = { particles: { length: 500, // maximum amount of particles duration: 2, // particle duration in sec velocity: 100, // particle velocity in pixels/sec effect: -0.75, // play with this for a nice effect size: 30 // particle size in pixels } }; /* * RequestAnimationFrame polyfill by Erik M?ller */ (function () { var b = 0; var c = ["ms", "moz", "webkit", "o"]; for (var a = 0; a < c.length && !window.requestAnimationFrame; ++a) { window.requestAnimationFrame = window[c[a] + "RequestAnimationFrame"]; window.cancelAnimationFrame = window[c[a] + "CancelAnimationFrame"] || window[c[a] + "CancelRequestAnimationFrame"]; } if (!window.requestAnimationFrame) { window.requestAnimationFrame = function (h, e) { var d = new Date().getTime(); var f = Math.max(0, 16 - (d - b)); var g = window.setTimeout(function () { h(d + f); }, f); b = d + f; return g; }; } if (!window.cancelAnimationFrame) { window.cancelAnimationFrame = function (d) { clearTimeout(d); }; } })(); /* * Point class */ var Point = (function () { function Point(x, y) { this.x = typeof x !== "undefined" ? x : 0; this.y = typeof y !== "undefined" ? y : 0; } Point.prototype.clone = function () { return new Point(this.x, this.y); }; Point.prototype.length = function (length) { if (typeof length == "undefined") return Math.sqrt(this.x * this.x + this.y * this.y); this.normalize(); this.x *= length; this.y *= length; return this; }; Point.prototype.normalize = function () { var length = this.length(); this.x /= length; this.y /= length; return this; }; return Point; })(); /* * Particle class */ var Particle = (function () { function Particle() { this.position = new Point(); this.velocity = new Point(); this.acceleration = new Point(); this.age = 0; } Particle.prototype.initialize = function (x, y, dx, dy) { this.position.x = x; this.position.y = y; this.velocity.x = dx; this.velocity.y = dy; this.acceleration.x = dx * settings.particles.effect; this.acceleration.y = dy * settings.particles.effect; this.age = 0; }; Particle.prototype.update = function (deltaTime) { this.position.x += this.velocity.x * deltaTime; this.position.y += this.velocity.y * deltaTime; this.velocity.x += this.acceleration.x * deltaTime; this.velocity.y += this.acceleration.y * deltaTime; this.age += deltaTime; }; Particle.prototype.draw = function (context, image) { function ease(t) { return --t * t * t + 1; } var size = image.width * ease(this.age / settings.particles.duration); context.globalAlpha = 1 - this.age / settings.particles.duration; context.drawImage( image, this.position.x - size / 2, this.position.y - size / 2, size, size ); }; return Particle; })(); /* * ParticlePool class */ var ParticlePool = (function () { var particles, firstActive = 0, firstFree = 0, duration = settings.particles.duration; function ParticlePool(length) { // create and populate particle pool particles = new Array(length); for (var i = 0; i < particles.length; i++) particles[i] = new Particle(); } ParticlePool.prototype.add = function (x, y, dx, dy) { particles[firstFree].initialize(x, y, dx, dy); // handle circular queue firstFree++; if (firstFree == particles.length) firstFree = 0; if (firstActive == firstFree) firstActive++; if (firstActive == particles.length) firstActive = 0; }; ParticlePool.prototype.update = function (deltaTime) { var i; // update active particles if (firstActive < firstFree) { for (i = firstActive; i < firstFree; i++) particles[i].update(deltaTime); } if (firstFree < firstActive) { for (i = firstActive; i < particles.length; i++) particles[i].update(deltaTime); for (i = 0; i < firstFree; i++) particles[i].update(deltaTime); } // remove inactive particles while ( particles[firstActive].age >= duration && firstActive != firstFree ) { firstActive++; if (firstActive == particles.length) firstActive = 0; } }; ParticlePool.prototype.draw = function (context, image) { // draw active particles if (firstActive < firstFree) { for (i = firstActive; i < firstFree; i++) particles[i].draw(context, image); } if (firstFree < firstActive) { for (i = firstActive; i < particles.length; i++) particles[i].draw(context, image); for (i = 0; i < firstFree; i++) particles[i].draw(context, image); } }; return ParticlePool; })(); /* * Putting it all together */ (function (canvas) { var context = canvas.getContext("2d"), particles = new ParticlePool(settings.particles.length), particleRate = settings.particles.length / settings.particles.duration, // particles/sec time; // get point on heart with -PI <= t <= PI function pointOnHeart(t) { return new Point( 160 * Math.pow(Math.sin(t), 3), 130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25 ); } // creating the particle image using a dummy canvas var image = (function () { var canvas = document.createElement("canvas"), context = canvas.getContext("2d"); canvas.width = settings.particles.size; canvas.height = settings.particles.size; // helper function to create the path function to(t) { var point = pointOnHeart(t); point.x = settings.particles.size / 2 + (point.x * settings.particles.size) / 350; point.y = settings.particles.size / 2 - (point.y * settings.particles.size) / 350; return point; } // create the path context.beginPath(); var t = -Math.PI; var point = to(t); context.moveTo(point.x, point.y); while (t < Math.PI) { t += 0.01; // baby steps! point = to(t); context.lineTo(point.x, point.y); } context.closePath(); // create the fill context.fillStyle = "#ea80b0"; context.fill(); // create the image var image = new Image(); image.src = canvas.toDataURL(); return image; })(); // render that thing! function render() { // next animation frame requestAnimationFrame(render); // update time var newTime = new Date().getTime() / 1000, deltaTime = newTime - (time || newTime); time = newTime; // clear canvas context.clearRect(0, 0, canvas.width, canvas.height); // create new particles var amount = particleRate * deltaTime; for (var i = 0; i < amount; i++) { var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random()); var dir = pos.clone().length(settings.particles.velocity); particles.add( canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y ); } // update and draw particles particles.update(deltaTime); particles.draw(context, image); } // handle (re-)sizing of the canvas function onResize() { canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight; } window.onresize = onResize; // delay rendering bootstrap setTimeout(function () { onResize(); render(); }, 10); })(document.getElementById("pinkboard")); </script> </body> </html> ``` ![示例图片](https://devbit-static.oss-cn-beijing.aliyuncs.com/devbit-static/img/heart.png)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值