Java Bresenham三维椭球问题

Java Bresenham三维椭球问题,java,algorithm,math,Java,Algorithm,Math,我正在用体素制作一个椭球体,我有一个实现,但它不能正常工作,在过去的几个小时里,我一直在尝试,但没有成功 下面是它的工作原理: 它使用Bresenham圆算法沿Z轴绘制二维椭圆 它计算一个向前的圆和一个从一边到另一边的圆的坐标 它使用这些坐标作为X和Y的半径 以下是有效的方法: 球体是完美的 椭球是完美的 z>x和z>y x==y 以下是不需要的: 当x!=Y y>x时的示例 当x>y仅翻转时也会发生同样的情况 我猜是因为我每次都从中间到前面画切片,但我不知道。下面是我的实现

我正在用体素制作一个椭球体,我有一个实现,但它不能正常工作,在过去的几个小时里,我一直在尝试,但没有成功

下面是它的工作原理:

  • 它使用Bresenham圆算法沿Z轴绘制二维椭圆
  • 它计算一个向前的圆和一个从一边到另一边的圆的坐标
  • 它使用这些坐标作为X和Y的半径
以下是有效的方法:

  • 球体是完美的
  • 椭球是完美的
    • z>x和z>y
    • x==y
以下是不需要的:

  • 当x!=Y
    • y>x时的示例
    • 当x>y仅翻转时也会发生同样的情况
我猜是因为我每次都从中间到前面画切片,但我不知道。下面是我的实现,一团糟。我很快把它清理了一点,所以在某种程度上它是可以理解的。此外,我正在为以后保存优化,我只希望它现在就可以工作

我不会展示圆算法本身的实现,因为我知道它是有效的,它只会让这个问题变得更长。因此,我将解释它的两个函数

private List 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());
arraylists=getSlice(rz,rx);
ArrayList s2=getSlice(rz,ry);
int cap=Math.max(s2.size(),s.size());
而(s.size()>1)
{
int x=0;
int z=0;
int z2=0;
int y2=0;
int i=cap-2;
如果(s.size()>i)
{
z=s.get(i);
x=s.get(i+1);
s、 移除(i+1);
s、 删除(i);
}
如果(s2.size()>i)
{
z2=s2.get(i);
y2=s2.get(i+1);
s2.移除(i+1);
s2.移除(i);
}
如果(x!=0&&y2!=0)
生成椭圆(z,cx,cy,cz,x,y2);
cap=Math.max(s2.size(),s.size());
一两周前,我问了一个类似的问题(是的,我已经有那么长时间的问题:(),得到了一个答案,我实现了它,它成功了,但我不满意,我想避免浮点数一起出现。请参阅

有了这些,我在舍入数字和获得不均匀切片方面遇到了问题,所以球体是不可能的。具有讽刺意味的是,现在球体是唯一可能的东西(除了前后的椭圆)

编辑:

通过添加,我得到了x>y

else if (y2 < x && ry - y2 != 0)
    generateEllipse(z, cx, cy, cz, x, ry - y2);
else if(y2
|r-y2==0
到底部的第一个测试

我不太清楚为什么会这样,我现在正在弄清楚。但我仍然有y>x的问题。有人吗

编辑2:

现在我看它,它不同于y=x椭球体,回到绘图板

编辑3:

昨晚我在想这个问题,我想我已经弄明白了,这不是我自己问题的答案,但我想指出我所看到的错误。我正在测试第一个列表,并从最大列表的大小递减绘制坐标

这是不好的,因为这两个列表不能保证长度相等,这是我试图匆忙完成一个算法的失败

在图中,你看不到,但小椭圆实际上离大椭圆有几个块远。这是因为没有绘制椭圆,这是因为列表没有数据。实际的小椭圆-大椭圆是因为算法绘制了两个八分之一,这两个八分之一都存储在
getSlice的列表中(…)

那么我该如何解决这个问题呢?我还没有实现任何东西,可能有一段时间也不会实现(现在还早),但这是我的大脑产生的结果。再说一遍,这不是问题的答案,只是想法

我在(!s.isEmpty()时迭代
并在循环外定义两个新值:
incX=s.size
incY=s1.size
我测试它们的z值是否匹配,如果不匹配,我就纠正它。我想我会得到值,测试最大的列表,如果它们不匹配,则将最小列表的inc值减2,然后得到旧值

我测试
!s.isEmpty()
,因为这两个列表将同时为空。同时绘制椭圆,我将使用任意一个z值,因为它们同样应该相等


如果这是错误的,那么我想我有我找到的这个文档要浏览:。

感谢所有查看此文档的人(即使我没有收到任何回复:(),我设置此答案是因为问题已解决,代码如下:

    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();
    }
arraylists=getSlice(rz,rx);
ArrayList s2=getSlice(rz,ry);
布尔值yMax=Math.max(s2.size(),s.size())==s2.size();
int decX=s.size()-1;
int decY=s2.size()-1;
布尔完成=假;
而(!完成)
{
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--);
如果(z!=z2)
{
if(yMax)
{
decX+=2;
x=s.get(decX);
s2.移除(decY+2);
s2.移除(decY+1);
}
其他的
{
decY+=2;
y=s2.get(decY);
s、 移除(decX+2);
s、 移除(decX+1);
}
z=z