Padanje kroglice in njen odboj od sten

Na spletni strani lahko, če uporabimo Javascript, kažemo tudi grafiko in celo kaj animiramo. Tule primer sposojene kode iz spletnega učbenika Javascripta, ki sem jo priredil za svoje potrebe.

Koda je naslednja:

<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width; charset=UTF-8; initial-scale=2.0"/>
<style>
.button {
  padding: 15px 25px;
  font-size: 24px;
  text-align: center;
  cursor: pointer;
  outline: none;
  color: #fff;
  background-color: #4CAF50;
  border: none;
  border-radius: 15px;
  box-shadow: 0 9px #999;
}

.button:hover {background-color: #3e8e41}

.button:active {
  background-color: #3e8e41;
  box-shadow: 0 5px #666;
  transform: translateY(4px);
}
</style>
</head>
<p>
Kažem kroglico, ki se odbija od tal in sten.
<body>
<p><button class="button" onclick ="startGame();">Klikni tu za začetek</button>
 
<script>
var mySound;
var myGamePiece;

function startGame() {
    myGamePiece = new component(10, "red", 5, 5);
 //   mySound=new sound("bounce.mp3");
    myGameArea.start();
}


var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 680;
        this.canvas.height = 470;
	this.canvas.style="border:10px solid #0000FF";
        this.context = this.canvas.getContext("2d");
      document.body.insertBefore(this.canvas, document.body.childNodes[0]);  
            this.interval = setInterval(updateGameArea, 20);
	        
    },	
     stop : function() {
        clearInterval(this.interval);
    },   
    clear : function() {
   this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);     
    }
}

function component(radij, color, x, y, type) {
	
    this.type = type;
    this.r = radij;
    this.x = x;
    this.y = y;    
    this.speedX = 3;
    this.speedY = 0;    
    this.gravity = 0.1;
    this.gravitySpeed = 0;
    this.bounce = 0.98;
    this.update = function() {
        ctx = myGameArea.context;
        ctx.beginPath();
        ctx.fillStyle = color;
        ctx.arc(this.x, this.y, this.r,0,2.1*Math.PI);
        ctx.fill();
        ctx.stroke()
    }
    this.newPos = function() {
        this.gravitySpeed += this.gravity;
        this.speedX=0.9995*this.speedX;
	this.x += this.speedX;
        this.y += this.speedY + this.gravitySpeed;
        this.hitBottom();
    }
    this.hitBottom = function() {
        var rockbottom = myGameArea.canvas.height - this.r;
	var rob =  myGameArea.canvas.width;      
	if ((this.y > rockbottom) || (this.y<0)) {
            this.y=rockbottom;
	    //mySound.play();
            this.gravitySpeed = -(this.gravitySpeed * this.bounce);
        }
	if ((this.x > rob-radij) || (this.x<5)) {
	    this.speedX=-this.speedX};
    }
}

function updateGameArea() {
    myGameArea.clear();
    myGamePiece.newPos();
    myGamePiece.update();
}

</script>

</body>
</html>

Z njo dobimo naslednjo animacijo:

Z majhno spremembo zgornje kode pa lahko namesto kroglice dobimo prikaz njenega tira:

<!DOCTYPE html>
<html>
<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width; charset=UTF-8; initial-scale=2.0"/>
<style>
.button {
  padding: 15px 25px;
  font-size: 24px;
  text-align: center;
  cursor: pointer;
  outline: none;
  color: #fff;
  background-color: #4CAF50;
  border: none;
  border-radius: 15px;
  box-shadow: 0 9px #999;
}

.button:hover {background-color: #3e8e41}

.button:active {
  background-color: #3e8e41;
  box-shadow: 0 5px #666;
  transform: translateY(4px);
}
</style>
</head>
<p>
Kažem tir kroglice, ki se odbija od tal in sten.
<body>
<p><button class="button" onclick ="startGame();">Klikni tu za začetek</button>
 
<script>
var mySound;
var myGamePiece;

function startGame() {
    myGamePiece = new component(0, "white", 5, 5);
 //   mySound=new sound("bounce.mp3");
    myGameArea.start();
}


var myGameArea = {
    canvas : document.createElement("canvas"),
    start : function() {
        this.canvas.width = 680;
        this.canvas.height = 470;
	this.canvas.style="border:10px solid #0000FF";
        this.context = this.canvas.getContext("2d");
      document.body.insertBefore(this.canvas, document.body.childNodes[0]);  
            this.interval = setInterval(updateGameArea, 20);
	        
    },	
     stop : function() {
        clearInterval(this.interval);
    },   
    clear : function() {
   this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);     
    }
}

function component(radij, color, x, y, type) {
	
    this.type = type;
    this.r = radij;
    this.x = x;
    this.y = y;    
    this.speedX = 2;
    this.speedY = 0;    
    this.gravity = 0.1;
    this.gravitySpeed = 0;
    this.bounce = 0.98;
    this.update = function() {
        ctx = myGameArea.context;
        //ctx.beginPath();
        ctx.fillStyle = color;
	//ctx.borderStyle="red";
	//ctx.style.color="blue";
        ctx.arc(this.x, this.y, this.r,0,2.1*Math.PI);
        ctx.fill();
        ctx.stroke()
    }
    this.newPos = function() {
        this.gravitySpeed += this.gravity;
        this.speedX=0.9995*this.speedX;
	this.x += this.speedX;
        this.y += this.speedY + this.gravitySpeed;
        this.hitBottom();
    }
    this.hitBottom = function() {
        var rockbottom = myGameArea.canvas.height - this.r;
	var rob =  myGameArea.canvas.width;      
	if ((this.y > rockbottom) || (this.y<0)) {
            this.y=rockbottom;
	   // mySound.play();
            this.gravitySpeed = -(this.gravitySpeed * this.bounce);
        }
	if ((this.x > rob-radij) || (this.x<5)) {
	    this.speedX=-this.speedX};
    }
}

function updateGameArea() {
    myGameArea.clear();
    myGamePiece.newPos();
    myGamePiece.update();
}

</script>

</body>
</html>

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.