• API
• FAQ
• Tools
• Trends
• Archive
SHARE
TWEET

# Eliptical_Orbit.py

a guest Nov 30th, 2012 490 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. #!/usr/bin/env python
2. """
3.
4.
5. Coded by Kyle Hovey a.k.a. spel3o
6. This is a script that uses the Python Imaging Library to model the eliptical orbit of a planet.
7. This is not a perfect model of an orbit, and models an ellipse by use of regular intervals where
8. gravity takes a "blow" on the intertial vector of the planet. The vector of the blow is a function
9. of gravity vs. distance and thus is an application of inverse square. In other words:
10.
11. g = H/(x/K)**2
12.
13. Where H and K are the vertical and horizontal scaling constants and x is the distance from the
14. orbital body.
15.
16. Errors in orbit calculation are found when:
17. a.) A vector lands somewhere in the middle of a pixel (can be augmented by scaling)
18. b.) The gravity vector's direction is determined (off by less than a degree due to rounding)
19.
20.
21.
22. """
23.
24.
25. import Image, ImageDraw, getpass, os, math
26.
27. user = getpass.getuser()
28. path = '/Users/'+user+'/Desktop'                    #Get current path
29.
30. def img_new(x, y, name='0'):                    #Create function for making new blank images
31.         img = Image.new('RGBA', (x, y), 'white')
32.         img.save(path+'/'+name+'.png', 'PNG')
33.         del img
34.
35. def conv_coords(tup, x, y):                                             #Convert cartesian coordinates to PIL coordinates
36.         return (tup[0], y-tup[1])
37.
38. def grav_pull(dist, scale=1, K=6.35, H=6.336)#Determine the gravitational vector length from the distance and two constants
39.         return scale*(K/((dist/scale)/H)**2)
40.
41. def find_center(dim):                                                   #Find the center of a rectangle with given dimensions (x,y)
42.         return (dim[1]/2,dim[0]/2)
43.
44. def draw_vector(working_vector, center, color, path, image_no):                                         #Define function for drawing a complete vector between two points
45.         current_image = Image.open(path+'/'+str(image_no)+'.png')                                               #Vectors are stored with both of their coordinates in a list [(x0,y0),(x1,y1)]
46.         draw = ImageDraw.Draw(current_image)                                                                                    #Open active image
47.         draw.line(conv_coords(working_vector[0], center[1], center[0]) + conv_coords(working_vector[1], center[1], center[0]), fill=color, width=4)
48.         current_image.save(path+'/'+str(image_no)+'.png', 'PNG')                                                #Save image
49.
50. def draw_sun(center, path, image_no=0):                                                                                         #Draw a dot in the center of the image for the sun
51.         draw_vector([(center[0]-1,center[1]+1),(center[0]+1,center[1]-1)], center, '#000', path, image_no)
52.
53. def draw_arb_vector(start, end, length, center, color, image_no, path, ret=1):          #Define a function to draw an arbitrarily long vector towards another point
54.         if end[1]-start[1] < 0:                                                                                                                 #Find if vector will be moving up or down
55.                 y_neg = -1
56.         else:
57.                 y_neg = 1
58.         if end[0]-start[0] < 0:                                                                                                                 #Find if vector will be moving left or right
59.                 x_neg = -1
60.         else:
61.                 x_neg = 1
62.         a = x_neg*math.sqrt(length**2/(1+((start[1]-end[1])/(start[0]-end[0]))**2))             #Find the change in the y value by solving for slope (rise/run) and pythagorean theorem a^2+b^2=c^2
63.         b = y_neg*math.sqrt(length**2-a**2)                                                                                             #Find the change in the x value by using pythagorean theorem
64.         new_endpoint = (start[0]+a, start[1]+b)
65.         arb_vector = [start, new_endpoint]
66.         draw_vector(arb_vector, center, color, path, image_no)                                                  #Draw the new vector
67.         if ret == 1:                                                                                                                                    #Return the new vector
68.                 return arb_vector
69.
70. def iterate(working_vector, center, image_no, path, scale):                                                     #Define the function for making a new iteration of the orbit
71.         vector_color = '#7513D6'                                                                                                                #
72.         inertia_color = '#CF8A15'                                                                                                               #Make things pretty
73.         gravity_color = '#069677'                                                                                                               #
74.         segment_color = '#000'
75.         draw_sun(center, path, image_no)                                                                                                                                #Draw the sun
76.         draw_vector([working_vector[0], center], center, segment_color, path, image_no)                                 #Draw initial vector
77.         draw_vector(working_vector, center, vector_color, path, image_no)                                                               #Draw line from vector start to center
78.         delta_y = working_vector[1][1]-working_vector[0][1]                                                                                             #
79.         delta_x = working_vector[1][0]-working_vector[0][0]                                                                                             #Determine the rise and run of the vector
80.         end_coords = working_vector[1]                                                                                                                                                          #Save the end of the original vector for the drawing of the next
81.         working_vector = [working_vector[1], (working_vector[1][0]+delta_x, working_vector[1][1]+delta_y)]                      #Apply the change in rise and run for the first vector to double it
82.         draw_vector(working_vector, center, inertia_color, path, image_no)                                                                                      #Draw the extended vector copy of the first vector
83.         distance = math.sqrt((working_vector[0][0]-center[0])**2+(working_vector[0][1]-center[1])**2)                           #Use Pythagorean theorem to find distance to center
84.         g = grav_pull(distance, scale)                                                                                                                                                          #Find gravitational pull
85.         working_vector = draw_arb_vector(working_vector[1], (center[0]+delta_x,center[1]+delta_y), g, center, gravity_color, image_no, path)      #Draw the gravity vector
86.         working_vector = [working_vector[1], end_coords]                                                                                                                        #Create new vector starting at the end of the initial vector and ending
87.         draw_vector(working_vector, center, vector_color, path, image_no)                                                                                       #at the end of the gravity vector, then draw it.
88.         return [working_vector[1],working_vector[0]]                                                                                                                            #Return resultant vector for next iteration
89.
90. def do_main(x=1000, y=2000):                                                                                                                                                                    #Start the whole shebang (no pun intended)
91.         image_no = 0                                                                                                                                                                                            #Start at image 0
92.         initial_distance = input('Please enter the starting distance of the orbital body from the sun:')                        #
93.         initial_vector = input('Please enter the initial speed vector in cm proportional to velocity:')                         #Get preliminary data
94.         scale = input('Please enter the scale of the model:')                                                                                                           #
95.         img_new(y,x)                                                                                                                                                                                            #Create a new image with the default or provided dimensions
96.         size = (x,y)
97.         center = find_center(size)                                                                                                                                                                      #Find center of new image
98.         working_vector =[(center[0]+initial_distance*scale, center[1]), (center[0]+initial_distance*scale, center[1]+initial_vector*scale)]             #Establish the initial vector
99.         while True:
100.                 questionaire = raw_input('Hit enter to execute an iteration or d for done:')                                                    #Begin the iterations
101.                 if questionaire == 'd':                                                                                                                                                                 #Break out of iterations if d for done is received
102.                         ##compile_gif(path+'/*.png)
103.                         print('Program execution completed.')
104.                         return False
105.                 else:
106.                         working_vector = iterate(working_vector, center, image_no, path, scale)                                 #Create new iteration
107.                         os.system('cp '+path+'/'+str(image_no)+'.png '+path+'/'+str(image_no+1)+'.png')                 #Copy the image and increase the filename number by one
108.                         image_no += 1                                                                                                                                                   #Increment the image count
109.
110. do_main()                                                                                                                                                                                       #Start the prompt
RAW Paste Data
Top