【问题标题】:Draw a sphere surface in voxels efficiently?有效地在体素中绘制球面?
【发布时间】:2012-03-13 12:34:01
【问题描述】:

我有一个大的 3D 网格(为简单起见,最小网格框大小为 1x1x1)并且只想在此网格中绘制大量具有可变半径的球体的表面。但是我想消除孔和土堆的典型光栅化问题。

我也不想采用蛮力方法(查找球心半径内的所有像素,移除非边界像素),因为我将创建数百万个这样的球体,其中一些球体可能具有很高的半径。圆圈的Bresenham algorithm 与我想要的类似,但我想知道如何将其调整为球体形状。

有人可以帮忙吗?

【问题讨论】:

标签: geometry


【解决方案1】:

好的,我想我已经解决了。不过不确定这是否是最有效的版本。

基本上,球体的表面是由一组无限大的圆组成,半径为 r,当您穿过与该圆相交的平面垂直的轴时,这些圆会先增大后减小。半径的增减可以用半圆来描述。

然后,在离散空间中,我们可以通过使用 Bresenham 算法绘制一组圆来以有效的方式对球体的表面进行建模,其中半径是使用额外的 bresenham 圆计算的,其半径是球体的半径。这个半径被设想为在第三维中从圆“向上”伸出。

其他圆圈围绕它建立起来,好像主要圆圈是一个构建框架。

我不完全确定这是否那么容易理解,所以希望该算法可以提供更多启示:

public static void bresenhamSphere(Vector3 centre, int radius)
    {
        List<Vector3> points = new List<Vector3>();
        foreach (Point coord in bresenhemCircle(new Point(0,0), radius)) //get the set of points for an initial bresenham circle centred at the origin (we'll add the coordinates later)
        {
            int z = coord.Y; //I think you should be able to pick which coord matches to Z and which matches to radius arbitrarily, but this was more intuitive
            int r = coord.X; //the radius for the new circles
            foreach(Point point in bresenhemCircle(new Point((int)(centre.X),(int)(centre.Y)), r)) //get the circle spans around the original circle, this will make the surface of the sphere - this time create them at the x and y coordinates of the centre point supplied in the parameters
            {
                points.Add(new Vector3(point.X, point.Y, (int)(centre.Z) + z)); //convert the 2D results into 3D points by adding in the z value and add to the list.
            }
        }
    }

其中 BresenhamCircle(centre, radius) 返回由提供的中心和半径形成的圆的圆周上所有像素的坐标。

其中 BresenhamSemiCircle(centre, radius) 返回由提供的中心和半径形成的半圆圆周上所有像素的坐标。

另一个增强功能是不添加新圈子的初始点,因为我们已经从原始圈子运行中获得了这些点,但我不确定其中有多少好处。

【讨论】:

  • 原则上看起来不错(自己没试过)。有趣的是,谷歌搜索 'sphere rasterize' 没有 发现任何感兴趣的东西......我的一部分确信 Bresenham 的 Line + Circle 中使用的 技术 必须是可扩展的到表面,但我找不到任何人这样做!
  • 我认为如果将圆算法扩展到包括初始误差或小数半径,这将非常有效。我认为你最终会遇到一个问题,在球体的赤道附近,它会光栅到圆柱体,因为你多次绘制同一个圆,实际上,即使 x=0 或 y,通过弧线也应该略有不同=0 点将保持不变。我认为当你沿着第一个圆(半径)时,使用每个点的累积误差作为第二个圆的输入可以解决这个问题。
猜你喜欢
  • 2018-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-31
  • 1970-01-01
  • 1970-01-01
  • 2019-04-04
相关资源
最近更新 更多