Created
March 5, 2012 23:33
-
-
Save thejh/1982072 to your computer and use it in GitHub Desktop.
Runge-Kutta in Coco
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<!-- Der Deutsch-Englisch-Mischmasch tut mir leid, aber ich bin es gewohnt, auf Englisch zu programmieren, und kenne viele Fachbegriffe nicht auf English... | |
und dann wird mein Code zu einem Mischmasch, weil ich die ganze Zeit umschalte. | |
--> | |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | |
<title>Kurvenverläufe von Lotka-Volterra-Gleichungen malen</title> | |
<script type="coco"> | |
# die Differentialfunktionen von Räuber und Beute | |
# Argument 1: n1 und n2, Argument 2: Parameter | |
beutedifferenz = ({n1, n2}, {epsilon1, gamma1}) -> n1 * (epsilon1 - gamma1*n2) | |
räuberdifferenz = ({n1, n2}, {epsilon2, gamma2}) -> -n2 * (epsilon2 - gamma2*n1) | |
# Zahl aus einem Eingabefeld auslesen | |
getnumber = (name) -> | |
parseFloat (document.getElementById name).value | |
# Methode, um die Grafik neu zu zeichnen | |
window.redraw = !-> | |
t = 0 | |
# Werte aus den HTML-Eingabefeldern auslesen | |
xmax = getnumber \xmax | |
stepsperpixel = 100 | |
stepsize = (xmax / 600) / stepsperpixel | |
yscale = 200 / (getnumber \ymax) | |
n1 = getnumber \n1_0 | |
n2 = getnumber \n2_0 | |
# Parameter in einem Objekt speichern | |
parameters = | |
epsilon1: getnumber \epsilon1 | |
epsilon2: getnumber \epsilon2 | |
gamma1: getnumber \gamma1 | |
gamma2: getnumber \gamma2 | |
# Malbereich (canvas) initialisieren | |
context = (document.getElementById \canvas).getContext \2d | |
context.clearRect 0, 0, 600, 200 # transparent/weiß machen | |
# und jetzt das runge-kutta-verfahren in der schleife anwenden... | |
while t < 600 | |
# alte Werte zwischenspeichern, damit Linien zwischen alten und neuen Punkten gemacht werden können | |
oldn1 = n1 | |
oldn2 = n2 | |
for i from 1 to stepsperpixel | |
k1_beute = stepsize * beutedifferenz {n1: n1, n2: n2}, parameters | |
k1_räuber = stepsize * räuberdifferenz {n1: n1, n2: n2}, parameters | |
k2_beute = stepsize * beutedifferenz {n1: n1 + k1_beute/2, n2: n2 + k1_räuber/2}, parameters | |
k2_räuber = stepsize * räuberdifferenz {n1: n1 + k1_beute/2, n2: n2 + k1_räuber/2}, parameters | |
k3_beute = stepsize * beutedifferenz {n1: n1 + k2_beute/2, n2: n2 + k2_räuber/2}, parameters | |
k3_räuber = stepsize * räuberdifferenz {n1: n1 + k2_beute/2, n2: n2 + k2_räuber/2}, parameters | |
k4_beute = stepsize * beutedifferenz {n1: n1 + k3_beute, n2: n2 + k3_räuber}, parameters | |
k4_räuber = stepsize * räuberdifferenz {n1: n1 + k3_beute, n2: n2 + k3_räuber}, parameters | |
n1 += (k1_beute + 2*k2_beute + 2*k3_beute + k4_beute ) / 6 | |
n2 += (k1_räuber + 2*k2_räuber + 2*k3_räuber + k4_räuber) / 6 | |
t++ | |
# diesen Schritt malen | |
# jedesmal Y invertieren - canvas zählt von oben! | |
context.strokeStyle = "green" | |
context.beginPath! | |
context.moveTo t-1, 200 - Math.round oldn1*yscale | |
context.lineTo t, 200 - Math.round n1*yscale | |
context.stroke! | |
context.strokeStyle = "orange" | |
context.beginPath! | |
context.moveTo t-1, 200 - Math.round oldn2*yscale | |
context.lineTo t, 200 - Math.round n2*yscale | |
context.stroke! | |
# Daten in die Eingabefelder laden und neu zeichnen | |
window.preset = (data) -> | |
for key, value in data | |
(document.getElementById key).value = value | |
redraw! | |
console.log "loaded!" | |
</script> | |
<script src="coco.js"></script> | |
</head> | |
<body> | |
<div> | |
<!-- Ausgabebereich --> | |
<canvas id="canvas" width="600" height="200" style="border: 1px solid black">Wenn man das hier sieht, ist der Browser zu alt für das canvas-Tag</canvas> | |
</div> | |
<div> | |
<!-- Eingabefelder --> | |
Anfangsgröße der Beutepopulation: <input id="n1_0" value=""> | |
<br> | |
Anfangsgröße der Räuberpopulation: <input id="n2_0" value=""> | |
<br> | |
Reproduktionsrate der Beutepopulation: <input id="epsilon1" value=""> | |
<br> | |
Sterberate der Beutepopulation durch Räuber: <input id="gamma1" value=""> | |
<br> | |
Reproduktionsrate der Räuber pro Beutetier: <input id="gamma2" value=""> | |
<br> | |
Sterberate der Räuber bei Beutemangel: <input id="epsilon2" value=""> | |
<br> | |
t-Maximum: <input id="xmax" value=""> | |
<br> | |
Y-Maximum: <input id="ymax" value=""> | |
<br> | |
<button onclick="redraw()"> | |
OK | |
</button> | |
<p> | |
Dies sind einige nett aussehende Voreinstellungen: | |
<button onclick="preset({n1_0: 100, n2_0: 10, epsilon1: 0.01, gamma1: 0.0001, gamma2: 0.001, epsilon2: 0.03, xmax: 10000, ymax: 1000})">stabil</button> | |
</p> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment