Reputation: 1
I am trying to design a QR-Code in a circular shape. I have to code it with python but I don't have much experience about it. After a lot of effort I created the shapes. Now I need to fill color between these shapes but I couldn't make it. My output graphic curently looks like this:
I need to fill those empty shapes with color. The code that I implemented to create this graphic is given below. I am not sure if I am using the right library. I saw lots of examples about matplotlib.pyplot but I thought it is more useful for creating charts. So any contribution is appreciated. I am really stuck.
from graphics import *
import math
def rect(r, theta):
"""theta in degrees
returns tuple; (float, float); (x,y)
"""
x = r * math.cos(math.radians(theta))
y = r * math.sin(math.radians(theta))
return x, y
def polar(x, y):
"""returns r, theta(degrees)
"""
r = (x ** 2 + y ** 2) ** .5
if y == 0:
theta = 180 if x < 0 else 0
elif x == 0:
theta = 90 if y > 0 else 270
else:
theta = math.degrees(math.atan(float(y) / x))
return r, theta
def main():
win = GraphWin('Canvas', 640, 480) # give title and dimensions
win.setCoords(-320, -240, 320, 240)
seventh = Circle(Point(0, 0), 90) # set center and radius
# seventh.setFill("yellow")
seventh.draw(win)
sixth = Circle(Point(0, 0), 80) # set center and radius
# sixth.setFill("yellow")
sixth.draw(win)
fifth = Circle(Point(0, 0), 70) # set center and radius
# fifth.setFill("yellow")
fifth.draw(win)
fourth = Circle(Point(0, 0), 60) # set center and radius
# fourth.setFill("yellow")
fourth.draw(win)
third = Circle(Point(0, 0), 50) # set center and radius
# third.setFill("yellow")
third.draw(win)
second = Circle(Point(0, 0), 40) # set center and radius
# second.setFill("yellow")
second.draw(win)
first = Circle(Point(0, 0), 30) # set center and radius
# first.setFill("yellow")
first.draw(win)
line = Line(Point(0, 0), Point(rect(90, 0)[0], rect(90, 0)[1]))
line.draw(win)
line2 = Line(Point(0, 0), Point(rect(90, 30)[0], rect(90, 30)[1]))
line2.draw(win)
line3 = Line(Point(0, 0), Point(rect(90, 60)[0], rect(90, 60)[1]))
line3.draw(win)
line4 = Line(Point(0, 0), Point(rect(90, 90)[0], rect(90, 90)[1]))
line4.draw(win)
line5 = Line(Point(0, 0), Point(rect(90, 120)[0], rect(90, 120)[1]))
line5.draw(win)
line6 = Line(Point(0, 0), Point(rect(90, 150)[0], rect(90, 150)[1]))
line6.draw(win)
line7 = Line(Point(0, 0), Point(rect(90, 180)[0], rect(90, 180)[1]))
line7.draw(win)
line8 = Line(Point(0, 0), Point(rect(90, 210)[0], rect(90, 210)[1]))
line8.draw(win)
line9 = Line(Point(0, 0), Point(rect(90, 240)[0], rect(90, 240)[1]))
line9.draw(win)
line10 = Line(Point(0, 0), Point(rect(90, 270)[0], rect(90, 270)[1]))
line10.draw(win)
line11 = Line(Point(0, 0), Point(rect(90, 300)[0], rect(90, 300)[1]))
line11.draw(win)
line12 = Line(Point(0, 0), Point(rect(90, 330)[0], rect(90, 330)[1]))
line12.draw(win)
line13 = Line(Point(0, 0), Point(rect(90, 360)[0], rect(90, 360)[1]))
line13.draw(win)
line14 = Line(Point(0, 0), Point(rect(90, 210)[0], rect(90, 210)[1]))
line14.draw(win)
first.setFill('black')
message = Text(Point(0, 200), 'Click anywhere to quit.')
message.draw(win)
win.getMouse()
win.close()
main()
If I can achieve it, I want to draw a picture that looks like this (drawn in Photoshop):
After some helpful comments I decided to find another appropriate python module. But I couldn't find the right one. If are there anyone who understand my problem can suggest the appropriate python module?
Upvotes: 0
Views: 1769
Reputation: 41872
I believe Python turtle, also built on tkinter, has enough capability to simulate your circular QR-Code with more intuitive logic:
from math import pi, sin, cos
from turtle import Turtle, Screen
TWO_PI = pi * 2
SEGMENTS = 10 # pie slices
SECTORS = 8 # concentric circles
MAXIMUM_RADIUS = 100
MINIMUM_RADIUS = 10
DELTA_RADIUS = (MAXIMUM_RADIUS - MINIMUM_RADIUS) // SECTORS
SEGMENT_EXTENT = TWO_PI / SEGMENTS
DEFAULT_LINE_WIDTH = 1
DATA = [ # data to match OP's example chart
(2, 0), (2, 3), (2, 5), (2, 6), (2, 9),
(3, 0), (3, 1), (3, 3), (3, 4), (3, 6),
(4, 1), (4, 2), (4, 7), (4, 8),
(5, 0), (5, 1), (5, 4), (5, 5), (5, 6), (5, 7),
(6, 3), (6, 5), (6, 8), (6, 9),
(7, 0), (7, 2), (7, 3), (7, 4), (7, 5), (7, 6), (7, 8),
]
def centered_circle(turtle, radius, extent=TWO_PI):
""" draw a circle centered about the current turtle location """
position = turtle.position()
heading = turtle.heading()
turtle.penup()
turtle.setx(turtle.xcor() + cos(heading) * radius)
turtle.sety(turtle.ycor() - sin(heading) * radius)
turtle.pendown()
turtle.circle(radius, extent, steps=60)
turtle.penup()
turtle.setposition(position) # return turtle to starting position
turtle.pendown()
def draw_blank_chart(turtle):
""" draw the empty chart """
turtle.dot(MINIMUM_RADIUS * 2) # center of chart
for radius in range(MINIMUM_RADIUS + DELTA_RADIUS, MAXIMUM_RADIUS + 1, DELTA_RADIUS):
centered_circle(turtle, radius) # divide chart into sectors
turtle.width(2 * DELTA_RADIUS / 3) # outer edge of chart
centered_circle(turtle, MAXIMUM_RADIUS + DELTA_RADIUS)
turtle.width(DEFAULT_LINE_WIDTH)
for _ in range(SEGMENTS): # divide chart into segments
turtle.forward(MAXIMUM_RADIUS + DELTA_RADIUS)
turtle.backward(MAXIMUM_RADIUS + DELTA_RADIUS)
turtle.left(SEGMENT_EXTENT)
def set_bit(turtle, sector, segment):
""" turn on (blacken) one sector:segment of chart """
turtle.setheading(SEGMENT_EXTENT * segment - pi/2)
turtle.width(DELTA_RADIUS)
centered_circle(turtle, (MINIMUM_RADIUS + DELTA_RADIUS * sector + DELTA_RADIUS/2), -SEGMENT_EXTENT)
screen = Screen()
screen.mode('logo') # force zero degrees to be straight up
yertle = Turtle(visible=False)
yertle.width(DEFAULT_LINE_WIDTH)
yertle.speed('fastest')
yertle.radians() # to make working with sin and cos easier
draw_blank_chart(yertle)
for sector, segment in DATA:
set_bit(yertle, sector, segment)
screen.exitonclick()
Upvotes: 1