Visual Studio 代码。 mingw64 编译器。我正在尝试用 C 语言编写一段代码,该代码能够重新创建一个由星号组成的五角对称星,就像图像中提供的那样。图中的星星共有 16 行星号。我已经尝试了几种方法,但终端中显示的结果甚至看起来都不像星星。
此时我只剩下写一百张带有空格的印刷品了。
这是我尝试编写的代码的最后一个版本,结果给出了菱形,但老实说,我不仅仅是纠正我的代码,我想知道是否有一种更简单、更有效的方法来创建这个星形图案。就像熟悉 c 语言的人会如何做一样。谢谢,我只是C语言的初学者。
#include <stdio.h>
int main() {
int i, j, k;
int size = 16;
int mid = size / 2;
for (i = 1; i <= mid; i++) {
// Print leading spaces
for (j = i; j < mid; j++) {
printf(" ");
}
for (k = 1; k <= (2 * i - 1); k++) {
printf("*");
}
printf("\n");
}
for (i = 1; i <= mid; i++) {
for (j = 1; j < i; j++) {
printf(" ");
}
for (k = (2 * (mid - i + 1) - 1); k > 0; k--) {
printf("*");
}
printf("\n");
}
return 0;
}
这是我想重新创建的星星图像,以文本形式发布(?这样看起来不像星星,它只是一堆没有顺序的星号,但如果你们在这里要求的话,它就是。
*
***
*****
*******
*********
**********************************
****************************
************************
********************
******************
********************
*********** **********
******* *******
***** *****
*** ***
* *
以及我用最后一个代码得到的菱形图像也以文本形式发布。 (哦现在,这个看起来就像在终端中一样)
*
***
*****
*******
*********
***********
*************
***************
***************
*************
***********
*********
*******
*****
***
*
一个简单的方法是使用数学。如果您将星形定义为特定顺序的一系列线(例如逆时针),那么您可以确定点位于每个线段的哪“一侧”。
为此,请计算从一个顶点到另一个顶点的向量,然后将其与从您的点到同一顶点的向量相交。要位于 5 角星形内,这些叉积中至少有 4 个必须具有相同的符号(或为零)。
现在,您可以对星形中的任意点进行“内部”测试。这意味着您可以在扫描线中计算它,与标准输出兼容。
示例:
#include <stdio.h>
int main() {
int width = 39;
int height = 16;
int verts[5][2] = {
{ width/2, 0 }, // top
{ width/8, height-1 }, // bottom-left
{ width-1, height*3/8 }, // right
{ 0, height*3/8 }, // left
{ width-1-width/8, height-1 }, // bottom-right
};
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// To be within star, a point must be on the same side of at least 4 lines.
// Use cross product to determine that.
int left_count = 0;
for (int v = 0; v < 5; v++) {
int vx = verts[v][0] - verts[(v+4)%5][0];
int vy = verts[v][1] - verts[(v+4)%5][1];
int dx = verts[v][0] - x;
int dy = verts[v][1] - y;
int cross = vx * dy - vy * dx;
if (cross >= 0) left_count++;
}
printf("%s", left_count >= 4 ? "*" : " ");
}
printf("\n");
}
return 0;
}
输出:
*
***
*****
*******
*********
***********
***************************************
*******************************
***********************
*******************
*********************
***********************
********* *********
****** ******
*** ***
* *
这是一个非常基本的例子。如果需要,您可以预先计算线段。请注意,我使用了单独的宽度和高度,以便控制纵横比。为了考虑矩形字符,我在这里使用大约 2.5 的系数。
如果你想避免尾随空格,你应该将扫描线写入缓冲区,然后在打印前修剪掉空格。