Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Heittoliikkeen simulointia, mukana ilmanvastus kv²
- # k riippuu ilman tiheydestä, joka riippuu korkeudesta ja lämpötilasta
- # lämpötila riippuu korkeudesta
- # joten k:n arvo muuttuu korkeuden mukaan
- # verlet second order method: x0,x1 alkuarvot, sitten loput x,y iteroimalla
- # iterointi: x(n+1) = 2x(n) - x(n-1) + a(n)*Dt^2
- # Juhani Kaukoranta 17.10.2021
- import pygame, math
- # pygame:ssa x kasvaa vasemmalta oikealle, y ylhäältä alas
- # laskut tehdään (x,y)-koordinaatistossa, tuloste pygame-koordinaatistossa
- pygame.font.init()
- font = pygame.font.Font('freesansbold.ttf', 24)
- # pallon ominaisuudet: (otettu baseballista, Cd=0.3)
- # ei ilmanvastusta Cd = 0, paraabelirata
- Cd = 0.3 # ilmanvastuskerroin, oletusarvo 0.3
- roo = 1.225 # ilman tiheys kg/m³ (ICAO, 0m +15C)
- A = 0.0043 # pallon poikkipinta-ala m²
- m = 0.145 # pallon massa kg
- r = 5 # piirretyn pallon säde pikseleinä
- # ilman tiheys roo = 1.225*(288.15/(288.15-0.0065*h))**(-4.25578597)
- k1 = (Cd*A)/(2*m) # pallon vastuskertoimen osa
- # k = k1*roo # pallon vastuskerroin, mukana ilman tiheys roo
- v0 = 300 # lähtönopeus
- g = 9.80665 # putouskiihtyvyys
- alfadeg = 30 # heittokulma (suhteessa vaakatasoon)
- alfa = alfadeg*math.pi/180 # heittosuunta radiaaneina
- # pystykiihtyvyys y''(t) = -g - k*vy² = -(g+k*vy²)
- # vaakakiihtyvyys x''(t) = -k *vx²
- t0 = 0.0 # aloitusaika
- Dt = 1/100.0 # aika-askel
- T = 7000 # animaation maksimikesto 7000*1/100 = 70 s
- # piirtoalueen asetus
- (width,height) = (1280,720) # Pygamen piirtoala pikseleinä
- screen = pygame.display.set_mode((width, height))
- black = (0,0,0)
- yellow =(255,255,0)
- red = (255,0,0)
- green = (0,255,0)
- blue =(0,0,255)
- magenta = (255,0,255)
- screen.fill(black)
- pygame.display.set_caption("pallon lento, ilmanvastus kv² ja tiheyden korkeusriippuvuus mukana: ")
- # pallon (0,0) vastaa Pygamen näytöllä (100,500)
- (x0,y0) =(0,0) # pallon koordinaattien aloitusarvot, (0 metriä, 0 metriä)
- (pygamex0,pygamey0) = (100,500) # Pygamen koordinaatiston origo
- h = 0 # korkeus lähtötasosta tasosta,lähtötaso on merenpinnan taso, Pygamen y=500=gamey0
- roo = 1.225*(288.15/(288.15-0.0065*h))**(-4.25578597) # ilman tiheyden alkuarvo
- k = k1*roo # pallon ilmanvastuskertoimen aloitusarvo
- vx = v0*math.cos(alfa) # vaakasuoran nopeuskomponentin alkuarvo
- vy = v0*math.sin(alfa) # pystysuoran nopeuskomponentin alkuarvo
- x1 =x0 + vx*Dt - 0.5*(k*vx**2)*Dt**2 # eka x-askel, verlet
- y1 = y0 + vy*Dt - 0.5*(k*vy**2+g)*Dt**2 # eka y-askel, verlet
- vx = (x1 - x0)/Dt # vaakanopeus eka-askeleen jälkeen
- vy = (y1 - y0)/Dt # pystynopeus eka-askeleen jälkeen
- hmax = y1 # pitää kirjaa pallon maksimikorkeudesta
- h = y1 # pallon korkeus
- timer = 0 # ajastin, 0.5 s välein tulostetaan näytölle pallon dataa
- alku =90 # punainen lähtötasoviivan alku pikseleinä vähän ennen lähtöpaikkaa Pygamessa
- loppu = 1000 # punaisen lahtötasoviivan loppupistepikseleinä Pygamessa
- pygame.draw.line(screen,red,(pygamex0-20,pygamey0+r),(pygamex0+1000,pygamey0+r),2) # vaakaviiva
- # piirretty niin, että pallo on vaakaviivalla, keskipiste korkeudella r
- text = font.render("Lähtökulma = "+str(round(alfadeg))+" Lähtönopeus = "+str(round(v0)), True, yellow, black)
- screen.blit(text,(100,40))
- pygame.draw.circle(screen, yellow,(pygamex0+x0,pygamey0-y0),r) # piirretään alkutilan (x0,y0) pallo
- pygame.display.flip() # päivitetään näyttö
- pygame.time.delay(2)
- pygame.draw.circle(screen,black,(pygamex0+x0,pygamey0-y0),r) # alkutilan (x0,y0) pallo pois
- pygame.draw.circle(screen,yellow,(pygamex0+x1,pygamey0-y1),r) # piirretään eka-askeen (x1,y1) pallo
- pygame.display.flip()
- pygame.time.delay(2)
- pygame.draw.circle(screen,black,(pygamex0+x1,pygamey0-y1),r) # eka-askeleen (x1,y1) pallo pois
- # simulointi jatkuu aikaan T asti iteroimalla x(n+1) = 2x(n) - x(n-1) + a(n)*Dt^2
- # eka arvojen (x0,y0) ja (x1,y1) jälkeen lasketaan ja tulostetaan päivitettyjä (x,y)
- for j in range (0,T) :
- timer += 1 # puolen sekunnin paikkatietojen tulostusta varten
- roo = 1.225*(288.15/(288.15-0.0065*h))**(-4.25578597) # ilman tiheys
- k = k1*roo # ilmanvastuskerroin
- x = 2*x1 - x0 - (k*vx**2)*Dt**2 # pallon uusi x-koordinaatti, verlet
- y = 2*y1 - y0 - (g + k*vy**2)*Dt**2 # pallon uusi y -kordinaatti, verlet
- h = y # pallon korkeus
- if h > hmax:
- hmax = h
- pygame.draw.circle(screen,yellow,(pygamex0+x,pygamey0-y),r) # piirretään päivitetty pallo
- pygame.display.flip()
- pygame.time.delay(2)
- pygame.draw.circle(screen,black,(pygamex0+x,pygamey0-y),r) # edellinen pallon paikka pois
- (xpaikka,ypaikka) = (round(abs(x)),round(y)) # paikka muistiin timer-tulostusta varten
- vaakamatka = round(abs(x)) # muistiin timer-tulostusta varten
- korkeus = round(h) # muistiin timer-tulostusta varten
- vx = (x - x0)/(2*Dt) # päivitetty vaakanopeus, huom! tämä on tarkempi kuin (x1-x0)/Dt
- vy = (y - y0)/(2*Dt) # päivitetty pystynopeus, huom! tämä on tarkempi kuin (y1-y0)/Dt
- x0 = x1 # askeleen jälkeen päivitetään koordinaatit, iterointi alkaa
- x1 = x
- y0 = y1
- y1 = y
- if y >= hmax : # pallo lakipisteessä
- korkeus = round(h)
- korkeustxt0 = font.render("xxxxxxxxxxxxxxxxxxx",True,black,black)
- korkeustxt = font.render("maxkorkeus = "+str(korkeus)+" m", True, yellow, black)
- screen.blit(korkeustxt0,(100,70)) # puhdistetaan korkeustietoja
- screen.blit(korkeustxt,(100,70))
- hmax = y
- if y < 0 : # pallo putosi maahan
- break
- if timer == 50: #puolisekunti kulunut,näytetään paikkatietoja
- text0 = font.render("xxxxxxxxxxxxxxxx",True,black,black)
- screen.blit(text0,(100,100)) # puhdistetaan vaakamatkatiedot
- text = font.render("Vaakamatka = "+str(vaakamatka),True,yellow,black)
- screen.blit(text,(100,100))
- screen.blit(text0,(100,120)) # puhdistetaan korkeustiedot
- txt = font.render("Lentoaika = "+str(round(100*j*Dt)/100),True,yellow,black)
- screen.blit(txt,(100,120))
- timer = 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement