跳
动
的
爱
心
- LOVE -
完整程序
#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 0c"); //设计程序颜色 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); for (float t = 0.0f;; t += 0.1f) { int sy = 0; float s = sinf(t); float a = s * s * s * s * 0.2f; for (float z = 1.3f; z > -1.2f; z -= 0.1f) { _TCHAR* p = &buffer[sy++][0]; float tz = z * (1.2f - a); for (float x = -1.5f; x < 1.5f; x += 0.05f) { float tx = x * (1.2f + a); float v = f(tx, 0.0f, tz); if (v <= 0.0f) { float y0 = h(tx, tz); float ny = 0.01f; float nx = h(tx + ny, tz) - y0; float nz = h(tx, tz + ny) - y0; float nd = 1.0f / sqrtf(nx * nx + ny * ny + nz * nz); float d = (nx + ny - nz) * nd * 0.5f + 0.5f; *p++ = ramp[(int)(d * 5.0f)]; } else *p++ = ' '; } } for (sy = 0; sy < 25; sy++) { COORD coord = { 0, sy }; SetConsoleCursorPosition(o, coord); WriteConsole(o, buffer[sy], 79, NULL, 0); } Sleep(40); } }
程序分析:
这段代码是一个跳动的爱心,使用了数学函数和控制台输出来实现。下面是具体的分析:
代码的第3到5行是引入所需要的库文件,其中math.h和windows.h是必须的,而tchar.h是用于处理字符串的。
接下来是代码的主要函数f,它用来计算出一个点在三维空间中的函数值,如果这个值小于等于0,则表明这个点在爱心的表面上。
函数h用来计算在给定的x和z坐标下,最高点的y坐标。
在主函数中,首先设置了程序的颜色和控制台的大小。接着通过GetConsoleWindow()获取控制台的句柄,进而获得控制台的大小和位置,计算出它应该出现的位置,并通过SetWindowPos函数移动控制台窗口到指定位置。
进入主循环后,通过sin函数计算出一个s值,用来控制爱心的缩放。然后通过循环输出每一行的字符,根据每个点的函数值计算出它在爱心表面上的位置并输出相应的字符。最后通过SetConsoleCursorPosition和WriteConsole函数输出到控制台上。
通过Sleep函数让程序等待一段时间,实现爱心跳动的效果。
总的来说,这段代码通过控制台输出的方式,利用函数计算出每一个点在爱心表面上的位置,实现了一个动态的、跳动的爱心效果。
运行结果