0

I am attempting to draw some images using Python Turtle and the screen sizing/canvas sizing is eluding me.

Here is what I have to create the current image:

import turtle
import math
from PIL import Image
import os

t = turtle.Turtle()

Image.MAX_IMAGE_PIXELS = None

screen = turtle.Screen()
fileName = "test"
seedString = fileName

turtle.setup(int(15000),int(15000),int(7500),int(7500))
turtle.screensize(int(15000), int(15000))
turtle.hideturtle()
screen.tracer(False)

t.pen(pensize=2, pencolor='black')

print(screen.screensize())
print(t.pos())

t.color('black')
t.begin_fill()
t.goto(7500,0)
t.right(90)
t.forward(7500)
t.right(90)
t.forward(15000)
t.right(90)
t.forward(15000)
t.right(90)
t.forward(15000)
t.right(90)
t.forward(7500)
t.end_fill()

print(t.pos())

t.goto(0,0)
t.pen(pencolor='white', pensize=5)
t.circle(4000, 360)

print(t.pos())
print(screen.screensize())

canvas = screen.getcanvas()
canvas.postscript(file=fileName, height=15000, width=15000)

img = Image.open(fileName)
img.save(seedString+'.jpg')
img.close()

os.system('move \"'+fileName+'\" somefilelocation')
os.system('move \"'+seedString+'.jpg\" somefilelocation')

Based on my understanding this script should set the Screen size to 15,000 by 15,000 pixels and move the origin to the center at (7,500,7,500) using turtle.setup(). I'm not sure if this is the canvas or just the window that we see the turtle move around in. But I also included the turtle.screensize() function to set it to 15000 x 15000. Perhaps this is redundant as it sizes the same thing, but the documentation is sort of vague regarding it.

At the end I save a PS file with the same size of 15000 x 15000 pixels but this image is what is created:

Scaled Turtled Image

The border was added by me to make the actual size of the image more viewable.

What I'm struggling to understand is a few things. One if the setup() and screensize() function is actually just changing the window size itself then how do I change the size of the actual canvas the drawing is created on. Second I start by manually drawing a rectangle that is filled black by the goto() and right() combination of functions above. But the image itself (the one in this post is scaled for the sake of size) is saved as 11251 x 11251. This does not only make no sense to me as I am setting the saved PS file to 15000 x 15000 but even if the original image was 11251 x 11251 after saving then why is my rectangle, which should be 15000 x 15000 based on how I scripted it, much much smaller than that. Also the origin does not appear anywhere near the center of either the black rectangle or the overall canvas/image that is saved.

Lastly I cannot understand why the circle() function is only producing a half circle despite me explicitly setting the extent argument to 360. I left it at 0 which is defaulted to a full circle and it produced the same semi circle.

I've tried only including setup or screensize, using absolute values like 1.0 vs pixel values and nothing seems to get me what I want. Which is a 15000 x 15000 pixel image with a circle drawn from the origin, being the center of the canvas at (7500,7500). I know that wouldn't be the center of the circle itself as it starts on an edge and creates a circle from that point to a point above or below it (radius,0) away. But that's not how my script is currently working.

It is clear that there is a fundamental understanding that I am not grasping. Any assistance would be much appreciated as I'd love to learn more about this library and better understand the canvas/coordinate system to more accurately create images.

Thank you!

martineau
  • 119,623
  • 25
  • 170
  • 301
Darren Woodson
  • 68
  • 1
  • 11
  • So I just figured out that what my current method of saving the image produces is actually dependent on the size of the Window itself that is shown when starting a turtle script. I thought the canvas and window size was independent, hence the use of scroll bars if the turtle travels outside the Window parameters? – Darren Woodson Aug 17 '21 at 16:55
  • So resizing the window itself with the traditional Minimize/Maximize buttons that all windows have actually affects what is saved as the 'canvas' so they are not independent. So how can I create an image that is larger than my monitor screens? Is there a way to draw the image without that window at all? Just in the background create and save the image with my specified dimensions? – Darren Woodson Aug 17 '21 at 17:16
  • `setup()` and `screensize()` do different things, see [this answer](https://stackoverflow.com/a/61883613/5771269) for an explanation of the difference. – cdlane Aug 19 '21 at 05:58

1 Answers1

1

You've a couple of flaws in your logic. First, you call tracer(False) but never call screen.update() when you finish drawing, which is why your circle is incomplete.

Second, although turtle crawls atop tkinter, it uses a different default coordinate system than Canvas. So we need to adjust for that in our Canvas.postscript() method invocation:

from turtle import Turtle, Screen

WIDTH, HEIGHT = 15_000, 15_000

fileName = "test"

screen = Screen()
screen.setup(WIDTH, HEIGHT)
screen.tracer(False)

turtle = Turtle()
turtle.hideturtle()
turtle.pensize(5)
turtle.penup()

turtle.goto(-WIDTH/2, -HEIGHT/2)

turtle.begin_fill()

for _ in range(2):
    turtle.forward(WIDTH)
    turtle.left(90)
    turtle.forward(HEIGHT)
    turtle.left(90)

turtle.end_fill()

turtle.goto(0, -HEIGHT/4)
turtle.pencolor('white')
turtle.pendown()
turtle.circle(HEIGHT/4)

screen.update()

canvas = screen.getcanvas()
canvas.postscript(file=fileName + ".eps", width=WIDTH, height=HEIGHT, x=-WIDTH/2, y=-HEIGHT/2)

enter image description here

You'll note that the image width/height (not fully shown above) is 200 inches, which is the inch equivalent of 15_000 points (using 75 points per inch instead of 72.)

I leave the final step of conversion to JPG to you.

cdlane
  • 40,441
  • 5
  • 32
  • 81