java - 布雷森汉姆3d椭球问题

标签 java algorithm math

我正在用体素制作一个椭球体,我有一个实现,但它不能正常工作,在过去的几个小时里,我一直在尝试一些没有成功的事情。
其工作原理如下:
利用Bresenham圆算法绘制Z轴上的2D椭圆
它计算一个圆向前和一个圆对一个圆的坐标
它用这些坐标作为X和Y的半径
以下是有效的方法:
球体是完美的

z>x和z>y
x==y轴
以下是不需要的:
椭圆体当X!=年
当y>xhttp://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 discrete units
有了这个,我在取整数字和得到不均匀的切片方面遇到了问题,所以球体是不可能的。讽刺的是,现在球体是唯一可能的东西(除了前后椭圆)。
编辑:
我通过添加
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.sizeincY = s1.size我测试它们的z值是否匹配,如果不匹配,那么我会更正它。我想我会得到这些值,测试最大的列表,如果它们不匹配,那么将最小列表的inc值减2,得到旧的值。
我测试!s.isEmpty(),因为这两个列表将同时为空同时画椭圆,我将使用任意一个z值,因为它们应该相等。
如果这是错误的,那么我想我已经找到了这个文件,我要通过:http://www.cs.sunysb.edu/vislab/wordpress/pdf/398.pdf

最佳答案

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

    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将改变,因为曲线将更快/更慢。当我在测试第一个列表时发生这种情况时,它会忽略这些,因为迭代会在到达它们之前停止。
大椭圆,小椭圆是因为它们是向后画的,所以先画外八度角,这正好有较少的总值。
在不久的将来,我将提出一个更详细的答案和一个更优雅的实现。我提出这个答案是为了让路人知道问题已经解决了。我不想让任何人经历我试图解决这件事的挫折!令人惊奇的是,最困难的问题是由最愚蠢的事情引起的。

关于java - 布雷森汉姆3d椭球问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10016002/

相关文章:

java - Android 淡入图像

java - Spring RESTful 应用程序中的 HTTP POST 请求

Java 从二进制文件中转换字符

java - Java 中 TSP 的分支定界实现

function - 在编程中实现微积分函数,即 f(x)

c++ - Cuda 数学与 C++ 数学

java - 用Java PreparedStatemen执行一批SQL命令后参数值会自动清零吗?

algorithm - Scala 函数式快速排序

algorithm - 范围内的Kth最小值

c++ - 我的程序不断四舍五入到最接近的整数