欢迎光临
我们一直在努力

C语言实现控制台爱心:静态渐变与3D动态粒子

引言

 本文核心主题

本文将深入解析两款控制台爱心图形代码——静态渐变爱心与3D动态粒子爱心的实现逻辑。

 代码功能概述

  • 静态爱心:基于笛卡尔心形公式,通过计算像素到爱心中心的距离实现多梯度粉色系渐变,在控制台固定位置绘制出视觉层次感的爱心图形。
  • 3D动态粒子爱心:基于3D心形隐函数建模,结合时间因子驱动的动画逻辑与帧刷新机制,实现粒子化、波动效果的3D动态爱心,支持ESC键退出交互。
  • 数学基础:2D笛卡尔心形公式$(x²+y²-1)³ – x²y³ ≤ 0$、3D心形隐函数$f(x,y,z)$;勾股定理计算距离、三角函数($\\sin$)实现动画波动、法线向量计算实现视觉亮度映射。
  • 心形隐函数推导:笛卡尔心形公式$(x²+y²-1)³ – x²y³ ≤ 0$是判定坐标点是否在爱心区域的核心,公式中$x$、$y$为数学坐标系下的坐标,满足公式的点即属于爱心范围。
  • 颜色控制封装:setColor函数封装SetConsoleTextAttribute,通过传入不同颜色宏(如FOREGROUND_RED)快速切换文本颜色。

附录

  • 完整可运行源代码(静态/动态版本)
  • 静态代码:

    #include <stdio.h>
    #include <windows.h>
    #include <math.h>

    void setColor(int textColor) {
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hConsole, textColor);
    }

    void initConsole() {
    system("cls");
    system("mode con cols=80 lines=40");
    system("chcp 65001 >nul");
    SetConsoleTitleA("正立彩色爱心 – 最终修复版");
    }

    int isInHeart(float x, float y) {
    float scale = 6.0f;
    float xScaled = x / scale;
    float yScaled = y / scale;
    float eq = pow(xScaled*xScaled + yScaled*yScaled – 1, 3) – xScaled*xScaled * pow(yScaled, 3);
    return eq <= 0;
    }

    int main() {
    initConsole();

    const int COLOR_LIGHT_PINK = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
    const int COLOR_PINK = FOREGROUND_RED | FOREGROUND_BLUE;
    const int COLOR_ROSE = FOREGROUND_RED | FOREGROUND_INTENSITY;
    const int COLOR_RED = FOREGROUND_RED;
    const int COLOR_DEEP_RED = FOREGROUND_RED | FOREGROUND_INTENSITY;

    int offsetX = 40;
    int offsetY = 20; // 调整垂直偏移,让爱心更居中

    // 正立爱心:Y轴从上往下遍历,同时传入方程时翻转Y值
    for (int y = offsetY – 8; y <= offsetY + 8; y++) {
    for (int x = offsetX – 10; x <= offsetX + 10; x++) {
    COORD pos = {x, y};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);

    // 关键修复:将控制台Y值取反后传入方程
    float heartX = x – offsetX;
    float heartY = -(y – offsetY); // 翻转Y轴方向

    if (isInHeart(heartX, heartY)) {
    float distance = sqrt(pow(heartX, 2) + pow(heartY, 2));
    if (distance < 2) {
    setColor(COLOR_DEEP_RED);
    } else if (distance < 4) {
    setColor(COLOR_RED);
    } else if (distance < 6) {
    setColor(COLOR_ROSE);
    } else if (distance < 8) {
    setColor(COLOR_PINK);
    } else {
    setColor(COLOR_LIGHT_PINK);
    }
    printf("*");
    }
    }
    }

    setColor(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    COORD endPos = {0, offsetY + 10};
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), endPos);
    printf("\\n");

    return 0;
    }

    实现效果如下图(有点丑):

  • 动态代码爱心:

  • #include <stdio.h>
    #include <math.h>
    #include <windows.h>
    #include <string.h>

    // 3D爱心核心公式
    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.005f)
    if (f(x, y, z) <= 0.0f)
    return y;
    return 0.0f;
    }

    int main() {
    // 1. 控制台初始化(一次性设置到位,避免兼容性问题)
    system("cls");
    system("mode con cols=80 lines=30"); // 固定窗口大小
    system("chcp 936 >nul"); // GBK编码
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTitleA("终极稳定3D爱心");

    // 隐藏光标,避免闪烁
    CONSOLE_CURSOR_INFO cursor = {1, FALSE};
    SetConsoleCursorInfo(hConsole, &cursor);

    // 2. 固定字符梯度和颜色(避免视觉混乱)
    char ramp[] = " .:-=+*#%@";
    int color = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; // 固定粉色
    SetConsoleTextAttribute(hConsole, color);

    // 3. 帧缓冲区(精确匹配窗口大小)
    char buffer[30][81]; // 30行×80列,每行1位结束符

    // 4. 主循环(彻底解决残留、错位问题)
    for (float t = 0.0f;; t += 0.05f) {
    // 彻底清空缓冲区,确保无残留
    memset(buffer, ' ', sizeof(buffer));
    for (int i = 0; i < 30; i++) buffer[i][80] = '\\0';

    int sy = 0;
    float s = sinf(t);
    float a = s * s * s * s * 0.15f;

    // 精确控制z轴循环,确保不越界
    for (float z = 1.4f; z > -1.3f && sy < 30; z -= 0.09f) {
    char *p = buffer[sy++];
    float tz = z * (1.2f – a);

    // 精确控制x轴循环,确保不越界
    for (float x = -1.6f; x < 1.6f && p – buffer[sy-1] < 80; 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;

    // 确保索引不越界
    int idx = (int)(d * 9.0f);
    idx = idx < 0 ? 0 : (idx > 9 ? 9 : idx);
    *p++ = ramp[idx];
    } else {
    *p++ = ' ';
    }
    }
    }

    // 光标定位到左上角,确保无错位
    COORD pos = {0, 0};
    SetConsoleCursorPosition(hConsole, pos);

    // 输出完整30行,覆盖整个控制台
    for (int i = 0; i < 30; i++) {
    printf("%s\\n", buffer[i]);
    }

    Sleep(30);

    // ESC退出
    if (GetAsyncKeyState(VK_ESCAPE) & 0x8000) {
    break;
    }
    }

    // 恢复控制台默认样式
    SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
    system("cls");
    printf("程序已退出\\n");
    return 0;
    }

    实现效果如下图所示:

赞(0)
未经允许不得转载:171主机测评 » C语言实现控制台爱心:静态渐变与3D动态粒子
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址