Python: 如何创建一个子矩阵来离散一个圆?
Python: how to create a submatrix discretizing a circle?
在一个充满zeros
的二维方格(矩阵)中,我需要创建一个充满ones
的子矩阵,这个子矩阵的形状尽可能接近圆形。我知道当你使用单元格或像素时,圆不能精确表示,因此我的目标是离散化圆。
我能想到的最好的事情是这段代码,它产生 方形子矩阵 (下图中的蓝色方块):
from __future__ import division
import numpy
import matplotlib.pyplot as plt
import matplotlib.colors as mc
import random
import os
import math
n=101 #Grid size
empty_lattice=numpy.zeros((n,n)) #The empty 2D grid
x=int(numpy.random.uniform(0,n-1)) #X coord. top left corner
y=int(numpy.random.uniform(0,n-1)) #Y coord. top left corner
side=int(numpy.random.uniform(15,n)) #Side of the square approximating the circle
max_y=n-y #Checks the distance between the y of the submatrix origin and the matrix vertical boundary
max_x=n-x #Checks the distance between the x of the submatrix origin and the matrix horizontal boundary
max_width=0 #Initializes a maximum width for the loading submatrix
if max_y<max_x: #This assigns the minimum value between max_y and max_x to max_width, so that the submatrix is always a square
max_width=max_y
else:
max_width=max_x
if side>max_width:
for i in range(0,max_width):
for j in range(0, max_width):
empty_lattice[x+i][y+j]=1
else:
for i in range(0, side):
for j in range(0, side):
empty_lattice[x+i][y+j]=1
现在,从视觉上看,这转化为下图,但如您所知,蓝色正方形和内切圆在面积方面存在明显差异:
我的问题:我如何修改我的代码才能"smooth"我的正方形的角,以便出现类似于圆形的东西?
编辑
即使圆圈没有完全位于网格边界内,也应该绘制圆圈(查看图像)。
这个函数填满一圈1,看起来还不错
def fill_cell(cell, corner, rad):
m, n = cell.shape
ctr = corner[0]+m/2, corner[1]+n/2
x = np.arange(m) - ctr[0]
y = np.arange(n) - ctr[1]
X,Y = np.meshgrid(x, y, order='ij') # could try order='xy'
Z = ((X**2 + Y**2)<= rad**2).astype(cell.dtype)
return Z
empty_lattice[:] = fill_cell(empty_lattice, (x,y),side/2)
empty_lattice
中的位置不正确 - 因为您定义 x,y
坐标的方式与我的假设不同,但我认为您可以解决这个问题。
Radius 看起来不错,但可能会相差一个整数。
要填充多个圆圈,您可以迭代 x,y
值,并且
为切片分配晶格值(视图)
xyslice = slice(x,15), slice(y,15)
empty_lattice[xyslice] = fill_cell(empty_lattice[xyslice],...)
对于重叠的圆圈,我会研究某种逻辑分配
empty_lattice[xyslice] |= fill_cell(...)
在一个充满zeros
的二维方格(矩阵)中,我需要创建一个充满ones
的子矩阵,这个子矩阵的形状尽可能接近圆形。我知道当你使用单元格或像素时,圆不能精确表示,因此我的目标是离散化圆。
我能想到的最好的事情是这段代码,它产生 方形子矩阵 (下图中的蓝色方块):
from __future__ import division
import numpy
import matplotlib.pyplot as plt
import matplotlib.colors as mc
import random
import os
import math
n=101 #Grid size
empty_lattice=numpy.zeros((n,n)) #The empty 2D grid
x=int(numpy.random.uniform(0,n-1)) #X coord. top left corner
y=int(numpy.random.uniform(0,n-1)) #Y coord. top left corner
side=int(numpy.random.uniform(15,n)) #Side of the square approximating the circle
max_y=n-y #Checks the distance between the y of the submatrix origin and the matrix vertical boundary
max_x=n-x #Checks the distance between the x of the submatrix origin and the matrix horizontal boundary
max_width=0 #Initializes a maximum width for the loading submatrix
if max_y<max_x: #This assigns the minimum value between max_y and max_x to max_width, so that the submatrix is always a square
max_width=max_y
else:
max_width=max_x
if side>max_width:
for i in range(0,max_width):
for j in range(0, max_width):
empty_lattice[x+i][y+j]=1
else:
for i in range(0, side):
for j in range(0, side):
empty_lattice[x+i][y+j]=1
现在,从视觉上看,这转化为下图,但如您所知,蓝色正方形和内切圆在面积方面存在明显差异:
我的问题:我如何修改我的代码才能"smooth"我的正方形的角,以便出现类似于圆形的东西?
编辑
即使圆圈没有完全位于网格边界内,也应该绘制圆圈(查看图像)。
这个函数填满一圈1,看起来还不错
def fill_cell(cell, corner, rad):
m, n = cell.shape
ctr = corner[0]+m/2, corner[1]+n/2
x = np.arange(m) - ctr[0]
y = np.arange(n) - ctr[1]
X,Y = np.meshgrid(x, y, order='ij') # could try order='xy'
Z = ((X**2 + Y**2)<= rad**2).astype(cell.dtype)
return Z
empty_lattice[:] = fill_cell(empty_lattice, (x,y),side/2)
empty_lattice
中的位置不正确 - 因为您定义 x,y
坐标的方式与我的假设不同,但我认为您可以解决这个问题。
Radius 看起来不错,但可能会相差一个整数。
要填充多个圆圈,您可以迭代 x,y
值,并且
为切片分配晶格值(视图)
xyslice = slice(x,15), slice(y,15)
empty_lattice[xyslice] = fill_cell(empty_lattice[xyslice],...)
对于重叠的圆圈,我会研究某种逻辑分配
empty_lattice[xyslice] |= fill_cell(...)