起因
在人工智能工具日益强大的今天
如何更高效的进行代码学习
如何借助智能工具实现代码转换?
是否直接可以使用?为何?
如何实现不同的编程语言之间代码的无损转换?
x86与arm
C++
云课五分钟-02第一个代码复现-终端甜甜圈C++-CSDN博客
#include <stdio.h>
#include <math.h>
#include <cstring>
#include <unistd.h>
int main() {
float A = 0, B = 0;
float i, j;
int k;
float z[1760];
char b[1760];
printf("\x1b[2J");
for (;;) {
memset(b, 32, 1760);
memset(z, 0, 7040);
for (j = 0; j < 6.28; j += 0.07) {
for (i = 0; i < 6.28; i += 0.02) {
float c = sin(i);
float d = cos(j);
float e = sin(A);
float f = sin(j);
float g = cos(A);
float h = d + 2;
float D = 1 / (c * h * e + f * g + 5);
float l = cos(i);
float m = cos(B);
float n = sin(B);
float t = c * h * g - f * e;
int x = 40 + 30 * D * (l * h * m - t * n);
int y = 12 + 15 * D * (l * h * n + t * m);
int o = x + 80 * y;
int N = 8 * ((f * e - c * d * g) * m - c * d * e - f * g - l * d * n);
if (22 > y && y > 0 && x > 0 && 80 > x && D > z[o]) {
z[o] = D;
b[o] = ".,-~:;=!*#$@"[N > 0 ? N : 0];
}
}
}
printf("\x1b[H");
for (k = 0; k < 1761; k++) {
putchar(k % 80 ? b[k] : 10);
A += 0.00004;
B += 0.00002;
}
usleep(30000);
}
return 0;
}
Python
import math
import numpy as np
import time
import sys
def main():
A = 0.0
B = 0.0
z = np.zeros(1760)
b = np.array([' '] * 1760, dtype='<U1') # Unicode character array
while True:
b.fill(' ') # Fill the array with spaces
z.fill(0) # Fill z with zeros
for j in np.arange(0, 6.28, 0.07):
for i in np.arange(0, 6.28, 0.02):
c = math.sin(i)
d = math.cos(j)
e = math.sin(A)
f = math.sin(j)
g = math.cos(A)
h = d + 2
D = 1.0 / (c * h * e + f * g + 5)
l = math.cos(i)
m = math.cos(B)
n = math.sin(B)
t = c * h * g - f * e
x = int(40 + 30 * D * (l * h * m - t * n))
y = int(12 + 15 * D * (l * h * n + t * m))
o = x + 80 * y
N = int(8 * ((f * e - c * d * g) * m - c * d * e - f * g - l * d * n))
if 0 < y < 22 and 0 < x < 80 and D > z[o]:
z[o] = D
b[o] = ".,-~:;=!*#$@"[N] if N > 0 else '.'
sys.stdout.write('\x1b[H')
for k in range(1760):
sys.stdout.write(b[k] if k % 80 else '\n')
A += 0.00004
B += 0.00002
sys.stdout.flush()
time.sleep(0.03)
if __name__ == '__main__':
main()
快速实现
echo "终端焦虑的甜甜圈"
git clone https://gitcode.net/ZhangRelay/donut.git
cd ~/donut
g++ colordonut.cpp -o donut
./donut
echo "突破封印的甜甜圈"
这段代码是一个简单的动画程序,它使用了数学函数(如正弦和余弦)来生成一个动态变化的图案,并通过终端或控制台窗口显示。这个程序可能看起来有些复杂,但我们可以逐步解析它的工作原理。
程序流程解析
- 初始化变量:
A
和B
是两个浮点数,用作动画变化的参数。i
和j
是循环变量,用于遍历0
到6.28
(即 2π)的范围,代表角度的变化。k
用于遍历数组。z[1760]
是一个浮点数数组,用于存储每个点上的最大深度值(或亮度)。b[1760]
是一个字符数组,用于存储每个点对应的字符,这些字符将组成显示的图案。
- 清除屏幕:
- 使用
printf("\x1b[2J");
清除终端屏幕。
- 使用
- 双重循环:
- 外层循环
j
和内层循环i
遍历不同的角度,以计算每个点的位置和深度(或亮度)。 - 使用正弦和余弦函数计算各种参数,这些参数用于确定每个点在屏幕上的位置和亮度。
- 外层循环
- 计算和更新屏幕内容:
- 对于每个点
(x, y)
,计算其深度和对应的字符。 - 如果该点的深度大于之前存储的深度(
z[o]
),则更新该点的深度和字符。
- 对于每个点
- 显示图案:
- 使用
printf("\x1b[H");
将光标移动到屏幕左上角。 - 遍历
b
数组,将每个字符输出到终端,并在每80个字符后输出换行符以换行。 - 同时,更新
A
和B
的值,为下一帧做准备。
- 使用
- 延时:
- 使用
usleep(30000);
在每帧之间添加延时,以控制动画的速度。
- 使用
图案的生成
图案的生成基于一系列复杂的数学计算,这些计算涉及到正弦和余弦函数的组合,以及这些函数值的乘法和加法操作。最终,每个点的位置 (x, y)
和亮度(通过 D
和 N
计算)决定了该点在图案中的表示(通过字符数组 b
)。
注意事项
- 这段代码使用了 ANSI 转义序列来清除屏幕和移动光标,这意味着它只在支持这些转义序列的终端中有效。
- 由于使用了浮点数和循环的增量非常小,这个动画可以生成非常平滑和详细的图案。
- 程序的性能可能受到终端处理速度和计算机性能的影响。
b[o] = ".,-~:;=!*#$@"[N > 0 ? N : 0];
这行代码通过N
的值来选择字符,但需要注意的是,N
的计算可能产生超出索引范围的值,但这里通过N > 0 ? N : 0
确保索引不会越界(尽管这种方式可能导致图案的某些部分看起来不够细致)。然而,由于N
的计算复杂且依赖于多个正弦和余弦函数的组合,它很可能在大多数情况下都能产生有效的索引值。
这段Python代码是一个使用NumPy和math库在终端中生成动态图案的脚本。它通过计算每个点的位置和亮度(或深度),并使用不同的字符来表示这些亮度值,从而在终端上创建了一个动画效果。下面是代码的主要部分和它们的作用:
- 初始化变量:
A
和B
是两个浮点数,用作动画中的参数,它们随时间变化以产生动态效果。z
是一个NumPy数组,用于存储每个可能位置上的最大深度值。b
是一个字符类型的NumPy数组,用于存储每个位置对应的字符,这些字符将组成显示的图案。
- 双重循环:
- 外层循环遍历
j
(从0到2π,步长为0.07),内层循环遍历i
(同样从0到2π,但步长为0.02)。这两个循环共同决定了图案中每个点的角度位置。
- 外层循环遍历
- 计算每个点的位置和亮度:
- 使用
math.sin
和math.cos
函数计算各种参数,这些参数与A
、B
以及当前的i
和j
值有关。 - 通过一系列的数学运算,计算出每个点的位置
(x, y)
和亮度D
。 - 亮度
D
通过公式计算得出,并用于确定字符的索引,该索引从字符串".,-~:;=!*#$@"
中选择字符。
- 使用
- 更新屏幕内容:
- 如果计算出的点
(x, y)
在有效范围内(即屏幕内),并且其亮度D
大于之前存储在该位置的亮度,则更新z[o]
和b[o]
。 - 这里,
o
是x
和y
的线性索引,用于将二维位置映射到一维数组中。
- 如果计算出的点
- 显示图案:
- 使用
sys.stdout.write
将光标移动到屏幕左上角,并遍历b
数组,将每个字符输出到终端。 - 每输出80个字符后,输出一个换行符以换行。
- 在输出过程中,同时更新
A
和B
的值,为下一帧做准备。 - 使用
sys.stdout.flush()
确保所有输出都被立即发送到终端。
- 使用
- 延时:
- 使用
time.sleep(0.03)
在每帧之间添加延时,以控制动画的速度。
- 使用
- 循环:
- 整个过程被包裹在一个无限循环中,因此动画将一直运行,直到被外部方式(如用户中断)停止。
注意:
- 这个脚本使用了ANSI转义序列
\x1b[H
来将光标移动到屏幕左上角,这意味着它只能在支持这些转义序列的终端中正常工作。 - 字符数组
b
使用了Unicode字符类型(<U1
),这确保了即使在不同的终端和编码设置下,字符也能正确显示。 - 代码中的
if N > 0 else '.'
确保即使N
计算出的索引超出字符串".,-~:;=!*#$@"
的长度,也会使用.
作为默认值,避免了潜在的索引越界问题。然而,由于N
的计算方式,这种情况在实际应用中不太可能发生。