tsl
tsl

Reputation: 21

Python Turtle: why centered square for odd size is uneven/distorted?

Do you have any idea why following code produces distorted square when side of the square is odd?

from turtle import *
s = 67.0

pu();fd(s/2.0);rt(90.0);fd(s/2.0);pd()
for _ in range(4):
  rt(90.0)
  fd(s)
pu();fd(-s/2.0);rt(-90.0);fd(-s/2.0);pd()

done()

I got such result

Above code works well when side is even. Python 3.5.0 was used. I have the same effect under linux, windows native and cygwin.

PARTIAL SOLUTION (EDIT): I made discovery, when I add very small number to s everything works well... s = 67.0 + 1e-10. But have no idea why?

EDIT: here is a more complicated program where above solution doesn't work. Here again I start drawing figure in the middle of square. I tried other strategy, drawing from the corner and in this case 1e-10 solution works.

from turtle import *
from math import sqrt
from random import *

plg = 53 - 1e-10 # side size, even - works well, odd - not
sk = sqrt(2) / 2.0

speed(0)

def square(q):
  s = q / 2.0
  penup()
  forward(s)
  right(90)
  forward(s)
  pendown()
  begin_fill()
  for i in range(4):
    right(90)
    forward(q)
  end_fill()
  penup()
  forward(-s)
  right(-90)
  forward(-s)
  pendown()

def triangle(q,rot):
  begin_fill()
  right(45 + rot)
  forward(q * sk)
  right(-135)
  forward(q)
  right(-90)
  forward(q)
  right(-135)
  forward(q * sk)
  end_fill()
  setheading(0)

pu(); forward(-plg*10/2); left(90); forward(plg*10/2);right(90); pd()
for y in range(10):
  p = pos()
  for x in range(10):
    i = randint(0,1)
    if i==0:
      triangle(plg,randrange(0,360,90))
    else:
      square(plg)
    pu(); forward(plg); pd()
  pu();setpos(p);right(90);forward(plg);left(90);pd()

done()

Upvotes: 2

Views: 306

Answers (2)

user5457708
user5457708

Reputation:

Few observations:

1) Remove 'right()' from the 5th line assures a regular square

2) Adding 'time.sleep(1)' just before 'for _ in range(4):' doesn't help in any way, so we can discard a timing problem

3) 'print heading()' after every 'rt()' prints the correct values, we can also discard problems of angulation

4) Drag the window very quickly around the screen changes the appearance of the square, this is definitely a graphical error

5) s = 66.9999999999999 returns an even square, s = 66.99999999999999 (adding 1 extra decimal) returns as the error

6) Even after compilation of the code, the square stills uneven

Turtle source: http://svn.python.org/projects/python/branches/pep-0384/Lib/turtle.py

I changed your code so it draws a simple angle:

pu();fd(s/2);rt(90.0);pd()
for x in range(2):
    rt(90.0)
    fd(s)
done()

This has the same issue as yours, but if I change fd(s/2) to fd(s) everything turns well, why?

it's just a guess (do not take it as absolute truth, I'm just intrigued and trying to figure it out) but I think that it depends by your screen resolution, odd_number%2 always returns 1, and the lines are misaligned by 1 pixel, If the value increases from 67 to 67.1 the screen reads it correctly and divides equally the space. (Mine is 1600x900)

if someone has more plausible explanations write them! This issue is interesting!

Upvotes: 1

saulspatz
saulspatz

Reputation: 5261

Using python 3.5 on Mac with Yosemite 10.10.5, it draws a perfect square.enter image description here

You might print the turtle coordinates after every drawing instruction to figure out what's going on on your platform.

Upvotes: 0

Related Questions