Grafični prikaz gibanja satelita okrog Zemlje

V poljubno verzijo Pythona dodamo katero od grafičnih knjižnic. Prav preprosta je graphic.py . Namestimo jo na disk tako, da postane Pythonu vidna, preberemo še navodila na začetku knjižnice in lahko začnemo s programiranjem grafike. Tako recimo koda

from math import *
from graphics import *
def delay(m):
    for i in range(1000*m):
            continue
def main():
    mx=600    # širina in višina okna
    my=400
    win=GraphWin("Moj Krog",mx,my,autoflush=False)
    p=Rectangle(Point(0,0),Point(mx,my))
    p.setFill("white")
    c=Circle(Point(mx/2,my/2),10)      #Zemlja je modri krogec
    c.setFill("blue")
    p.draw(win)
    c.draw(win)
    dt=10                  #interval med računi leg
    x=mx/3                 #začetna lega
    y=0
    vx=0                   # začetna hitrost
    vy=0.04                # to komponento malo spremeni 
    while True:
        r=sqrt(x*x+y*y)   # račun razdalje satelit-Zemlja
        ax=-x/(r*r*r)     # pospešek satelita sledi iz 
        ay=-y/(r*r*r)     # gravitacijskeg azakona
        vx=vx+ax*dt       # račun nove hitrosti
        vy=vy+ay*dt       
        x=x+vx*dt         #račun nove lege satelita 
        y=y+vy*dt
        t=Point(mx/2+x,my/2-y)     # risanje satelita
        t.setFill("red")
        t.draw(win)
        delay(100)
        #t.setFill("white")
        #t.draw(win)
        update()
    win.getMouse()
    win.close()
main()

spravimo v gibanje satelit okrog Zemlje.

Fuzbalska lestvica

 

Na evropskem in svetovnem prvenstvu v nogometu so reprezentance razvrščene v skupine po 4 in odigrajo med seboj vsaka z vsemi, torej vsaka 3 tekme, skupaj 6 tekem. Za zmago dobi ekipa 3 točke, za neodločen rezultat eno, ob porazu pa ostane brez točk. Ekipi, ki v skupini zbereta največ točk, se uvrstita v nadaljnje tekmovanje, preostali pa odpotujeta domov.

Vprašajmo se, kakšni so možni točkovni izidi po koncu tekem v skupini. Na misel nam pride, da je eden od možnih izdov osvojenih točk   npr. 9,6,3,0, kar pomeni, da ni bilo nobenega neodločenega rezultata, temveč same zmage,  in da je prva ekipa premagala ostale tri, druga izgubila s prvo, premagala pa ostali, tretje je izgubila z ekipama pred njo, premagala pa zadnjo in nazadnje četrta ekipa je izgubila vse tekme. Pri tem izidu je bilo v skupini razdeljeno maksimalno, 18 točk. Ni pa to edina taka možnost, preostali sta še npr. 9,3,3,3 ali 6,6,6,0.

Drug skrajni primer so sami remiji, torej 3,3,3,3. V tem primeru je bilo v skupini podeljeno minimalno, torej 12 točk.

Zanima nas, koliko je vseh možnih izidov osvojenih točk v skupini po koncu teh tekem. V skupini so 4 ekipe in vsaka igra z vsako, torej je skupaj C_4^2={4 \choose 2}=6 tekem. Ker so na vsaki tekmi tri možnosti izida, je po osnovnem izreku kombinatorike N=^{\left(p\right)}\hspace{-1.8mm} V_6^3=3^6=729 vseh možnosti. A število različnih izidov je dosti manjše, saj moramo odšteti njihove permutacije (npr 0,9,6,3 da isti izid kot 9,6,3,0). Imamo kar zapleten kombinatoričen problem. Namesto da bi ga rešili matematično, raje napišimo program, ki bo simuliral število točk po vseh možnih izidih teh tekem. Najprej sestavimo niz vseh izidov, nato pa izide v njem sortiramo in različne prepišemo v novi niz. V Pythonu gre to skoraj tako kot v slovenščini.

Koda programa zgleda takole:

#Program ugotovi vse različne možnosti osvojitve točk 
#v skupini 4 moštev.
#Medsebojnih tekem je 6, zmagovalec, dobi 3 točke, poraženec 0,
# v primeru
#neodločenega rezultata pa si moštvi razdelita 2 točki.
# V Petruna, junij 2014
x=3
y=0
z=1
izidi=[]
izid2=[]
for i in range(3):    
    for ii in range(3):
        for iii in range(3):
            for i4 in range(3):
                for i5 in range(3):
                    for i6 in range(3):
                        a=0
                        b=0
                        c=0
                        d=0
