Reputation: 733
I'm trying to build a method in my class Circle
which gets a matrix (represented by a list of lists, each sublist represents a row) as an input.
The matrix has zero in every cell, and I'm supposed to place my circle in the center of the matrix and check if the (i,j)
cell which represents the (i,j)
point is contained in the circle, but for some reason I get a different output.
Here is an example:
mat = [[0 for j in range(5)] for i in range(7)]
Circle(40, 10, 1).draw(mat)
The output I expect is:
[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]
But the output I get is:
[[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 1],
[0, 0, 0, 1, 1],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]
Here's my code:
class Point():
""" Holds data on a point (x,y) in the plane """
def __init__(self, x=0, y=0):
assert isinstance(x,(int, float)) and isinstance(y,(int, float))
self.x = x
self.y = y
class Circle():
""" Holds data on a circle in the plane """
def __init__(self,*args):
if len(args)==2:
if isinstance(args[0],Point) and isinstance(args[1],(float,int)):
assert args[1]>0
self.center= args[0]
self.radius= args[1]
if len(args)==3:
assert args[2]>0
self.a=args[0]
self.b=args[1]
self.center= Point(self.a,self.b)
self.radius= args[2]
def contains(self,check):
if isinstance(check,(Point)):
if math.sqrt((self.center.x-check.x)**2 + (self.center.y-check.y)**2) <= self.radius:
return True
if isinstance(check,Circle):
test= math.sqrt((self.center.x-check.center.x)**2 + (self.center.x-check.center.x)**2)
if test < (abs((self.radius)-(check.radius))):
return True
else:
return False
def draw(self,mat):
n=len(mat)
m=len(mat[0])
newcircle=Circle((int(m/2)+1),(int(n/2)+1),self.radius)
for i,lst in enumerate(mat):
for j,val in enumerate(lst):
if newcircle.contains(Point(i,j)):
mat[i][j]=1
Upvotes: 1
Views: 70
Reputation: 778
To draw a circle, you create a new circle in the center of the matrix, you check the cells that are inside and then you turn the value to 1 for those inside.
contains
:def contains(...):
if (cond1):
if (cond11)
return True
if (cond2):
if (cond21)
return True
else:
return False
If cond2 is true and cond21 is false, you will get a None. To be more Pythonic, try:
def contains(...):
if (cond1) and (cond11):
return True
elif (cond2) and (cond21):
return True
else:
return False
You are sure in this case to have a True or a False.
There is a copy / paste mistake in the function contains when instance is Circle.
You have forgotten to turn y
into x
.
draw
All you need for this function is the radius. Be careful with the use of integers and floats; we have:
(int(5 / 2)) == (5 / 2) != (5 / 2.)
To be sure to have a float, write the divisor as a float 2.
instead of 2
Your circle is created on a matrix which rows and columns indices start with 1 if you define the center using int(len(mat) / 2.) + 1
.
Don't forget that enumerate
indices starts at 0, not 1.
So, int((len(mat) - 1) / 2.) + 1
(which is the same as len(mat) / 2
) would be more accurate.
Seriously, Taha!
Upvotes: 0
Reputation: 13539
You're not placing your circle in the middle of the matrix.
newcircle=Circle((int(m/2)+1),(int(n/2)+1),self.radius)
should be
newcircle=Circle((int(n/2)),(int(m/2)),self.radius)
or possibly, since there is no need to use just integers here.
newcircle=Circle((n-1)/2.0,(m-1)/2.0,self.radius)
Upvotes: 1