球体的计算点
calc Points of sphere
我知道互联网上还有其他一些问题和文章,但还不够。我的问题是,现在,我正在通过使用 bresenham 的圆绘图算法制作具有 ascending/descending 半径的堆叠圆来计算球体的点。这是我的代码,但它应该不重要。
def drawCircle(self, xyz, r): #Draws circle with radius "r" from midpoint "xyz". Note: Circle is parallel to x-axis
xc, yc, zc = xyz
coords = []
def drawC(xc, yc, zc, x, y):
coords.append((xc+x, yc+y, zc))
coords.append((xc-x, yc+y, zc))
coords.append((xc+x, yc-y, zc))
coords.append((xc-x, yc-y, zc))
coords.append((xc+y, yc+x, zc))
coords.append((xc-y, yc+x, zc))
coords.append((xc+y, yc-x, zc))
coords.append((xc-y, yc-x, zc))
x = 0
y = r
d = 3 - 2 * r
drawC(xc, yc, zc, x, y)
while y >= x:
x += 1
if (d > 0):
y -= 1
d = d + 4 * (x - y) + 10
else:
d = d + 4 * x + 6
drawC(xc, yc, zc, x, y)
for c in coords:
self.drawPixel(c)
return coords
def drawSphere(self,xyz,r): #Draws sphere. Not quite functional yet
x, y, z = xyz
for sr in range(-1,r):
self.drawCircle((x,y,z-r+sr),sr)
index = list(range(-1,r))
for sr in index:
self.drawCircle((x,y,z+sr),index[-sr])
当我渲染其中一个球体时,会发生这种情况:
如果我把厚度增加到2层
到 3 层:
有洞。 :( 球体越厚,孔越少,但创建速度要慢得多。有没有办法得到无孔球体?
所以看起来您只是在绘制每个圆的边缘。
消除孔洞的一种方法是填充每个圆圈内的区域。您可以在圆上的任意位置选择一个点,然后直接选择它旁边的两个点并在它们之间填充一个三角形。然后,将第二个点移到第三个点的对面,画一个新的三角形。
或者,您可以选择圆的一个轴(x 或 y)并取位于 x 上的两个点=每个 x 的某个值。当你调用 drawC()
时,你已经有了相反的点,所以只需将它们插入下面的 draw_line 中:
def fill_line(x1, x2, y, z):
max = max(x1,x2)
min = min(x1,x2)
for i in range(min, max):
coords.append(i, y, z)
您还可以遍历每个圆所在的正方形并找到其中的点:
def fill_circle(xy, r, z):
for i in range(xy[0]-r, xy[0]+r):
for j in range(xy[1]-r, xy[1]+r):
if (i - xy[0])**2 + (j - xy[1])**2 < r**2:
coords.append(i,j,z)
如果在填充圆圈时图层之间出现空洞,请尝试在另一个轴上绘制圆圈。
我不会继续画圈。相反,我会通过扫描投影磁盘的边界框(这是一个正方形)来填充磁盘,然后计算 R² - (X-Xc)² - (Y-Yc)²
并在该数量为正时绘制。
如果需要Z
坐标,这个就是上面数量的平方根。
您可以以增量方式非常快速地评估它,注意
R² - (X+1-Xc)² - (Y-Yc)² = R² - (X-Xc)² - (Y-Yc)² + 2(X-Xc) + 1 =
R² - (X-Xc)² - (Y-Yc)² + 2X + 1-2Xc`
我知道互联网上还有其他一些问题和文章,但还不够。我的问题是,现在,我正在通过使用 bresenham 的圆绘图算法制作具有 ascending/descending 半径的堆叠圆来计算球体的点。这是我的代码,但它应该不重要。
def drawCircle(self, xyz, r): #Draws circle with radius "r" from midpoint "xyz". Note: Circle is parallel to x-axis
xc, yc, zc = xyz
coords = []
def drawC(xc, yc, zc, x, y):
coords.append((xc+x, yc+y, zc))
coords.append((xc-x, yc+y, zc))
coords.append((xc+x, yc-y, zc))
coords.append((xc-x, yc-y, zc))
coords.append((xc+y, yc+x, zc))
coords.append((xc-y, yc+x, zc))
coords.append((xc+y, yc-x, zc))
coords.append((xc-y, yc-x, zc))
x = 0
y = r
d = 3 - 2 * r
drawC(xc, yc, zc, x, y)
while y >= x:
x += 1
if (d > 0):
y -= 1
d = d + 4 * (x - y) + 10
else:
d = d + 4 * x + 6
drawC(xc, yc, zc, x, y)
for c in coords:
self.drawPixel(c)
return coords
def drawSphere(self,xyz,r): #Draws sphere. Not quite functional yet
x, y, z = xyz
for sr in range(-1,r):
self.drawCircle((x,y,z-r+sr),sr)
index = list(range(-1,r))
for sr in index:
self.drawCircle((x,y,z+sr),index[-sr])
当我渲染其中一个球体时,会发生这种情况:
如果我把厚度增加到2层
到 3 层:
有洞。 :( 球体越厚,孔越少,但创建速度要慢得多。有没有办法得到无孔球体?
所以看起来您只是在绘制每个圆的边缘。
消除孔洞的一种方法是填充每个圆圈内的区域。您可以在圆上的任意位置选择一个点,然后直接选择它旁边的两个点并在它们之间填充一个三角形。然后,将第二个点移到第三个点的对面,画一个新的三角形。
或者,您可以选择圆的一个轴(x 或 y)并取位于 x 上的两个点=每个 x 的某个值。当你调用 drawC()
时,你已经有了相反的点,所以只需将它们插入下面的 draw_line 中:
def fill_line(x1, x2, y, z):
max = max(x1,x2)
min = min(x1,x2)
for i in range(min, max):
coords.append(i, y, z)
您还可以遍历每个圆所在的正方形并找到其中的点:
def fill_circle(xy, r, z):
for i in range(xy[0]-r, xy[0]+r):
for j in range(xy[1]-r, xy[1]+r):
if (i - xy[0])**2 + (j - xy[1])**2 < r**2:
coords.append(i,j,z)
如果在填充圆圈时图层之间出现空洞,请尝试在另一个轴上绘制圆圈。
我不会继续画圈。相反,我会通过扫描投影磁盘的边界框(这是一个正方形)来填充磁盘,然后计算 R² - (X-Xc)² - (Y-Yc)²
并在该数量为正时绘制。
如果需要Z
坐标,这个就是上面数量的平方根。
您可以以增量方式非常快速地评估它,注意
R² - (X+1-Xc)² - (Y-Yc)² = R² - (X-Xc)² - (Y-Yc)² + 2(X-Xc) + 1 =
R² - (X-Xc)² - (Y-Yc)² + 2X + 1-2Xc`