C/C++跳动的爱心②

写在前面

这是一段使用C语言编写的控制台程序,用于在Windows命令行中动态绘制一颗跳动的爱心。通过数学函数建模与字符渲染技术,程序模拟了三维爱心的形状,并使其具有动态效果。整个过程融合了数学建模、图形渲染和控制台操作技术,展现了如何在有限的控制台环境中实现复杂的视觉表现。

系列文章

序号 直达链接
1 C/C++李峋同款跳动的爱心
2 C/C++跳动的爱心
3 C/C++经典爱心
4 C/C++满屏飘字
5 C/C++大雪纷飞
6 C/C++黑客帝国字母雨
7 C/C++樱花树
8 C/C++奥特曼
9 C/C++精美圣诞树
10 C/C++俄罗斯方块小游戏
11 C/C++贪吃蛇小游戏
12 C/C++孤单又灿烂的神
13 C/C++闪烁的爱心
14 C/C++哆啦A梦
15 C/C++简单圣诞树
16 C/C++小宇宙
17 C/C++冰墩墩
18 C/C++七彩花朵
19 C/C++玫瑰花
20 C/C++小猪佩奇
21 C/C++简易爱心
22 C/C++流星雨①
23 C/C++2048小游戏
24 C/C++爱心圣诞树
25 C/C++文字跑马灯
26 C/C++教师工作量管理系统
27 C/C++满天繁星
28 C/C++漂浮爱心
29 C/C++五子棋小游戏
30 C/C++球球大作战小游戏
31 C/C++走迷宫小游戏
32 C/C++粉色爱心
33 C/C++棕色小熊
34 C/C++粉色动态爱心
35 C/C++炫酷烟花①
36 C/C++炫酷烟花②
37 C/C++炫酷烟花③
38 C/C++炫酷烟花④
39 C/C++星空漩涡
40 C/C++流星雨②
敬请期待......

技术需求

  1. 数学建模与几何表达
  • 隐函数定义 :使用自定义函数f(x, y, z)描述爱心的三维几何形状,通过复杂的多项式运算实现非线性曲面建模。
  • 高度场计算 :通过函数h(x, z)计算爱心表面在特定x、z坐标下的y值,用于生成三维表面的投影信息。
  1. 控制台图形渲染
  • 字符灰度映射 :使用字符集.:-=+*#%@表示不同的亮度等级,通过法向量计算得到的光照强度映射到字符上,实现三维效果。
  • 缓冲区绘制:使用二维字符数组作为绘制缓冲区,先在内存中完成整帧图像的构建,再一次性输出到控制台,避免画面闪烁。
  1. 系统级控制台操作
  • 窗口居中显示:通过Windows API获取屏幕分辨率和窗口尺寸,计算并设置控制台窗口的位置,使其居中显示,提升用户体验。
  • 颜色与窗口设置 :使用system函数设置控制台背景色和窗口尺寸,优化视觉呈现效果。
  1. 动态效果实现
  • 时间参数驱动 :通过主循环中的时间变量t驱动爱心的变形,利用三角函数生成周期性变化的比例因子,实现跳动效果。
  • 实时渲染与刷新 :在循环中不断重新计算并渲染每一帧图像,通过Sleep函数控制帧率,保持动画流畅性。
  1. 光照与视觉增强
  • 法向量与光照计算:通过数值微分方法计算爱心表面的法向量,结合光照模型计算每个点的亮度值,增强立体感。
  • 视角变换:根据时间参数动态调整x、z坐标的缩放比例,模拟视角变化,增强动态效果。

主要代码

创作不易,订阅后可查看完整代码

c 复制代码
#include <stdio.h>
#include <math.h>
#include <windows.h>
#include <tchar.h>
 
float f(float x, float y, float z) {
	float a = x * x + 9.0f / 4.0f * y * y + z * z - 1;
	return a * a * a - x * x * z * z * z - 9.0f / 80.0f * y * y * z * z * z;
}
 
float h(float x, float z) {
	for (float y = 1.0f; y >= 0.0f; y -= 0.001f)
		if (f(x, y, z) <= 0.0f)
			return y;
	return 0.0f;
}
 
