2012-04-04 111 views
1

我正在做一個橢球體外的體素,我有一個實現,但它不能正常工作,在過去的幾個小時裏,我一直在嘗試沒有成功的事情。Bresenham三維橢球體問題

下面是它如何工作的:

  • 它吸引了2D橢圓下來使用布氏圈算法Z軸
  • 它計算圓的座標前進和一個會一邊到另一邊
  • 它使用這些座標半徑爲X和Y

這裏是什麼工作:

  • 球是完美
  • 橢圓面完美的,當
    • ž> x和z>ÿ
    • X ==Ÿ

這裏是不會:

我猜它,因爲我每次繪製片從中心到前,但我不知道。下面是我的實施,這是一團糟。我很快清理了一下,所以在一定程度上可以理解。此外,我還爲以後節省了優化,我現在只想讓它工作。

我不會顯示我的圓算法本身的實現,因爲我知道它的工作原理,它會讓這個問題變得更長。所以我會解釋它的兩個功能。

private List<Integer> getSlice(int rx, int ry)從Bresenham圓算法運行得到原始結果,不需要對稱。它按照該順序返回結果作爲x,y結果的列表。

public void generateEllipse(int z, int cx, int cy, int cz, int rx, int ry)使用給定的信息生成一個橢圓,並使用對稱來描繪座標,這些將被渲染在屏幕上。

ArrayList<Integer> s = getSlice(rz, rx); 
ArrayList<Integer> s2 = getSlice(rz, ry); 

int cap = Math.max(s2.size(), s.size()); 

