在乌龟程序中画一个圆圈

时间:2016-09-22 10:44:56

标签: java processing

我目前正在处理一个Processing(在语言中)草图,它由Turtle逻辑驱动(参见https://en.wikipedia.org/wiki/Turtle_graphics)。这意味着我从当前坐标到提供的坐标绘制一条线。然后,该提供的坐标将成为新的当前坐标。我想近似一个圆,并使用trigonometrics编写了一段简单的代码。代码如下:

void drawCircle(int radius){
   // The circle center is radius amount to the left of the current xpos
   int steps = 16;
   double step = TWO_PI /steps;

   for(double theta = step; theta <= TWO_PI; theta += step){
      float deltaX = cos((float)theta) - cos((float)(theta - step));
      float deltaY = sin((float)theta) - sin((float)(theta - step));

      moveXY(deltaX*radius, deltaY*radius);
   }

}

程序逻辑很简单。它将使用变量theta循环遍历圆中的所有弧度。步数将指示每个theta块的大小。然后,它将计算由theta控制的圆中特定点的x,y值。然后它将扣除前一周期的x,y值(因此为theta-step)以获得从该位置移动到达到期望的x,y位置的量。它最终将这些delta值提供给moveXY函数,该函数从当前点绘制一条线到提供的值,并使它们成为新的当前位置。

使用有限数量的步骤时,该程序似乎运行良好。然而,当步数增加时,圆圈变得越来越像斐波那契螺旋。我的猜测是,这是由于浮点数和正弦和余弦计算不精确,并且每次迭代都会增加。

我解释错了吗?我希望最终将此代码移植到Javascript,所以我在设计中寻找解决方案。使用BigDecimal可能不起作用,特别是因为它不包含自己的余弦和正弦函数。我已经包含了一些图像来详细说明问题。非常感谢任何帮助!

步数16: Step count 16

步数32: Step count 32

步数64: Step count 64

步数128: Step count 128

2 个答案:

答案 0 :(得分:1)

浮点数和正弦/余弦应足够精确。问题是:你在飞机上的位置有多精确?如果以像素为单位测量此位置,则每个步骤后每个浮点值都会舍入为整数。然后精度的损失就会增加。

答案 1 :(得分:0)

在循环的每次迭代中,您正在计算delta而不考虑当前坐标是什么。如此有效,你是“无法估算”,这总是不准确,因为每一步的错误都会累积。

既然你知道你想要一个圆,那么在每次迭代时都会有另一种方法,首先确定你想要到达的圆上的实际点,然后计算三角形到达那里 - 如下所示: (但我必须承认我没有测试过它!):

void drawCircle(int radius){
   // The circle center is radius amount to the left of the current xpos
   int steps = 16;
   double step = TWO_PI /steps;

   float previousX = 0;
   float previousY = radius;

   for(double theta = step; theta <= TWO_PI; theta += step){
       float thisX = radius * sin((float)theta);
       float thisY = radius * cos((float)theta);

       moveXY(thisX - previousX, thisY - previousY);

      previousX = thisX;
      previousY = thisY;
    }

}