我正在用体素制作一个椭圆体,我有一个实现,但它没有正常工作,在过去的几个小时里,我一直在尝试没有成功的事情。
以下是它的工作原理:
这是有效的:
这不是:
我猜它是因为我每次都从中心到前面画切片,但我不知道。下面是我的实现,这是一团糟。我很快就清理了一下,所以在某种程度上这是可以理解的。此外,我正在为以后保存优化,我只是想让它现在正常工作。
我不会展示我对圆形算法本身的实现,因为我知道它的工作原理并且只会让这个问题变得更长。所以我将为它解释两个函数。
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。
由于这个问题,我在修补数字和获得不均匀的切片时遇到了问题,所以球体是不可能的。具有讽刺意味的是,现在球体是唯一可能的(除了前后椭圆)。
编辑:
我得到x&gt; y通过添加
工作else if (y2 < x && ry - y2 != 0)
generateEllipse(z, cx, cy, cz, x, ry - y2);
和|| r - y2 == 0
到底部的第一个测试。
我不太确定为什么会这样,我现在正在考虑这个问题。但我仍然遇到y&gt;的问题。 X。任何人吗?
EDIT2:
现在我看着它,它与y = x椭圆体不同,回到绘图板。
EDIT3:
昨晚我在想这个,我想我已经弄明白了,这不是我自己问题的答案,但我想指出我看到的错误。我正在测试第一个列表,并从最大列表的大小开始逐渐绘制坐标。
这是不好的,因为两个列表不能保证相同的长度,这是我试图赶紧算法的失败。
在图片中,你看不到,但是小椭圆实际上距离大椭圆几个街区。这是由未绘制的省略号引起的,这是由没有数据的列表引起的。导致实际的小椭圆大椭圆是因为算法绘制了两个八分圆,两个八分圆都存储在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。
答案 0 :(得分: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会发生变化,因为曲线会更快/更慢。当我在测试第一个列表时发生这种情况时,它会忽略这些,因为迭代会在它到达之前停止。
大椭圆,小椭圆是由于它们被向后拉动而引起的,因此首先绘制外部八分圆,其总值较少。
在不久的将来,我会提出更详细的答案和更优雅的实施方案。我只是提出这个答案,让任何一个路人都知道问题已经解决了。我希望没有人能够经历过我试图弄清楚这一切的挫败感!令人惊讶的是,最棘手的问题是由最愚蠢的事情引起的。