Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Turtle how to draw a marker inside a cell in a 7x7 grid

I'm new to using Turtle graphics in Python 3, and I'm at a loss on what to do. One of my problems is that I have no idea where to begin with creating a function that will draw a marker inside of a grid cell based on a data set called 'path' containing 3 variables. The grid map itself is 7x7 and there's 5 markers in total (ranging from 0 to 4). Each marker draws its own social media logo and are completely different from each other.

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]]

My main goal is to be able to draw all 5 markers at once in their own location coordinates using the above data set. I'm not sure how should I approach with assigning these markers to their own marker_value. Would an if/elif/else statement work for this?

Trying to implement 5 markers at once is too overwhelming for me so I've tried using this very simple data set called 'path_var_3' that will only draw 1 marker.

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)

So far I was able to draw the marker in the program, but immediately I've encountered my first problem: I've realised that I've hardcoded the coordinates of where the superellipse and the triangle will begin to draw at, as indicated with the '!!!' comments. So when I run the program the marker is drawn outside of the grid cell. How do I get the marker to be drawn INSIDE a cell, regardless of where the cell is located within the 7x7 grid map?

If anyone has any ideas or is able to help I will greatly appreciate it.

TL;DR:

  1. How do I draw a marker, consisting of various shapes, inside the 100x100 cell within the 7x7 grid map?
  2. How do I draw a marker in any cell based on the location variable from a data set?
  3. How should I approach with assigning markers to integers ranging 0-4? If/elif/else statements?
like image 941
Listerbean Avatar asked Nov 07 '22 02:11

Listerbean


1 Answers

The code you provided isn't runnable due to goto(-59) and endfill() not being valid function calls. In the large, your code is lacking a layer to organize the problem you're trying to solve. (E.g. you need to define code-wise what 'Bottom left' or 'East' mean.) In the small, your YouTube logo drawing is using absolute coordinates instead of relative, preventing it from being drawn anywhere.

Below is a skeletal implementation of what you describe. It draws a grid for debugging purposes to show that logos are ending up in the correct locations. It substitutes colored circles for all but the YouTube logo:

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

like image 52
cdlane Avatar answered Nov 14 '22 22:11

cdlane