SocketByte
SocketByte

Reputation: 325

Filling triangles in Python (Turtle)

I will probably get shit-ton of dislikes, but I really need to know this. I've tried turtle.begin_fill() etc. but nothing really works for me.

I want to make filled triangles / rectangles in Python, but I don't know how to implement it to my code.

Current code:

import turtle, math
def theme():
    turtle.speed(10)

    column_1()
    reset_column()
    column_2()
    reset_column()
    column_1()

def reset_column():
    turtle.up()
    turtle.forward(160)
    turtle.left(90)
    turtle.forward(480)
    turtle.right(90)
    turtle.down()

def reset_box():
    turtle.up()
    turtle.forward(3 * 32)
    turtle.right(90)
    turtle.forward(2 * 32)
    turtle.right(180)
    turtle.down()

def column_2():
    empty()
    reset_box()
    filled()
    reset_box()
    empty()
    reset_box()

def column_1():
    filled()
    reset_box()
    empty()
    reset_box()
    filled()
    reset_box()

def filled():
    size = 480
    box = size / 3
    for index in range(4):
        turtle.forward(box)
        turtle.right(90)
    turtle.forward(32)
    turtle.right(135)
    turtle.forward(32 * math.sqrt(2))
    for index in range(4):
        for index in range(3):
            turtle.left(90)
            turtle.forward((32 * math.sqrt(2)) / 2)
            turtle.right(90)
            turtle.forward((32 * math.sqrt(2)) / 2)
        turtle.left(90)
        turtle.forward(32 * math.sqrt(2))
    turtle.left(135)
    turtle.up()
    turtle.forward(32)
    turtle.down()
    for index in range(4):
        turtle.forward(box - (2 * (box / 5)))
        turtle.right(90)
    turtle.forward(32)

    first = True
    for index in range(4):
        if (first):
            turtle.right(135)
            first = False
        else:
            turtle.left(90)
        turtle.forward(32 * math.sqrt(2))
        turtle.left(90)
        turtle.forward((32 * math.sqrt(2)) / 2)
        turtle.right(90)
        turtle.forward((32 * math.sqrt(2)) / 2)

    turtle.left(135)
    turtle.up()
    turtle.forward(32)
    turtle.down()
    for index in range(4):
        turtle.forward(box - (4 * (box / 5)))
        turtle.left(90)
def empty():
    size = 480
    box = size / 3
    for index in range(4):
        turtle.forward(box)
        turtle.right(90)
    turtle.forward(32)
    turtle.right(90)
    turtle.up()
    turtle.forward(32)
    turtle.down()
    for index in range(4):
        turtle.forward(box - (2 * (box / 5)))
        turtle.left(90)
    turtle.left(90)
    turtle.forward(32)

    first = True
    for index in range(4):
        if (first):
            turtle.right(135)
            first = False
        else:
            turtle.left(90)
        turtle.forward(32 * math.sqrt(2))
        turtle.left(90)
        turtle.forward((32 * math.sqrt(2)) / 2)
        turtle.right(90)
        turtle.forward((32 * math.sqrt(2)) / 2)

    turtle.left(135)
    turtle.up()
    turtle.forward(32)
    turtle.down()
    for index in range(4):
        turtle.forward(box - (4 * (box / 5)))
        turtle.left(90)

theme()

My results are: enter image description here What I want to have: enter image description here

Any suggestions? Really don't know how to even start something like this. It is my first time with Python and especially Turtle mechanics.

Upvotes: 0

Views: 1525

Answers (2)

cdlane
cdlane

Reputation: 41872

I believe this is yet another situation where stamping works better than drawing. I've composed this as a set of five stamps where one of them has a variable fill color:

from turtle import Turtle, Screen

SIZE = 480
BOX = SIZE // 3
STAMP_SIZE = 20
STEP = 32 * 2 ** 0.5

screen = Screen()
stamps = []

stamp = Turtle('square', visible=False)
stamp.shapesize(BOX / STAMP_SIZE)
stamp.color('black', 'white')
stamps.append(stamp)

stamp2 = Turtle()
stamp2.goto(STEP / 2, -BOX / 2 - STEP / 4)
stamp2.begin_poly()
for _ in range(4):
    for _ in range(3):
        stamp2.left(90)
        stamp2.forward(STEP / 2)
        stamp2.right(90)
        stamp2.forward(STEP / 2)
    stamp2.left(90)
    stamp2.forward(STEP)
stamp2.end_poly()
polygon = stamp2.get_poly()
screen.addshape('stamp2', polygon)

stamp2.reset()
stamp2.shape('stamp2')
stamp2.color('white')
stamp2.tilt(45)
stamps.append(stamp2)

stamp = Turtle('square', visible=False)
stamp.shapesize(3 * BOX / 5 / STAMP_SIZE)
stamp.color('black')
stamps.append(stamp)

