user6442076 user6442076 - 1 month ago 11
Python Question

Can't draw parabolic curve correctly with turtle graphics

I'm making a game like 'angry bird'.

There are two input:power and angle.
I apply those inputs to parabolic curve.

My turtle flies, making a parabolic curve. and my turtle have to hit the target,
but my turtle draws strange curve when angle is greater than 46, angle is 30, 40 etc...

I don't know where is problem....here is my code:

import turtle
import random
import math

g=9.80665
origin_x=-480
origin_y=-180
flag=False


def create_target():

x=random.randint(0,500)
y=random.randint(-200,0)
target=turtle.Turtle()
target.hideturtle()
target.penup()
target.goto(x,y)
target.shape('square')
target.color('red')
target.showturtle()
return target

def create_turtle():

homework=turtle.Turtle()
homework.hideturtle()
homework.penup()
homework.speed(0)
homework.goto(origin_x,origin_y)
homework.pendown()
homework.shape('turtle')
homework.color('blue')
homework.left(45)
homework.showturtle()
return homework

def setting():
'''drawing back ground lines'''
setting=turtle.Turtle()
setting.hideturtle()
setting.speed(0)
turtle.colormode(255)
setting.pencolor(214,214,214)

for y in range(100,-101,-100):
setting.penup()
setting.goto(-500,y)
setting.pendown()
setting.goto(500,y)

for x in range(-375,500,125):
setting.penup()
setting.goto(x,200)
setting.pendown()
setting.goto(x,-200)


def throw_turtle(turtle,target):
angle=int(input("Enter Angle:"))
power=int(input("Enter Power:"))
'''
parabola fomula:
x coordinate: speed(in here, that is power) * cos(anlge)*time
y coordinate: speed*sin(angle)*time - (gravity speed*time**2)/2
'''
for time in range(1,20):
# the origin fomula is for the situation that starts from (0,0). so I think
# I should compensate it, but is it right?
x=power*math.cos(angle)*time + origin_x
y=power*math.sin(angle)*time - (((time**2)*g)/2) + origin_y
if x<origin_x: # I think it has problem...
x-=origin_x

turtle.goto(x,y)
turtle.stamp() #this is for testing
if (x==target.xcor()) and (y==target.ycor()):
print("******Target is HIT!!! ******")
print("End of Game")
flag=True
break
else:
print("You missed...")


turtle.setup(1000,400)
windo=turtle.Screen()
windo.title('Angry Turtle')
setting()

#__main

my_turtle=create_turtle()
while flag==False:
target=create_target()
my_turtle=create_turtle()
my_turtle.speed(6)

throw_turtle(my_turtle,target)
my_turtle.hideturtle()
target.hideturtle()


I think
create_target()
and
create_turtle()
, and
setting()
don't have problem...

Answer

Below, I reduce your code to a MVCE (minimal, complete, and verifiable example) to examine the parabolic curve drawing code. The problem I found with it is the usual one of the difference between degrees and radians. The Python math library thinks in radians but provides a conversion function for degrees. The Python turtle library thinks in degress, by default, but can switch to radians using turtle.radians(). Either way is fine but the usage has to be consistent:

from turtle import Turtle, Screen
import math
import random

G = 9.80665
origin_x = -480
origin_y = -180

def create_turtle():

    homework = Turtle(shape='turtle')
    homework.hideturtle()
    homework.penup()
    homework.goto(origin_x, origin_y)
    homework.pendown()
    homework.speed(0)
    homework.left(45)
    homework.showturtle()

    return homework

def throw_turtle(turtle):

    angle = int(input("Enter Angle (in degrees): "))
    power = int(input("Enter Power: "))

    # parabola formula:
    #   x coordinate: speed(in here, that is power) * cos(angle)*time
    #   y coordinate: speed*sin(angle)*time - (gravity speed * time**2)/2

    for time in range(1, 20):

        x = power * math.cos(math.radians(angle)) * time + origin_x
        y = power * math.sin(math.radians(angle)) * time - (((time ** 2) * G) / 2) + origin_y

        turtle.goto(x, y)
        turtle.stamp()  # this is for testing


window = Screen()
window.setup(1000, 400)

for _ in range(3):
    my_turtle = create_turtle()

    my_turtle.color(random.choice(['red', 'green', 'blue', 'purple', 'black']))

    throw_turtle(my_turtle)

window.exitonclick()

EXAMPLE

> python3 test.py
Enter Angle (in degrees): 30   
Enter Power: 120
Enter Angle (in degrees): 45
Enter Power: 90
Enter Angle (in degrees): 60
Enter Power: 90
> 

enter image description here

Now, what more do you want it to do parabolic curve-wise?