#simulacija izida na posamezni tekmi
                        if i==0:a=a+x;b=b+y
                        else:
                            if i==1:a=1;b=1
                            else:a=a+y;b=b+x

                        if ii==0:a=a+x;c=c+y
                        else:
                            if ii==1:a=a+1;c=c+1
                            else:a=a+y;c=c+x

                        if iii==0:a=a+x;d=d+y
                        else:
                            if iii==1:a=a+1;d=d+1
                            else:a=a+y;d=d+x   

                        if i4==0:b=b+x;c=c+y
                        else:
                            if i4==1:b=b+1;c=c+1
                            else:b=b+y;c=c+x

                        if i5==0:b=b+x;d=d+y
                        else:
                            if i5==1:b=b+1;d=d+1
                            else:b=b+y;d=d+x    

                        if i6==0:c=c+x;d=d+0
                        else:
                            if i==1:c=c+1;d=d+1
                            else:c=c+0;d=d+x

                        izi=[a,b,c,d]
                        izid=sorted(izi,reverse=True)                    
#tvorimo niz vseh izidov
                        izidi.append(izid)
#izločanje podvojenih
for i in range (len(izidi)):       
    if (izidi[i] not in izid2):
        izid2.append(izidi[i])       
izidis=sorted(izid2,reverse=True)
#računanje vsote točk v skupini
for i in range(len(izid2)):
    vsota=izidis[i][0]+izidis[i][1]+izidis[i][2]+izidis[i][3]
    izidis[i].insert(0,vsota)
#izpis števila vseh različnih možnosti
print "VSEH RAZLIČNIH MOŽNOSTI = ",len(izidis)
izidiss=sorted(izidis,reverse=True)
#izpis vseh različnih možnosti, urejenih po številu doseženih točk v skupini
for i in range(len(izidiss)):
    for j in range(5):
        print izidiss[i][j],"  ",
    print

Rezultat, ki ga dobimo, je naslednji:

18    9    6    3    0   
18    9    3    3    3   
18    6    6    6    0   
18    6    6    3    3   
17    9    6    1    1   
17    9    4    4    0   
17    9    4    3    1   
17    7    7    3    0   
17    7    6    4    0   
17    7    6    3    1   
17    7    4    3    3   
17    6    6    4    1   
17    6    4    4    3   
16    9    4    2    1   
16    7    7    1    1   
16    7    6    2    1   
16    7    5    4    0   
16    7    5    3    1   
16    7    4    4    1   
16    7    4    3    2   
16    6    5    4    1   
16    6    4    4    2   
16    5    4    4    3   
16    4    4    4    4   
15    9    2    2    2   
15    7    5    2    1   
15    7    4    3    1   
15    7    4    2    2   
15    6    5    2    2   
15    5    5    5    0   
15    5    5    4    1   
15    5    5    3    2   
15    5    4    4    2   
15    4    4    4    3   
14    7    3    2    2   
14    5    5    3    1   
14    5    5    2    2   
14    5    4    3    2   
13    5    3    3    2   
12    3    3    3    3

Opazimo torej, da je vseh možnih različnih izidov 40.

Zgornja tabela možnih točkovnih izidov po koncu tekmovanja v skupini pokaže nekaj zanimivosti. Možno je npr. napredovati samo z dvema remijema, ali zapustiti tekmovanje kljub dvem zmagam.  V prvem primeru ima drugovrščena ekipa samo 2 točki, v drugem pa tretjeuvrščena 6 točk (poišči v tabeli ta primera).  Tudi v zadnjem primeru, ko so tekmeci izenačeni, dva nadaljujeta, dva pa končata s tekmovanjem.

Tega dejstva ne  spremenijo niti dodatna pravila za napredovanje, ki so:

  1. točke
  2. razlika v golih (na vseh tekmah skupine)
  3. število doseženih golov (na vseh tekmah skupine)
    Če sta dve ali več reprezentanc še vedno izenačeni, se začne gledati medsebojne tekme!
  4. točke na medsebojni(h) tekmi(ah);
  5. razlika v golih na medsebojnih tekmah;
  6. število doseženih golov na medsebojnih tekmah;
  7. število točk ferpleja: rumeni karton -1 točka, drugi rumeni karton -3, neposredni rdeči karton -4, rumeni karton in neposredni rdeči karton
  8. žreb

 

