main 中的代码在一段时间内打印一条彩色丝带,当我尝试在用户输入 1 后的一段时间内重复此过程时,该常数会调整可见光中可能的波长(即四个),并将一个字符分配给根据 o 形状的波长指定阵列的位置,否则打印其他颜色的空白空间。
恰巧用户通知1后,在第一次之后又重复了3次,如上面结果的打印,只需要打印一条色带。是什么让它发生? 编译
-lncursesw
环境xfce4-terminal
wprintw(stdscr, "%lc", randomCharacter);
,我注意到每个新条带都包含在不同位置绘制的 randomCharacter
,对应于 adjustedConstant
的四种可能长度之一,因此总共有 4 个条带,而不是 1 个。i == index
这是一种可视化与可见光谱内特定波长相关的颜色的方法。adjustedConstant
给出的公式计算与给定输入相关的波长。如果该波长在可见光范围内(400 nm 到 700 nm 之间),则程序会确定颜色数组中的相应位置,并打印与该波长相关的颜色的随机字符。1n = 2, 2n = 3, Wavelength: 6.564696e-07 meters
1n = 2, 2n = 4, Wavelength: 4.862738e-07 meters
1n=2, 2n=5, Wavelength: 4.341730e-07 meters
1n=2, 2n=6, Wavelength: 4.102935e-07 meters
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <locale.h>
#include <math.h>
typedef struct {
int r;
int g;
int b;
} RGB;
RGB newRGB(int r, int g, int b) {
RGB color;
color.r = r;
color.g = g;
color.b = b;
return color;
}
void calculateColor(RGB *colors, int totalColors, int currentIndex, float saturation, float luminosity);
double adjustedConstant() {
return 1.0973731568508E7 / (1 + 9.10938356E-31 / 1.67262192E-27);
}
int main() {
setlocale(LC_ALL, "");
int totalColors = 60;
RGB colors[totalColors];
float saturation = 1.0;
float luminosity = 0.3;
initscr();
start_color();
int end = totalColors - 18;
int start = end - 42;
for (int i = end; i >= start; i--) {
calculateColor(&colors[i], totalColors, i, saturation, luminosity);
// Convert RGB colors to curses default model
int r = colors[i].r * 1000 / 255;
int g = colors[i].g * 1000 / 255;
int b = colors[i].b * 1000 / 255;
// Set color in curses
init_color(i + 16, r, g, b); // needs to define the pair of colors i+16
init_pair(i + 16, COLOR_BLACK, i + 16);
// Print the color
attron(COLOR_PAIR(i + 16)); // needs to activate the pair of colors i+16
printw(" ");
attroff(COLOR_PAIR(i + 16));
}
// Vector of characters for drawing
int characters[] = {
9474, 9475, 10072, 10073, 12321
};
int numCharacters = sizeof(characters) / sizeof(characters[0]);
// Loop to print the colors on the screen
int wavelength;
while (1) {
int number;
printw("\n\nEnter 1 or -1 to exit: ");
scanw("%d", &number);
if (number == -1) {
break; // Exit the loop if the user enters -1
}
// Wavelength
int n1 = 1, n2 = 2;
double lambda_a = 0;
while (1) {
lambda_a = 1.0 / (adjustedConstant() * ((1.0 / (n1 * n1)) - (1.0 / (n2 * n2))));
if (lambda_a >= 400E-9 && lambda_a <= 700E-9) {
// Calculate the position in the colors array based on the wavelength
int index = (700 - lambda_a * 1e9) * (totalColors - 10.5) / (750 - 380);
// Print all colors
for (int i = end; i >= start; i--) {
if (i == index) {
// Activate the color pair for the corresponding wavelength color
attron(COLOR_PAIR(i + 16));
// Draw one of the characters randomly
int randomCharacter = characters[rand() % numCharacters];
wprintw(stdscr, "%lc", randomCharacter);
// Deactivate the color pair
attroff(COLOR_PAIR(i + 16));
} else {
// Draw empty spaces for the other colors
attron(COLOR_PAIR(i + 16));
printw(" ");
attroff(COLOR_PAIR(i + 16));
}
}
refresh(); // Update the screen
}
if (lambda_a > 700E-9) {
break; // Wavelength exceeded the visible range, end the loop
}
n2++; // Increment the value of 2n
if (n2 <= 6) {
continue;
}
n1++; // Increment the value of 1n and reset 2n to a value greater than 1n
n2 = n1 + 1;
}
}
getch(); // Wait for user input
endwin(); // End curses mode
return 0;
}
void calculateColor(RGB *colors, int totalColors, int currentIndex, float saturation, float luminosity) {
float hue = currentIndex * (360.0 / totalColors);
float chroma = (1 - fabs(2 * luminosity - 1)) * saturation;
float x = chroma * (1 - fabs(fmod(hue / 60, 2) - 1));
float m = luminosity - chroma / 2;
float r, g, b;
if (hue >= 0 && hue < 60) {
r = chroma;
g = x;
b = 0;
} else if (hue >= 60 && hue < 120) {
r = x;
g = chroma;
b = 0;
} else if (hue >= 120 && hue < 180) {
r = 0;
g = chroma;
b = x;
} else if (hue >= 180 && hue < 240) {
r = 0;
g = x;
b = chroma;
} else if (hue >= 240 && hue < 300) {
r = x;
g = 0;
b = chroma;
} else {
r = chroma;
g = 0;
b = x;
}
colors->r = (r + m) * 255;
colors->g = (g + m) * 255;
colors->b = (b + m) * 255;
}
发布的代码中的循环逻辑不正确。
OP 代码具有一个计算可能与光谱吸收线相对应的
lambda_a
值的外循环,以及一个根据与 lambda_a
值关联的颜色索引以块或字符形式打印色谱的内循环。内部循环打印色谱并检查与 lambda_a
关联的索引是否匹配,在这种情况下打印字符,然后在外部循环中修改 lambda_a
。通过此过程,四个 lambda_a
值出现在可见光谱范围 (lambda_a >= 400E-9 && lambda_a <= 700E-9
) 中,因此光谱被打印四次。
更好的方法是计算并缓存与吸收线匹配的颜色索引。然后,当色谱打印一次时,如果颜色索引与缓存索引匹配,则会打印字符。
这里是实现此功能的 OP 代码的修改版本。现在有一个循环,根据原始 OP 代码使用吸收线的颜色索引填充
line_idxs
。接下来是打印光谱的循环。请注意,此代码以相反的顺序逐步执行 line_idxs
,因为颜色的打印顺序是从最高索引到最低索引,而吸收线是按从最低到最高顺序发现的。
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <locale.h>
#include <math.h>
typedef struct {
int r;
int g;
int b;
} RGB;
RGB newRGB(int r, int g, int b) {
RGB color;
color.r = r;
color.g = g;
color.b = b;
return color;
}
void calculateColor(RGB *colors, int totalColors, int currentIndex, float saturation, float luminosity);
double adjustedConstant() {
return 1.0973731568508E7 / (1 + 9.10938356E-31 / 1.67262192E-27);
}
int main(void) {
setlocale(LC_ALL, "");
int totalColors = 60;
RGB colors[totalColors];
float saturation = 1.0;
float luminosity = 0.3;
initscr();
start_color();
int end = totalColors - 18;
int start = end - 42;
for (int i = end; i >= start; i--) {
calculateColor(&colors[i], totalColors, i, saturation, luminosity);
// Convert RGB colors to curses default model
int r = colors[i].r * 1000 / 255;
int g = colors[i].g * 1000 / 255;
int b = colors[i].b * 1000 / 255;
// Set color in curses
init_color(i + 16, r, g, b); // needs to define the pair of colors i+16
init_pair(i + 16, COLOR_BLACK, i + 16);
// Print the color
attron(COLOR_PAIR(i + 16)); // needs to activate the pair of colors i+16
printw(" ");
attroff(COLOR_PAIR(i + 16));
}
// Vector of characters for drawing
int characters[] = {
9474, 12321
};
int numCharacters = sizeof(characters) / sizeof(characters[0]);
// Loop to print the colors on the screen
// int wavelength;
while (1) {
int number;
printw("\n\nEnter 1 or -1 to exit: ");
scanw("%d", &number);
if (number == -1) {
break; // Exit the loop if the user enters -1
}
// Wavelength
int n1 = 1, n2 = 2;
int line_idxs[4] = { 0 }; // Save spectral line indices.
// Populate `line_idxs[]` with spectral lines.
for(size_t i = 0; i < 4;) {
double lambda_a = 0;
lambda_a =(1.0 / (adjustedConstant() * ((1.0 / (n1 * n1)) - (1.0 / (n2 * n2)))));
if (lambda_a >= 400E-9 && lambda_a <= 700E-9) {
line_idxs[i] = start + (700 - lambda_a * 1e9) * (totalColors - 10.5) / (750 - 380);
i++;
}
n2++;
if (n2 <= 6) continue;
n1++;
n2 = n1 + 1;
}
// Print spectrum.
for (int i = end, line_idx = 3; i >= start; i--) {
attron(COLOR_PAIR(i + 16));
if (line_idx >= 0 && i == line_idxs[line_idx]) {
// Print a random character.
int randomCharacter = characters[rand() % numCharacters];
wprintw(stdscr, "%lc", randomCharacter);
--line_idx;
} else {
printw(" ");
}
attroff(COLOR_PAIR(i + 16));
}
refresh(); // Update the screen
}
getch(); // Wait for user input
endwin(); // End curses mode
return 0;
}
void calculateColor(RGB *colors, int totalColors, int currentIndex, float saturation, float luminosity) {
float hue = currentIndex * (360.0 / totalColors);
float chroma = (1 - fabs(2 * luminosity - 1)) * saturation;
float x = chroma * (1 - fabs(fmod(hue / 60, 2) - 1));
float m = luminosity - chroma / 2;
float r, g, b;
if (hue >= 0 && hue < 60) {
r = chroma;
g = x;
b = 0;
} else if (hue >= 60 && hue < 120) {
r = x;
g = chroma;
b = 0;
} else if (hue >= 120 && hue < 180) {
r = 0;
g = chroma;
b = x;
} else if (hue >= 180 && hue < 240) {
r = 0;
g = x;
b = chroma;
} else if (hue >= 240 && hue < 300) {
r = x;
g = 0;
b = chroma;
} else {
r = chroma;
g = 0;
b = x;
}
colors->r = (r + m) * 255;
colors->g = (g + m) * 255;
colors->b = (b + m) * 255;
}
这是结果显示:
功能区被打印多次,因为外循环的条件在 4 次迭代中保持为真。
您应该在色带循环后输出一个
'\n'
,以便所有色带显示对齐而不是垂直对齐,而不是长的缠绕色带。