pythondrawingturtle-graphicspython-turtle

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...


Solution

  • 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?