将正弦波打印到控制台

Printing a Sine Wave to the Console

我正在开发一个 Java 程序,可以将正弦波打印到控制台。这是我到目前为止写的:

int num = 7;
for (double y = 2; y >= 0; y-=0.2) {
  for (double x = 0; x <= num; x+=0.2) {
    if ( ((0.1+x) >= Math.asin((double)y-1)) && (((double)x-0.1) <= Math.asin((double)y-1)) )
      System.out.print('*');
    else
      System.out.print(' ');
  }
  System.out.println();
}

本质上,该程序将每行中的每个字符视为坐标平面上的 0.2 x 0.2 区域。如果正弦函数穿过这个区域,屏幕上会打印一个星号。否则,将打印 space。 当 运行 时,将打印到控制台:

        *                          
     *                             
   *                               
  *                                
 *                                 
*                                  

谁能告诉我为什么我的程序在打印第一四分之一波后停止了?

编辑:糟糕,浏览代码有点太快了。这是错误的。

好吧,您将 num 设置为 7,然后在循环中将 x 从 0 取到 num-1,因此您只循环 7 列。增加 num 并且您的图形应该添加额外的列。如果您希望图表扩展到负数,您也必须增加循环的 y 值的范围。

但是,您的算法效率极低。您正在为图表上的每个正方形计算两次 asin(y-1),而您真正需要做的只是为每一列计算一次 sin(x)。为什么不直接用预先计算的正弦值填充一个数组,然后在绘制图形时参考该数组? (当然,我意识到,在现代计算机上,它的速度足够快,实际上无论哪种方式都无关紧要。)

问题似乎是由您的 if 语句的条件引起的,它的计算结果几乎总是 false。您应该检查条件表达式背后的微积分。我发现增加 num 在这里并没有真正帮助。

也许您应该打印另一个字符而不是空格,例如将 System.out.print(' '); 替换为 System.out.print('_');。这样您就可以弄清楚为什么您的程序会这样运行。修改您的算法也可能有所帮助。

它只打印正弦波的第一季度的原因是因为指定的 range of Math.asin:

Returns the arc sine of a value; the returned angle is in the range -pi/2 through pi/2.

一旦 x 超过 Math.PI / 2,则 if 语句的条件将始终为 false.

您可以利用

sin(π - x) = sin(x)

sin(2π - x) = -sin(x)

包括更多条件。 (为了清楚起见,我还删除了对 double 的不必要的强制转换。)

if ( (0.1+x >= Math.asin(y-1)) && (x-0.1 <= Math.asin(y-1)) ||
     (0.1+x >= Math.PI - Math.asin(y-1)) && (x-0.1 <= Math.PI - Math.asin(y-1))
     (2*Math.PI -(0.1 + x) <= -Math.asin(y-1)) && (2*Math.PI -(x-0.1) >= -Math.asin(y-1))  )

输出:

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

谢谢大家的帮助!根据@dasblinkenlight 的建议使用 sin 而不是 asin,我找到了一个非常简单的解决方案:

int num = 7;
for (double y = 1; y >= -1; y-=0.2) {
  for (double x = 0; x <= num; x+=0.2) {
    double sin = Math.sin(x);
    if ( (0.1+y) >= sin && (y-0.1) <= sin )
      System.out.print('*');
    else
      System.out.print(' ');
  }
  System.out.println();
}

这会将其打印到控制台:

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