Python Turtle如何在7x7网格的单元格内绘制标记

时间:2018-09-04 18:26:59

标签: python python-3.x turtle-graphics

我不熟悉在Python 3中使用Turtle图形的方法,我不知所措。我的问题之一是,我不知道从哪里开始创建一个函数,该函数将基于包含3个变量的称为“路径”的数据集在网格单元内绘制标记。网格图本身是7x7,共有5个标记(范围从0到4)。每个标记都绘制自己的社交媒体徽标,并且彼此完全不同。

grid_cell_size = 100 # px
num_squares = 7 # this for creating the 7x7 grid map

# for clarification: path = ['Start', location, marker_value]

path = [['Start', 'Centre', 4], ['North', 2, 3], 
         ['East', 2, 2], ['South', 4, 1], ['West', 2, 0]]

我的主要目标是能够使用上述数据集在其自己的位置坐标中一次绘制所有5个标记。我不确定如何将这些标记分配给自己的marker_value。 if / elif / else语句可以解决这个问题吗?

尝试一次实现5个标记对我来说不堪重负,因此我尝试使用称为“ path_var_3”的非常简单的数据集,该数据集只会绘制1个标记。

path_var_3 = [['Start', 'Bottom left', 3]]

def follow_path(path_selection):

  # Draws YouTube logo marker
  if 3 in path_var_3[0]:
    penup()
    # !!!
    goto(0, -32)
    setheading(90)

    # Variables
    youtube_red = '#ff0000'
    youtube_white = 'White'

    radius = 10
    diameter = radius * 2

    # Prep to draw the superellipse
    pencolor(youtube_red)
    fillcolor(youtube_red)

    # Drawing the superellipse
    begin_fill()
    pendown()

    for superellipse in range(2):
      circle(radius, 90)
      forward(80)
      circle(radius, 90)
      forward(60 - diameter)

    # Finish up
    end_fill()
    penup()

    # Move turtle position towards the centre of the superellipse
    # !!!
    goto(-59)
    backward(16)
    setheading(90)

    fillcolor(youtube_white)

    # Drawing the white 'play icon' triangle
    begin_fill()
    pendown()

    for play_triangle in range(2):
      right(120)
      forward(28)
      right(120)
      forward(28)

    # Finish up
    endfill()
    penup()
  else: return print('ERROR')

follow_path(path_var_3)

到目前为止,我已经能够在程序中绘制标记,但是立即遇到了我的第一个问题:我意识到我已经对超级椭圆和三角形将开始绘制的位置的坐标进行了硬编码,如“ !!!”所示注释。因此,当我运行程序时,标记将绘制在网格单元的外部。无论单元格在7x7网格图中的何处,如何在单元格内绘制标记?

如果有人有任何想法或能够提供帮助,我将不胜感激。

TL; DR

  1. 如何在7x7网格图的100x100单元内绘制由各种形状组成的标记?
  2. 如何根据数据集中的位置变量在任何单元格中绘制标记?
  3. 我应该如何为0至4的整数分配标记? if / elif / else语句?

1 个答案:

答案 0 :(得分:1)

由于goto(-59)endfill()不是有效的函数调用,因此您提供的代码无法运行。总体而言,您的代码缺少一层来组织要解决的问题。 (例如,您需要按代码定义“左下”或“东”的含义。)在较小的情况下,您的YouTube徽标绘图使用的是绝对坐标,而不是相对坐标,从而防止将其绘制到任何地方。

以下是您所描述的基本实现。它绘制网格用于调试目的,以显示徽标最终在正确的位置。它将彩色圆圈替换为YouTube徽标以外的所有徽标:

from turtle import Turtle, Screen

path = [('Start', 'Centre', 4), ('North', 2, 3), ('East', 2, 2), ('South', 4, 1), ('West', 2, 0)]

GRID_CELL_SIZE = 100  # pixels
NUMBER_SQUARES = 7  # this for creating the 7x7 grid map