Vidi se torej, da je kljub točkovanju zelo pomembna tudi sreča.

Nostalgija(2)

Zadnjič sem pisal o tem, kako je Logo kakor feniks ponovno vstal iz pepela, tokrat v preobleki Pythonove želvje grafike. Nekaj preprostih ukazov , pa vam program lahko riše lepe krivulje. Grafika pa lahko postane nekaj posebnega, če pri njenem nastajanju uporabite rekurzijo – programerski prijem, s katerim velik problem razdelite na identične, a nekoliko manjše probleme. Seveda se to da narediti samo pri posebnih problemih. Včasih smo občudovali Hilbertove krivulje, krivulje Sierpinskega, hanojske stolpiče, celo permutacije se dajo programirati rekurzivno. A tokrat (pogled skozi okno pove, da še vedno sneži) si oglejmo Kochovo snežinko.

Koda je naslednja:

#Kochova snežinka, V.Petruna feb.2013
from Tkinter import *
import math
import turtle
a=80
def koch(x,stopnja):
    if stopnja<1:
        turtle.forward(x)
    else:
        koch(x/3,stopnja-1)
        turtle.left(60)
        koch(x/3,stopnja-1)
        turtle.right(120)
        koch(x/3,stopnja-1)        
        turtle.left(60)
        koch(x/3,stopnja-1)
turtle.heading()
turtle.penup()
turtle.setpos(-600,0)
turtle.pendown()
for n in range(5):    
    for i in range(3):        
        koch(243,n)
        turtle.right(120)
    turtle.penup()
    turtle.forward(243)
    turtle.pendown()
mainloop()

Dolžina 243 ni izbrana naključno, saj je to 3^5. Tako se izognemo napaki zaradi necelega deljenja. Program nam ustvari naslednjo risbico

Simulacija gibanja satelita v VisualPythonu

Poljubno gibanje lahko simuliramo tako, da upoštevamo naslednje korake:

  1. izberemo majhen časovni interval dt,
  2. podamo komponente krajevnega vektorja \vec{r}=(x,y) telesa  na začetku gibanja in komponente njegove hitrosti \vec{v}=(v_x,v_y) takrat,
  3. zapišemo za telo 2. Newtonov zakon po komponentah in iz izrazimo komponenti pospeška,
  4. uporabimo definicjo pospeška in iz nje izračunamo novi komponenti hitrosti, v_x\leftarrow v_x+a_x\cdot dt,\quad v_y\leftarrow v_y+a_y\cdot dt
  5. uporabimo definicijo hitrosti in iz nje določimo komponenti nove lege telesa  x\leftarrow x+v_x\cdot dt,\quad y\leftarrow y+v_y\cdot dt,
  6. narišemo novo lego,
  7. pravkar izračunani lego in hitrost proglasimo za stari, nato pa ponavljamo korake 3-7.

Tako simulacijo lahko izvedemo samo s kalkulatorjem, točke rišemo npr. na mmilimetrski papir (če ga še prodajajo). Lahko pa seveda uporabimo preglednico ali še boljše, programski jezik. Zadnje čase je naših šolah v modi  Python, sorazmerno lahko je  preiti nanj, čr ste se  prej ukvarjali s Pascalom in Delphijem.  Spodnji program je napisan v VisualPythonu,  različici, ki je posebej primerna za grafične prikaze.

Rezultat, ki ga dobimo, je premikajoč se satelit na spodnji sličici:



In takoj se ponujajo  modifikacije programa – satelit, ki pušča za sabo sled, preverjanje Keplerjevih zakonov, dvojna zvezda, zvezdna kopica, trk kopic….Zanimivo vprašanje, na katerega lahko prv hitro odgovorimo,  je postavil Ivan Kuščer: kakšen bi bil tir satelita, če bi privlačna sila med telesi nekoliko odstopala od Newtonovega gravitacijskega zakona, npr.

\vec{F}=\frac{GmM}{r^{3+\alpha}}\vec{r}.

Prav tako lahko npr. napišete  igro, v kateri z raketo in omejeno količino goriva pristajate na Zemlji ali Luni in ste ves čas v nevarnosti, da če vam goriva zmanjka, postanete umetni satelit….