我正在用体素制作一个椭圆体,并且我有一个实现,但它不能正常工作,在过去的几个小时里,我一直在尝试没有成功的事情。
以下是它的工作原理:
- 它使用 Bresenham 圆算法沿 Z 轴绘制 2D 椭圆
- 它计算一个向前和一边到另一边的圆的坐标
- 它使用这些坐标作为 X 和 Y 的半径
这是有效的:
- 球体是完美的
- 椭球体是完美的
- z > x 和 z > y
- x == y
这是没有的:
- x != y 时的椭球体
- y > x 时的示例http://postimage.org/image/gslvykrgd/
- 当 x > y 只翻转时也会发生同样的事情
我猜是因为我每次都从中心到前面绘制切片,但我不知道。下面是我的实现,一团糟。我很快把它清理了一下,所以在某种程度上是可以理解的。另外我正在为以后保存优化,我只想让它现在工作。
我不会展示我对圆算法本身的实现,因为我知道它可以工作,而且只会让这个问题变得更长。所以我将解释它的两个功能。
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 distinct units。
有了这个,我在四舍五入和得到不均匀的切片时遇到了问题,所以球体是不可能的。具有讽刺意味的是,现在球体是唯一可能的东西(除了从前到后的椭圆)。
编辑:
我通过添加 x > y 工作
else if (y2 < x && ry - y2 != 0)
generateEllipse(z, cx, cy, cz, x, ry - y2);
并|| r - y2 == 0
到底部的第一个测试。
我不太确定为什么会这样,我现在正在弄清楚。但我仍然遇到 y > x 的问题。任何人?
编辑2:
现在我看它,它与 y = x 椭球不同,回到绘图板上。
编辑3:
昨晚我在想这个,我想我已经想通了,这不是我自己问题的答案,但我想指出我所看到的错误。我正在测试第一个列表并从最大列表的大小递减地绘制坐标。
这很糟糕,因为不能保证两个列表的长度相等,这是我试图加速算法的失败。
在图片中,你看不到,但小椭圆实际上距离大椭圆有几个街区。这是由于未绘制椭圆而引起的,这是由于列表没有数据引起的。实际的小椭圆大椭圆是因为算法绘制了两个八分圆,这两个八分圆都存储在列表中getSlice(...)
。
那么我该如何解决这个问题呢?我还没有实现任何东西,可能暂时不会(现在还早),但这就是我的大脑所产生的结果。同样,这不是问题的答案,只是想法。
我while(!s.isEmpty())
在循环外迭代并定义了两个新值:incX = s.size
然后incY = s1.size
测试它们的 z 值是否匹配,如果不匹配,则进行更正。我想我会得到这些值,测试最大的列表,如果它们不匹配,那么将最小列表的 inc 值减 2 并获取旧值。
我测试是!s.isEmpty()
因为这两个列表将同时为空。同样绘制椭圆,我将使用任何一个 z 值,因为同样,它们都应该相等。
如果那是错误的,那么我想我找到了这份文件:http ://www.cs.sunysb.edu/vislab/wordpress/pdf/398.pdf 。