int main() {
	system("color fc"); //设计程序颜色
	system("mode con cols=60 lines=28");  //设计控制台大小
	HANDLE o = GetStdHandle(STD_OUTPUT_HANDLE);
	_TCHAR buffer[25][80] = { _T(' ') };
	_TCHAR ramp[] = _T(".:-=+*#%@");
 
	HWND consoleHandle = GetConsoleWindow();
 
	// 获取系统屏幕分辨率
	int screenWidth = GetSystemMetrics(SM_CXSCREEN);
	int screenHeight = GetSystemMetrics(SM_CYSCREEN);
 
	// 获取窗口大小
	RECT consoleRect;
	GetWindowRect(consoleHandle, &consoleRect);
	int consoleWidth = consoleRect.right - consoleRect.left;
	int consoleHeight = consoleRect.bottom - consoleRect.top;
 
	// 计算窗口应该出现的位置
	int x = (screenWidth - consoleWidth) / 2;
	int y = (screenHeight - consoleHeight) / 2;
 
	// 使用SetWindowPos函数设置新的窗口位置
	SetWindowPos(consoleHandle, 0, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
 
......

创作流程

在创作这段代码时,我的初衷是用最朴素的控制台环境展现一个生动的爱心形象。这个想法源于对数学之美的敬畏和对编程艺术的热爱。我想要挑战在没有图形库支持的条件下,如何用字符和数学公式构建出具有生命力的视觉作品。

首先,我需要一个数学模型来描述爱心的形状。经过一番思考,我选择了一个经典的三维隐函数来表达爱心的几何结构。这个函数包含了复杂的多项式运算,能够生成一个具有心形轮廓的三维曲面。为了让这个曲面能够在二维屏幕上呈现,我设计了函数h(x, z)来计算每个(x, z)坐标对应的y值,这实际上是在构建一个高度场。

在渲染方面,我决定使用字符画的方式。我精心挑选了一组从暗到亮的字符,构成一个灰度渐变序列。为了让爱心看起来更立体,我引入了光照模型。通过计算每个点的法向量,并结合光源方向,我可以得到该点的亮度值,然后映射到字符灰度序列上。这种做法让爱心表面具有了明暗变化,增强了立体感。

为了实现动态效果,我在主循环中引入了时间参数。通过正弦函数生成周期性变化的比例因子,我可以让爱心在一定范围内收缩和膨胀,模拟跳动的效果。同时,我还根据时间参数调整了视角,让爱心在跳动的同时还带有一点旋转的感觉,使动画更加生动。

在控制台操作方面,我希望程序运行时能给用户带来更好的体验。因此,我对控制台窗口进行了定制,包括设置背景颜色、调整窗口大小,并将窗口居中显示在屏幕中央。这些细节处理虽然不复杂,但却能让整个作品显得更加专业和精致。

整个创作过程中,我不断地在数学精度和程序性能之间寻找平衡。比如在计算高度场时,我需要在精度和速度之间做出权衡,最终选择了合适的步长。在字符渲染时,我也考虑了字符的密度和视觉效果,选择了最能表现灰度变化的字符组合。

当我第一次看到控制台中那颗跳动的爱心时,内心充满了成就感。这不仅是一个技术实现,更是一种情感的表达。在这个由代码和数学构建的世界里,我找到了技术与艺术的完美结合点。

写在后面

我是一只有趣的兔子,感谢你的喜欢!

相关推荐
无能者狂怒15 分钟前
YOLO C++ Onnx Opencv项目配置指南
c++·opencv·yolo
集智飞行37 分钟前
c++函数传参的几种推荐方式
开发语言·c++
鼾声鼾语1 小时前
matlab的ros2发布的消息,局域网内其他设备收不到情况吗?但是matlab可以订阅其他局域网的ros2发布的消息(问题总结)
开发语言·人工智能·深度学习·算法·matlab·isaaclab
麦麦鸡腿堡1 小时前
Java_类的加载
java·开发语言
我命由我123451 小时前
VSCode - Prettier 配置格式化的单行长度
开发语言·前端·ide·vscode·前端框架·编辑器·学习方法
JIngJaneIL2 小时前
基于java + vue校园快递物流管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js
超级大只老咪2 小时前
数组的正向存储VS反向存储(Java)
java·开发语言·python
柏木乃一2 小时前
进程(2)进程概念与基本操作
linux·服务器·开发语言·性能优化·shell·进程
毕设源码-赖学姐2 小时前
【开题答辩全过程】以 基于JSP的物流信息网的设计与实现为例,包含答辩的问题和答案
java·开发语言
leo__5202 小时前
基于LDA的数据降维:原理与MATLAB实现
开发语言·matlab·信息可视化