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.

Grafika na spletni strani, Javascript in HTML5

Matematik želi prikazati matematično grafiko na zaslonu, po možnosti na spletni strani in -še bolj zaželjeno – po možnosti dinamično. Na začetku je te prikaze sprogramiral sam. Nato pa je bila v preteklih desetletjih razvita vrsta orodij, od tistih za prikaz grafov do orodij za modeliranje, ki se uporabljajo namensko npr. v strojništvu, gradbeništvu.  Programiranje je domala izginilo, sploh pa iz šol.  Slovenske firme danes vneto iščejo programerje, v glavnem brezuspešno. Nekatere jih morajo celo uvažati iz vzhodnih držav.

Sam sem se z dijaki precej ukvarjal z računalniško grafiko, najprej v strem dobrem Turbo Pascalu v operacijskem sistemu DOS, pod Okni pa v nadaljevanju Pascala  – programu Delphi. Dijaki so znali napisati samostojne grafične aplikacije, pretežno simulacije fizikalnih pojavov, in ti programi so se preko orodja Activex dali zaganjati tudi preko spleta. Napredno za tiste čase ob koncu tisočletja, a tudi povezano s težavami. Brskalnik je moral imeti varnostne nastavitve znižane, Delphi pa je bil plačljiv program in je kar nenadoma izginil, skupaj s svojo različico Kilix za Linux.

Sredi prejšnjega desetletja sem na nekem seminarju opazoval predavatelja, kako uspešno je zganjal grafiko na spletni strani z običajnim Javascriptom. Prikaz mi je bil zelo všeč, dosti manj pa koda. Sem pač scrkljan tako od Pascala in Delphija, da ko slišim C++, skoraj dobim ošpice, največ, kar lahko še prezvečim, je Python. Poleg tega se mi je zdelo, da uporablja trike iz CSS. Kljub temu sem napisal nekaj kratkih programov v Javascriptu, pa jih tudi hitro pozabil zaradi obilice drugega dela.

Potem pa mi je prišel v roke standard zadnje verzije HTML-ja, torej HTML 5.0. Podpirajo ga vsi moderni brskalniki, pa tudi mobilne priprave. Postal sem pozoren na njegovo podporo grafiki in sklenil sem, da spet poskusim. Tole je (s pomočjo priročnika seveda) pravkar ratalo. Ni bogvekaj in nič ne miga, je pa dokaz, da se da:

<html>
<head>
	<style type="text.css">
		canvas {border: 1px solid black}
	</style>
</head>
<body>
<h3>Moja prva grafika v HTML5</h3>
<canvas id="mycanvas" width="800" height="500"></canvas>
<script language ="Javascript">
var canvas = document.getElementById('mycanvas');
var c = canvas.getContext('2d');
c.fillStyle="red";
c.fillRect(0,0,20,10);

c.lineWidth=1;
c.beginPath();
c.moveTo(0,100);
c.lineTo(201,100);
c.stroke()

c.beginPath();
c.moveTo(100,0);
c.lineTo(100,120);
c.stroke()

for (i=-100;i<100;i++)
{
c.fillStyle="black";
c.lineColor="red";
c.lineWidth=3;
c.beginPath();
c.moveTo(i+100,100-i*i/100);
c.lineTo(i+101,100-i*i/100);
c.stroke()
}
</script>

</body>
</html>

zgornja koda  nam da naslednji graf kvadratne funkcije:

HTML5 ima navo značko platno <canvas>, na katerega lahko rišemo na spletni strani. Canvas je poznal tudi Delphi, zato  je pojem poznan. Nanj rišemo z ukazi iz Javascripta, kot so drawRect, fill in drawImage.

 

Moja prva grafika v HTML5