python - discretizar - diferencias finitas ecuacion de calor
Python: ¿cómo crear una submatriz discretizando un círculo? (1)
Esta función completa un círculo de 1 que se ve bastante bien.
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)
La posición en empty_lattice
no es correcta, debido a una diferencia en la forma en que está definiendo las coordenadas x,y
y mis suposiciones, pero creo que puede resolverlo.
El radio se ve bien, aunque podría estar apagado por un número entero.
Para completar varios círculos, puede iterar sobre los valores x,y
, y asignar valores de celosía para un sector (ver)
xyslice = slice(x,15), slice(y,15)
empty_lattice[xyslice] = fill_cell(empty_lattice[xyslice],...)
Para círculos superpuestos buscaría algún tipo de asignación lógica
empty_lattice[xyslice] |= fill_cell(...)
En una cuadrícula 2D cuadrada (matriz) llena de zeros
, necesito crear una submatriz llena de ones
, con la forma de esta submatriz lo más cerca posible de un círculo. Sé que un círculo no se puede representar con precisión cuando se trabaja con celdas o píxeles, por lo tanto apunto a un círculo discretizado.
Lo mejor que se me ocurrió fue este código, que produce submatrices cuadradas (el cuadrado azul en la imagen a continuación):
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
Ahora, visualmente esto se traduce en la siguiente imagen, pero como saben hay una diferencia notable entre el cuadrado azul y el círculo inscrito en términos de área:
Mi pregunta: ¿cómo podría modificar mi código para poder "suavizar" las esquinas de mis cuadrados para que aparezca algo que se asemeje a un círculo?
EDITAR
Los círculos deben dibujarse incluso si no residen por completo dentro de los límites de la cuadrícula (observe la imagen).