louis liu
louis liu

Reputation: 1

Unexpected results drawing ellipse using Python Turtle Module

I'm trying to draw an ellipse using Turtle module in Python, my plan is as follow:

  1. Let the starting point be the focal point of the ellipse
  2. Set the initial theta value to 0
  3. Let the turtle forward, let the distance of the forwarding be a*(1-ee)/(1-emath.cos(theta))
  4. Let it turn around and back to the original spot
  5. Make a very small turn, update the theta value
  6. Repeat the above process

Here's my actual code:

import turtle
import math
wn = turtle.getscreen()
wn.bgcolor("red")
My_Turtle = turtle.Turtle()
My_Turtle.penup()
My_Turtle.speed(9)
i=0
j=0
a=200
e=0.5
x_0 = 20
theta = 0
while(i<5000):
    #Plotting squares
    My_Turtle.penup()
    ellipse = a*(1-e*e)/(1-e*math.cos(theta))
    My_Turtle.forward(ellipse)
    My_Turtle.pendown()
    My_Turtle.forward(1)

    My_Turtle.left(180)
    My_Turtle.penup()
    My_Turtle.forward(ellipse+1)

However, the results were really off like this:(Not the complete image but can see that it's already off)

enter image description here

Can anyone explain to me where I get it wrong ? Thank you very much!

Upvotes: 0

Views: 803

Answers (1)

cdlane
cdlane

Reputation: 41872

I'm used to drawing ellipses from the center, not from one focal point so I read up on ellipse math to get my head around this. Your key formula appears to be correct:

ellipse = a*(1-e*e)/(1-e*math.cos(theta))

The issue is how you do your drawing. First you need to add setheading() to point your turtle in the correct direction. (Remember that by default it's in degrees so we need to either convert or change turtle's default). Second, how you bridge between steps in your drawing isn't sufficient.

I've reworked your code below, and have compared it to a center-based solution to confirm it generates the same ellipse:

import math
from turtle import Turtle, Screen

my_screen = Screen()

my_turtle = Turtle(visible=False)
my_turtle.speed('fastest')
my_turtle.radians()
my_turtle.penup()

e = 0.5  # linear eccentricity
a = 200  # semi major axis
c = e * a  # distance from center to focal point

my_turtle.goto(-c, 0)  # starting at a focal point
there = (2 * c, 0)  # initialize previous point visited

step = 0.1

theta = step  # already at starting point, so calculate next point

while theta < math.pi * 2 + step:  # overshoot to close curve

    # draw ellipse from one focus point
    my_turtle.setheading(theta)

    distance = a * (1 - e * e) / (1 - e * math.cos(theta))

    my_turtle.forward(distance)
    here = my_turtle.position()
    my_turtle.pendown()
    my_turtle.goto(there)  # draw line from last position to this one
    my_turtle.penup()  # comment out to demonstrate algorithm
    my_turtle.goto(-c, 0)  # return to focal point
    there = here

    theta += step

my_screen.exitonclick()

OUTPUT

enter image description here

I left the pen down for this illustrution so it's obvious that it's forming the ellipse from one focal point.

Upvotes: 1

Related Questions