while (s.size() > 1) 
{ 
    int x = 0; 
    int z = 0; 
    int z2 = 0; 
    int y2 = 0; 

    int i = cap - 2; 

    if (s.size() > i) 
    { 
     z = s.get(i); 
     x = s.get(i + 1); 

     s.remove(i + 1); 
     s.remove(i); 
    } 

    if (s2.size() > i) 
    { 
     z2 = s2.get(i); 
     y2 = s2.get(i + 1); 

     s2.remove(i + 1); 
     s2.remove(i); 
    } 

    if (x != 0 && y2 != 0) 
     generateEllipse(z, cx, cy, cz, x, y2); 

    cap = Math.max(s2.size(), s.size()); 

我問過類似的問題,一兩個星期回來(是的,我一直有針對的問題:(長),並得到一個答案,我實現了它和它的工作,但我並不滿足,我想避免所有的浮點數一起參見3D Ellipsoid out of discrete units

因爲我在舍入數字和得到不均勻的片時遇到了問題,所以球體是不可能的,具有諷刺意味的是,現在球體是唯一可能的前後橢圓)。

編輯:

我通過在底部加入

else if (y2 < x && ry - y2 != 0) 
    generateEllipse(z, cx, cy, cz, x, ry - y2); 

|| r - y2 == 0於所述第一測試得到了X> Y的工作。

我不太清楚爲什麼這個工作,我現在搞清楚了。但是我仍然遇到了y> x的問題。任何人?

EDIT2:

現在,我看它,它比Y = X橢圓形不同,回到繪圖板。

EDIT3:

昨晚我在想這件事,我想我已經想通了,這不是一個答案,我自己的問題,但我想指出我所看到的是錯誤。我正在測試第一個列表,並從最大列表的大小遞減地繪製座標。

這是不好的,因爲這兩個列表不能保證有相同的長度,這對我來說是一個失敗,因爲我試圖衝過一個算法。

在圖片中,你看不到,但小橢圓實際上距離大橢圓幾個街區。這是由於沒有繪製的橢圓造成的,這是由沒有數據的列表引起的。實際的小橢圓大橢圓是因爲算法繪製了兩個八分圓,這兩個八分圓都存儲在getSlice(...)的列表中。

那麼我該如何解決這個問題呢?我還沒有實現任何東西,可能一段時間(現在還不早),但這是我的腦子發出的。再次,這不是對問題的回答,只是想法。

我重複了while(!s.isEmpty())並在循環外定義了兩個新值:incX = s.sizeincY = s1.size我測試它們的z值是否匹配,如果不匹配,則我糾正它。我想我會得到這些值,測試最大的列表,如果它們不匹配,則將最小列表的公式值減2,並獲得舊值。

我測試!s.isEmpty(),因爲這兩個列表將同時爲空。同時繪製橢圓,我會使用任何一個z值,因爲它們都應該是相等的。

如果這是錯誤的,那麼我想我有這個文件,我發現要經歷:http://www.cs.sunysb.edu/vislab/wordpress/pdf/398.pdf

回答

2

謝謝你的人誰看這個(儘管我沒有得到任何答覆:(),因爲這個問題就解決了我設置這個答案,代碼如下:

ArrayList<Integer> s = getSlice(rz, rx); 
    ArrayList<Integer> s2 = getSlice(rz, ry); 

    boolean yMax = Math.max(s2.size(), s.size()) == s2.size(); 

    int decX = s.size() - 1; 
    int decY = s2.size() - 1; 

    boolean done = false; 

    while (!done) 
    { 

     int x = 0; 
     int z = 0; 
     int z2 = 0; 
     int y = 0; 

     y = s2.get(decY--); 
     z2 = s2.get(decY--); 

     x = s.get(decX--); 
     z = s.get(decX--); 

     if (z != z2) 
     { 
      if (yMax) 
      { 
       decX += 2; 
       x = s.get(decX); 

       s2.remove(decY + 2); 
       s2.remove(decY + 1);  
      } 
      else 
      { 
       decY += 2; 
       y = s2.get(decY); 

       s.remove(decX + 2); 
       s.remove(decX + 1); 
      } 

      z = z < z2 ? z : z2; 
     } 
     else 
     { 
      s.remove(decX + 2); 
      s.remove(decX + 1);    

      s2.remove(decY + 2); 
      s2.remove(decY + 1);  
     } 

     if (y != 0 && x != 0) 
      generateEllipse(z, cx, cy, cz, x, y); 

     done = yMax ? s2.isEmpty() : s.isEmpty(); 
    } 

現在需要完成的所有工作都是優化,我仍然要閱讀這篇文章,它涵蓋了其他對我的程序很有意義和有用的主題:)。

問題是,我沒有考慮到每個列表的不同大小,如果一條曲線比另一條曲線更陡峭,它將會有更多的座標。當rx == ry時Z總是相同的。這使我可以繪製球體和前後橢球體。

當它們不一樣時,z會改變,因爲曲線會更快/更慢。當我在測試第一個列表時發生這種情況時,它會忽略這些列表,因爲迭代在到達它們之前會停止。

大橢圓,小橢圓是由於它們向後拉,導致外八分圓被首先繪製,而恰好總的值較小。

在不久的將來,我會提出一個更詳細的答案和一個更優雅的實現。我只是提出這個答案,讓任何路人知道問題已經解決。我希望沒有人能經歷挫折,我試圖把這件事全部弄清楚!令人驚奇的是,最棘手的問題是最難解決的問題。

+0

快速提示,您的橢球體素需要對齊到3D網格嗎?你似乎暗示了這個限制。 – 2012-04-05 19:17:30

+0

@MichaelSlade 是的,有一個網格。這在我的照片中是可見的。另外在一個側面說明中,我想提到'done'的測試只存在,因爲意外的是當完成時列表不相同。我相信這是一個簡單的解決方法,但是當rz大於rx或ry和rx!= ry時,我注意到這是一個問題。我會做更多的遊戲,我認爲修復很簡單。 – SpaceFace 2012-04-05 19:27:13

+0

Prupel - 我一直在試圖找到一種方法與您取得聯繫。你似乎已經完成了一大堆關於這個我的世界的令人敬畏的工作,我想用你的算法在一個開放源代碼mod中。如果你認爲你不會介意我的話,請與我聯繫。介意與我分享這些。乾杯! espernet irc:mikee – Mikee 2013-07-20 23:06:56