ABSOLUTE_OFFSETS = {
    'Centre': (NUMBER_SQUARES // 2, NUMBER_SQUARES // 2),
    'Bottom left': (0, NUMBER_SQUARES - 1),
    # etc.
}

COMPASS_OFFSETS = {
    'North': (0, 1),
    'East': (1, 0),
    'South': (0, -1),
    'West': (-1, 0),
    'Start': (1, 1),  # Special case, assumes absolute offset
}

# YouTube Variables
YOUTUBE_RED = '#ff0000'
YOUTUBE_WHITE = 'White'
YOUTUBE_RADIUS = 10
YOUTUBE_WIDTH = 80
YOUTUBE_HEIGHT = 60
YOUTUBE_TRIANGLE_EDGE = 28

def draw_grid():  # for debugging
    grid = Turtle(visible=False)
    grid.speed('fastest')
    grid.dot()  # visualize origin
    grid.penup()
    grid.goto(-GRID_CELL_SIZE * NUMBER_SQUARES / 2, GRID_CELL_SIZE * (NUMBER_SQUARES / 2 - 1))

    for _ in range(NUMBER_SQUARES - 1):
        grid.pendown()
        grid.forward(NUMBER_SQUARES * GRID_CELL_SIZE)
        grid.penup()
        grid.goto(-GRID_CELL_SIZE * NUMBER_SQUARES / 2, grid.ycor() - GRID_CELL_SIZE)

    grid.goto(-GRID_CELL_SIZE * (NUMBER_SQUARES / 2 - 1), GRID_CELL_SIZE * NUMBER_SQUARES / 2)

    grid.setheading(270)

    for _ in range(NUMBER_SQUARES - 1):
        grid.pendown()
        grid.forward(NUMBER_SQUARES * GRID_CELL_SIZE)
        grid.penup()
        grid.goto(grid.xcor() + GRID_CELL_SIZE, GRID_CELL_SIZE * NUMBER_SQUARES / 2)

def follow_path(path_selection):

    turtle = Turtle(visible=False)

    x, y = ABSOLUTE_OFFSETS['Centre']  # relative to grid, not screen!

    for direction, offset, marker in path_selection:
        if direction in COMPASS_OFFSETS:
            dx, dy = COMPASS_OFFSETS[direction]

            if offset in ABSOLUTE_OFFSETS:
                x, y = ABSOLUTE_OFFSETS[offset]
            else:
                x += dx * offset
                y += dy * offset

            turtle.penup()
            # new virtual drawing origin, convert to screen coordinates
            turtle.goto((x - NUMBER_SQUARES // 2) * GRID_CELL_SIZE, (y - NUMBER_SQUARES // 2) * GRID_CELL_SIZE)
            MARKERS[marker](turtle)
            turtle.penup()

def YouTube(turtle):
    diameter = YOUTUBE_RADIUS * 2

    x, y = turtle.position()

    # Draws YouTube logo marker
    turtle.goto(x + YOUTUBE_WIDTH/2 + YOUTUBE_RADIUS, y + YOUTUBE_HEIGHT/2 - YOUTUBE_RADIUS)
    turtle.setheading(90)

    # Draw the rounded rectangle (should really be a superellipse)
    turtle.color(YOUTUBE_RED)

    turtle.begin_fill()

    for _ in range(2):
        turtle.circle(YOUTUBE_RADIUS, 90)
        turtle.forward(YOUTUBE_WIDTH)
        turtle.circle(YOUTUBE_RADIUS, 90)
        turtle.forward(YOUTUBE_HEIGHT - diameter)

    # Finish up
    turtle.end_fill()

    # Return turtle position towards the centre of the rounded rectangle
    turtle.goto(x - YOUTUBE_TRIANGLE_EDGE/4, y + YOUTUBE_TRIANGLE_EDGE/2)
    turtle.setheading(90)

    # Drawing the white 'play icon' triangle
    turtle.fillcolor(YOUTUBE_WHITE)

    turtle.begin_fill()

    for _ in range(2):
        turtle.right(120)
        turtle.forward(YOUTUBE_TRIANGLE_EDGE)

    # Finish up
    turtle.end_fill()

def RedDot(turtle):
    turtle.dot(GRID_CELL_SIZE / 2, 'Red')

def BlueDot(turtle):
    turtle.dot(GRID_CELL_SIZE / 2, 'Blue')

def GreenDot(turtle):
    turtle.dot(GRID_CELL_SIZE / 2, 'Green')

def OrangeDot(turtle):
    turtle.dot(GRID_CELL_SIZE / 2, 'Orange')

MARKERS = [RedDot, BlueDot, GreenDot, YouTube, OrangeDot]

screen = Screen()

draw_grid()  # for debugging

follow_path(path)

screen.mainloop()

enter image description here