用 C 编写代码来创建由星号组成的对称五角星,最简单、最有效的方法是什么?

问题描述 投票:0回答:1

Visual Studio 代码。 mingw64 编译器。我正在尝试用 C 语言编写一段代码,该代码能够重新创建一个由星号组成的五角对称星,就像图像Five-pointed symmetric star中提供的那样。图中的星星共有 16 行星号。我已经尝试了几种方法,但终端中显示的结果甚至看起来都不像星星。 Try 1Try 2Try 3

此时我只剩下写一百张带有空格的印刷品了。

这是我尝试编写的代码的最后一个版本,结果给出了菱形,但老实说,我不仅仅是纠正我的代码,我想知道是否有一种更简单、更有效的方法来创建这个星形图案。就像熟悉 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;
}

这是我想重新创建的星星图像,以文本形式发布(?这样看起来不像星星,它只是一堆没有顺序的星号,但如果你们在这里要求的话,它就是。

                *
               ***
              *****
             *******
            *********
**********************************
   ****************************
     ************************
       ********************
        ******************
       ********************
      *********** **********
     *******          *******
    *****                *****
   ***                      ***
  *                            *

以及我用最后一个代码得到的菱形图像也以文本形式发布。 (哦现在,这个看起来就像在终端中一样)

       *
      ***
     *****
    *******
   *********
  ***********
 *************
***************
***************
 *************
  ***********
   *********
    *******
     *****
      ***
       *
c shapes
1个回答
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 的系数。

如果你想避免尾随空格,你应该将扫描线写入缓冲区,然后在打印前修剪掉空格。

© www.soinside.com 2019 - 2024. All rights reserved.