Skip to content

Instantly share code, notes, and snippets.

@spdegabrielle
Created May 23, 2017 20:27
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spdegabrielle/ce60f0a4188f58663d108f10e8b389ec to your computer and use it in GitHub Desktop.
Save spdegabrielle/ce60f0a4188f58663d108f10e8b389ec to your computer and use it in GitHub Desktop.
solar sim using 2htdp/universe
#lang racket/base
(require 2htdp/universe 2htdp/image lang/posn)
; The gravitational constant G
(define G 6.67428e-11)
; Assumed scale: 100 pixels = 1AU
(define AU (* 149.6e6 1000))
(define SCALE (/ 250 AU))
(struct body (id px py vx vy mass radius color) #:mutable #:transparent) ;Structure of body
;position in m, vector in m/s, mass in kg, radius in m
(define (force g mass otherMass distance) ;Calculate the force of attraction
(/ (* g (* mass otherMass)) (expt distance 2)))
(define (directionOfForce dx dy force) ;Calculate direction of the force
(let ([theta (atan dy dx)])
(list (* (cos theta) force) (* (sin theta) force))))
(define (attraction body otherBody) ;Creates a vector to adjust planet heading depending on all other bodies
(let* ([dx (- (body-px otherBody) (body-px body))]
[dy (- (body-py otherBody) (body-py body))]
[distance (sqrt (+ (expt dx 2) (expt dy 2)))]) ;Distance between bodys
(if (= distance 0) (print "Hitt!")
(directionOfForce dx dy
(force G (body-mass body) (body-mass otherBody) distance)))))
(define timestep (* 12 3600)) ;Half a day
(define (totalAttraction body bodies fxy) ;Creates a list of vectors, a vector for every body
(if (equal? bodies '())
fxy
(totalAttraction body (cdr bodies) (map + fxy (attraction body (car bodies))))))
;; gravity
;; bodies ⇒ bodies
(define (gravity bodies timestep)
(let* ([forces (for/list ([b bodies]) (totalAttraction b (remove b bodies) '(0 0)))]
[vectors (for/list ([f forces][b bodies]) (list (+ (body-vx b) (* (/ (car f) (body-mass b)) timestep))
(+ (body-vy b) (* (/ (car(cdr f)) (body-mass b)) timestep))))]
[positions (for/list ([v vectors][b bodies]) (list (+ (body-px b) (* (car v) timestep))
(+ (body-py b) (* (car (cdr v)) timestep))))])
(for/list ([b bodies][v vectors][p positions])
(body (body-id b) (car p) (car(cdr p)) (car v) (car(cdr v))
(body-mass b) (body-radius b) (body-color b)))))
;(struct body (id px py vx vy mass radius color)) ;just a reminder of the struct
;A list of bodies, size of planets is not real... you woldent se the planets.
(define testCollPlanets (list
(body "Sun" 0 0 0 0 (* 1.98892 (expt 10 30)) 100 "yellow")
(body "Mercury" (* -0.387098 AU) 0 0 (* -47.362 1000) (* 3.3011 (expt 10 23)) 4 "red")
(body "Venus" (* 0.723 AU) 0 0 (* 35.02 1000) (* 4.8685 (expt 10 24)) 8 "brown")
(body "Earth" (* -1 AU) 0 0 (* -29.783 1000) (* 5.9742 (expt 10 24)) 8 "green")
(body "Mars" (* -1.5236 AU) 0 0 (* -24.077 1000) (* 6.4174 (expt 10 23)) 4 "orange")
; (body "Havoc" (* -1.2 AU) 0 0 (* -10 1000) (* 8 (expt 10 25)) 50 "green")
))
(define (printBodies bodies scale) ;To print the numbers for control
(if (equal? bodies '())
(printf "Done\n")
(let
([ p (printf "Position XY ~a \n" (list (body-id (car bodies))
(* (body-px (car bodies)) scale)
(* (body-py (car bodies)) scale)
(* (body-vx (car bodies)) scale)
(* (body-vy (car bodies)) scale)))])
(printBodies (cdr bodies) scale))))
;; setup
(define Width 1200)
(define xoffset (/ Width 2))
(define Height 720)
(define yoffset (/ Height 2))
;; start-world (world left right ps vs as f)
(define starting-state testCollPlanets);position velocity
;; world -> scene
(define (render-expr bodies)
;(printBodies bodies SCALE)
(place-images
(map (λ (b) (circle (body-radius b) "solid" (body-color b))) bodies)
(map (λ (b) (make-posn (+ (* (body-px b) SCALE) xoffset ) (+ (* (body-py b) SCALE) yoffset ))) bodies)
(empty-scene Width Height "black")))
;; world -> world
;; update velocities and positions
(define (tick-expr bodies)
(gravity bodies timestep))
;;
(big-bang starting-state
(on-tick tick-expr)
(to-draw render-expr Width Height))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment