finitas ecuacion discretizar diferencias continuas calor python numpy multidimensional-array grid shapes

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).