ボクセルから楕円体を作成していて、実装がありますが、正しく機能していません。過去数時間、試行錯誤を繰り返してきましたが、成功しませんでした。
仕組みは次のとおりです。
- Bresenham円アルゴリズムを使用してZ軸に2D楕円を描画します
- 前方の円と左右に向かう円の座標を計算します
- これらの座標をXとYの半径として使用します
動作するものは次のとおりです。
- 球は完璧です
- 楕円体は次の場合に最適です
- z>xおよびz>y
- x == y
そうでないものは次のとおりです。
- x!=yの場合の楕円体
- y> xhttp://postimage.org/image/gslvykrgd/の場合の例
- x>yが反転しただけでも同じことが起こります
毎回中央から前にスライスを描いているので推測していますが、わかりません。以下は私の実装です、それは混乱です。すぐに少しクリーンアップしたので、ある程度理解できます。また、後で使用するために最適化を保存しています。今すぐ機能させたいだけです。
サークルアルゴリズム自体の実装については説明しません。これは、サークルアルゴリズムが機能することを知っており、この質問が長くなるだけだからです。そこで、代わりに2つの機能について説明します。
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());
私は1、2週間前に同様の質問をしました(ええ、私は長い間問題を抱えていました:()そして答えを得ました、私はそれを実装しました、そしてそれはうまくいきました、しかし私は満足しませんでした、私は浮動小数点数を避けたいです個別のユニットからの3D楕円体を参照してください。
それで、数字を四捨五入して不均一なスライスを取得するのに問題があったので、球は不可能でした。皮肉なことに、現在可能なのは球だけです(前から後ろへの楕円を除く)。
編集:
追加することでx>yが機能するようになりました
else if (y2 < x && ry - y2 != 0)
generateEllipse(z, cx, cy, cz, x, ry - y2);
一番下の|| r - y2 == 0
最初のテストに。
なぜそれがうまくいったのかよくわかりません、私は今それを理解しています。しかし、私はまだy>xの問題を抱えています。誰?
EDIT2:
これを見てみると、y = x楕円体とは異なり、製図板に戻ります。
EDIT3:
昨夜私はこれについて考えていました、そして私はそれを理解したと思います、これは私自身の質問への答えではありません、しかし私は私が間違っていると見ているものを指摘していると思います。最初のリストをテストし、最大のリストのサイズから徐々に座標を描画しています。
2つのリストが同じ長さであることが保証されていないため、これは悪いことです。これは、アルゴリズムを急がせようとした私の側の失敗です。
写真では見えませんが、小さな楕円は実際には大きな楕円から数ブロック離れています。これは、楕円が描画されていない場合に発生します。これは、リストにデータがないことが原因です。実際の小さな楕円の大きな楕円は、アルゴリズムが2つの八分円を描画するために発生します。これらは両方とも、からリストに格納されgetSlice(...)
ます。
では、どうすればこの問題を解決できますか?私はまだ何も実装しておらず、おそらくしばらくは実装しないでしょう(それは早いです)が、これは私の脳がクランクアウトしたものです。繰り返しますが、これは質問に対する答えではなく、単なる考えです。
while(!s.isEmpty())
ループの外側で2つの新しい値を繰り返し定義します。incX = s.size
そしてincY = s1.size
、それらのz値が一致するかどうかをテストし、一致しない場合は修正します。値を取得し、最大のリストをテストし、それらが一致しない場合は、最小のリストのinc値を2つ減らして、古い値を取得すると思います。
!s.isEmpty()
2つのリストが同時に空になるため、テストします。また、楕円を描画する場合は、どちらか1つのz値を使用します。これも、両方が等しくなければならないためです。
それが間違っている場合は、私が見つけたこのドキュメントを持っていると思います:http ://www.cs.sunysb.edu/vislab/wordpress/pdf/398.pdf 。