2012-03-13 33 views
1

我有一个很大的3D网格(为了简单起见,网格框的最小尺寸为1x1x1),并且只希望在这个网格中绘制大量可变半径球体的表面。不过,我想消除洞和丘的典型光栅化问题。有效地绘制体素中的球体表面?

我也不想做一个暴力方法(找到球体中心半径内的所有像素,删除非边界像素),因为我将创建数百万个这样的球体,其中一些可能会有高半径。圈子的Bresenham algorithm类似于我想要的,但我想知道如何将其适应球形。

有人能帮忙吗?

+0

相似:http://stackoverflow.com/questions/9084189/draw-a-sphere-using-3d-pixels-voxels http://stackoverflow.com/questions/564492/recommend-some-bresenhams-like-算法的球面映射在2d – AakashM 2012-03-13 13:38:23

+0

啊感谢您找到这个。我自己也遇到了第一个链接,但假设他们正在寻找一个填充球体,因为回应仅涵盖了我上面概述的蛮力方法(或者除非我能计算体素的确切跨度,否则对我无用的跨度方法转换角度变化 – 2012-03-13 14:31:56

回答

2

好吧,我想我已经解决了。不知道这是否是最有效的版本。

本质上,一个球体的表面由一组半径为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(圆心,半径)返回所有像素的坐标在由所提供的中心和半径形成的圆的圆周上。

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

一个额外的增强将是不添加在新的圈子的初始点,因为我们已经从原来的圈子运行这些,但我不知道这是多少奖金。

+0

原则上看起来不错(自己还没有尝试过)。有趣的是,谷歌搜索'sphere rasterize'**不会引起任何有趣的事情......我的一部分人确信*在Bresenham的Line + Circle中使用的技术*必须可扩展到表面,但我找不到任何人完成它! – AakashM 2012-03-13 16:33:41

+1

我认为如果将圆算法扩展为包含初始误差或半径分数,这将工作得非常好。我认为最终会出现一个问题,即在一个球体的赤道附近将其划分为一个圆柱体,因为您多次绘制相同的圆,实际上,即使x = 0或y,通过圆弧应该略有变化= 0分s会保持不变。我认为当你沿着第一个圆圈(半径)时,使用每个点的累积误差作为第二个圆圈的输入可以解决这个问题。 – rjp 2013-12-04 18:31:28