2016-09-22 82 views
1

我目前正在研究處理(如在語言中)的草圖,這是由海龜邏輯驅動的(請參閱https://en.wikipedia.org/wiki/Turtle_graphics)。這意味着我從當前座標畫出一條直線到一個提供的座標。這個提供的座標將成爲新的當前座標。我想近似一個圓,並使用三角函數寫了一段簡單的代碼。代碼如下所示:在烏龜程序中畫一個圓圈

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

回答

1

浮球和正弦/餘弦應足夠精確。問題是:你在飛機上的位置有多精確?如果這個位置是以像素爲單位進行測量的,那麼在每一步之後,您的每個浮點值都被四捨五入爲整數。然後精度的損失加起來。

+0

位置變量被存儲爲int,並且這導致了偏差。將其切換到浮動狀態後,錯誤得到糾正。我所有的圈子都是完美的! – Diaita

0

在循環的每次迭代中,您都在計算增量而不考慮當前座標是什麼。如此有效地,你是「無法估算的」,這總是不準確的,因爲每一步都會產生錯誤。

既然你知道你想要一個圓,另一種方法是在每一次迭代中,首先確定你想要到達的圓上的實際點,然後計算到達那裏的三角洲 - 所以像以下(但我必須承認我還沒有測試過!):

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; 
    } 

} 
+0

但由於職位是由相同的算法生成的,職位應該幾乎相同。問題結果是保存了職位。解決這個問題會產生完美的圈子不過謝謝你的貢獻。 – Diaita