图形:如何填充行之间的颜色?

时间:2018-03-19 19:53:58

标签: python graphics fill area zelle-graphics

我正在设计一个圆形的QR码。我必须用python编写它,但我没有太多经验。经过大量的努力,我创造了形状。现在我需要填充这些形状之间的颜色,但我无法做到。我的输出图形看起来像这样:

screenshot of current output

我需要用颜色填充那些空的形状。我在下面给出了用于创建此图形的代码。我不确定我是否使用了正确的库。我看到很多关于matplotlib.pyplot的例子,但我认为它对于创建图表更有用。所以任何贡献都表示赞赏。我真的被卡住了。

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

如果我能实现它,我想绘制一幅看起来像这样的图片(用Photoshop绘制):

screenshot of desired image created with Photoshop

经过一些有用的评论后,我决定找到另一个合适的python模块。但我找不到合适的人。如果有人了解我的问题可以建议适当的python模块吗?

1 个答案:

答案 0 :(得分:0)

我相信Python龟也是建立在tkinter上的,它有足够的能力以更直观的逻辑模拟你的圆形QR码:

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

enter image description here