Is there a function or some easier way to draw this, each of this little circles should have 8 other smaller circles around them like the big circle... So far i made big circle in center with 8 smaller circles using canvas
from Tkinter import *
canvas = Canvas(width=700, height=700, bg='black')
canvas.pack(expand=YES, fill=BOTH)
canvas.create_oval(240, 240, 410, 410, width=2, fill='yellow') #big circle
canvas.create_oval(140, 140, 210, 210, width=2, fill='yellow') #10h
canvas.create_oval(440, 440, 510, 510, width=2, fill='yellow') #16h
canvas.create_oval(285, 100, 355, 170, width=2, fill='yellow') #12h
canvas.create_oval(285, 480, 355, 550, width=2, fill='yellow') #18h
canvas.create_oval(440, 140, 510, 210, width=2, fill='yellow') #13h
canvas.create_oval(140, 440, 210, 510, width=2, fill='yellow') #19h
canvas.create_oval(100, 285, 170, 355, width=2, fill='yellow') #21h
canvas.create_oval(480, 285, 550, 355, width=2, fill='yellow') #15h
#lines
#1
canvas.create_line(320, 170, 320, 250, fill="yellow")
canvas.create_line(320, 400, 320, 480, fill="yellow")
#2
canvas.create_line(170, 320, 250, 320, fill="yellow")
canvas.create_line(400, 320, 480, 320, fill="yellow")
#3
canvas.create_line(200, 200, 275, 275, fill="yellow")
canvas.create_line(450, 200, 375, 275, fill="yellow")
#4
canvas.create_line(185, 465, 270, 380, fill="yellow")
canvas.create_line(480, 480, 380, 380, fill="yellow")
mainloop()
-
\$\begingroup\$ Well you have a lot of duplication you could easily factor out! \$\endgroup\$jonrsharpe– jonrsharpe2015年05月13日 14:07:42 +00:00Commented May 13, 2015 at 14:07
-
\$\begingroup\$ And how do I do that? Sorry I'm new at this \$\endgroup\$unacreatura– unacreatura2015年05月13日 14:25:45 +00:00Commented May 13, 2015 at 14:25
-
\$\begingroup\$ Look at the code - every time you see two (or nine!) lines with mostly the same structure and some different values, pull out all the bits that are the same into a function and make the differences parameters of that function. See e.g. docs.python.org/2/tutorial/controlflow.html#defining-functions \$\endgroup\$jonrsharpe– jonrsharpe2015年05月13日 14:27:05 +00:00Commented May 13, 2015 at 14:27
-
\$\begingroup\$ Can you write an example? \$\endgroup\$unacreatura– unacreatura2015年05月13日 14:30:46 +00:00Commented May 13, 2015 at 14:30
1 Answer 1
Here's one approach (some additional explanation after code):
from Tkinter import *
import numpy as np
def circle_burst(center_x, center_y, radius, ncircles, depth):
"""Make a circle burst pattern.
ncircles gives the number of circles surrounding the center
depth gives the number of levels of burst"""
# center circle
canvas.create_oval(center_x-radius, center_y-radius,
center_x+radius, center_y+radius,
width=2, fill='yellow')
# values for the smaller circles
small_radius = radius/3.0
circle_spread = 2*radius
# loop to make the smaller circles
for i in xrange(ncircles):
angle = i*2*np.pi/ncircles
epicenter_x = center_x + circle_spread*np.sin(angle)
epicenter_y = center_y + circle_spread*np.cos(angle)
if depth > 1:
circle_burst(epicenter_x, epicenter_y, small_radius, ncircles,
depth-1)
canvas.create_line(center_x, center_y, epicenter_x, epicenter_y,
fill='yellow')
else:
canvas.create_oval(epicenter_x-small_radius,
epicenter_y-small_radius,
epicenter_x+small_radius,
epicenter_y+small_radius,
width=2, fill='yellow')
canvas.create_line(center_x, center_y, epicenter_x, epicenter_y,
fill='yellow')
# make the canvas
width = 700
height = 700
canvas = Canvas(width=width, height=height, bg='black')
canvas.pack(expand=YES, fill=BOTH)
center_x = width/2
center_y = height/2
big_radius = width/8
# generate the pattern
circle_burst(center_x, center_y, big_radius, 8, 2)
mainloop()
Notes:
Parameterize everything you can/avoid magic numbers. Since you want your circles to have the same radius and the same offset from the center, it makes sense to calculate the x, y values that go into the
create_oval
calls from radius and offset rather than hardcode them in as numbers. This is true of the canvas size and center of the canvas, as well.You're essentially describing a recursive procedure, so it makes sense to use recursion to tackle it (each circle is surrounded by a collection of smaller circles). The
depth
parameter indicates how many levels of recursion to use.Math is your friend! Equally spacing objects in a circular pattern is pretty easy when you use a little trig.
You could easily have the scalings for
small_radius
andcircle_spread
be parameters rather than hardcoded; I chose some values that looked decent to me for ancircles=8
anddepth=2
.
-
\$\begingroup\$ thanks for help but i was hoping i could do that without numpy because we didn't work that yet. Is there any other way? \$\endgroup\$unacreatura– unacreatura2015年05月13日 15:06:16 +00:00Commented May 13, 2015 at 15:06
-
\$\begingroup\$ I run your code at depth 5: it is fractal! So nice \$\endgroup\$Caridorc– Caridorc2015年05月13日 15:23:09 +00:00Commented May 13, 2015 at 15:23
-
\$\begingroup\$ Regarding the use of numpy: sin, cos, and pi are also in the math module. I use numpy a lot, so it's sort of reflexive for me to use it, but you could just use the math module instead. \$\endgroup\$tachycline– tachycline2015年05月13日 15:28:57 +00:00Commented May 13, 2015 at 15:28
-
\$\begingroup\$ Oh thanks a lot! Just one more little thing. What do I add to that code to make even smaller circler around small circles but without that line or shorter line? \$\endgroup\$unacreatura– unacreatura2015年05月13日 16:04:54 +00:00Commented May 13, 2015 at 16:04