stamp4 = Turtle()
stamp4.setx(BOX / 5)
stamp4.right(45)
stamp4.begin_poly()
for index in range(4):
    stamp4.forward(STEP / 2)
    stamp4.right(90)
    stamp4.forward(STEP)
    stamp4.right(90)
    stamp4.forward(STEP / 2)
    stamp4.left(90)
stamp4.end_poly()
polygon = stamp4.get_poly()
screen.addshape('stamp4', polygon)

stamp4.reset()
stamp4.shape('stamp4')
stamp4.color('white')
stamps.append(stamp4)

stamp = Turtle('square', visible=False)
stamp.shapesize(BOX / 5 / STAMP_SIZE)
stamp.color('black')
stamps.append(stamp)

for stamp in stamps:
    stamp.speed('fastest')
    stamp.penup()

parity = True

for x in range(-BOX, BOX + 1, BOX):
    for y in range(-BOX, BOX + 1, BOX):

        stamps[0].fillcolor(['white', 'black'][parity])

        for stamp in stamps:
            stamp.goto(x, y)
            stamp.stamp()

        parity = not parity

for stamp in stamps:
    stamp.hideturtle()

screen.exitonclick()

You'll find this makes the code both simpler and faster.

enter image description here

Upvotes: 1

EyuelDK
EyuelDK

Reputation: 3189

Use turtle.begin_fill() and turtle.end_fill() and may be also turtle.fillcolor

Here is the code to achieve it along with a demo. I have comment on all the lines of code.

import turtle, math
def theme():
    turtle.speed(10)

    column_1()
    reset_column()
    column_2()
    reset_column()
    column_1()

def reset_column():
    turtle.up()
    turtle.forward(160)
    turtle.left(90)
    turtle.forward(480)
    turtle.right(90)
    turtle.down()

def reset_box():
    turtle.up()
    turtle.forward(3 * 32)
    turtle.right(90)
    turtle.forward(2 * 32)
    turtle.right(180)
    turtle.down()

def column_2():
    empty()
    reset_box()
    filled()
    reset_box()
    empty()
    reset_box()

def column_1():
    filled()
    reset_box()
    empty()
    reset_box()
    filled()
    reset_box()

def filled():

    turtle.fillcolor('black') # NEW CODE
    turtle.begin_fill()       # NEW CODE

    size = 480
    box = size / 3
    for index in range(4):
        turtle.forward(box)
        turtle.right(90)
    turtle.forward(32)
    turtle.right(135)
    turtle.forward(32 * math.sqrt(2))
    for index in range(4):
        for index in range(3):
            turtle.left(90)
            turtle.forward((32 * math.sqrt(2)) / 2)
            turtle.right(90)
            turtle.forward((32 * math.sqrt(2)) / 2)
        turtle.left(90)
        turtle.forward(32 * math.sqrt(2))
    turtle.left(135)
    turtle.up()
    turtle.forward(32)
    turtle.down()
    for index in range(4):
        turtle.forward(box - (2 * (box / 5)))
        turtle.right(90)
    turtle.forward(32)

    first = True
    for index in range(4):
        if (first):
            turtle.right(135)
            first = False
        else:
            turtle.left(90)
        turtle.forward(32 * math.sqrt(2))
        turtle.left(90)
        turtle.forward((32 * math.sqrt(2)) / 2)
        turtle.right(90)
        turtle.forward((32 * math.sqrt(2)) / 2)

    turtle.left(135)
    turtle.up()
    turtle.forward(32)
    turtle.down()
    for index in range(4):
        turtle.forward(box - (4 * (box / 5)))
        turtle.left(90)

    turtle.end_fill()     # NEW CODE

def empty():

    size = 480
    box = size / 3
    for index in range(4):
        turtle.forward(box)
        turtle.right(90)
    turtle.forward(32)
    turtle.right(90)
    turtle.up()
    turtle.forward(32)
    turtle.down()

    turtle.fillcolor('black') # NEW CODE
    turtle.begin_fill()       # NEW CODE

    for index in range(4):
        turtle.forward(box - (2 * (box / 5)))
        turtle.left(90)
    turtle.left(90)
    turtle.forward(32)

    turtle.end_fill()         # NEW CODE

    turtle.fillcolor('white') # NEW CODE
    turtle.begin_fill()       # NEW CODE

    first = True
    for index in range(4):

        if (first):
            turtle.right(135)
            first = False
        else:
            turtle.left(90)

        turtle.forward(32 * math.sqrt(2))
        turtle.left(90)
        turtle.forward((32 * math.sqrt(2)) / 2)
        turtle.right(90)
        turtle.forward((32 * math.sqrt(2)) / 2)

    turtle.end_fill()       # NEW CODE

    turtle.left(135)
    turtle.up()
    turtle.forward(32)
    turtle.down()

    turtle.fillcolor('black') # NEW CODE
    turtle.begin_fill()       # NEW CODE

    for index in range(4):
        turtle.forward(box - (4 * (box / 5)))
        turtle.left(90)

    turtle.end_fill()       # NEW CODE

theme()

Upvotes: 1

Related Questions