Last active
December 17, 2015 00:51
-
-
Save birjj/70f2b35de601756e1546 to your computer and use it in GitHub Desktop.
En hurtig implementation af Eulers metode til numerisk løsning af koblede differentialligninger, til brug i min SRP
This file contains hidden or 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
| /** | |
| * PLEASE READ: | |
| * This is a very simple implementation of Eulers method for | |
| * numerically solving coupled differential equations, used | |
| * in an article of mine. It outputs the data in a CSV format | |
| * (which is plaintext). | |
| * | |
| * To run the code, press F12, go to the Console tab of the window | |
| * that opens, and paste the code (that's everything with the | |
| * line numbers, as seen to the left, beside it) in there. | |
| * A textbox should appear on the website (in the middle), which | |
| * contains your data. The easiest way to copy this data is to | |
| * click the textbox, then CTRL+A (or CMD+A if you're on a Mac) | |
| * and then CTRL+C (or CMD+C). | |
| * | |
| * To plot this data, paste it into | |
| * Notepad and save as <somename>.csv. Then open this file with | |
| * Excel and do "Insert > Scatterchart" (punktdiagram in Danish) | |
| * | |
| * The step size is set to 0.01, and the interval is [0;10]. | |
| * This gives us 1000 data points, and a small enough step size to | |
| * be relatively exact. | |
| */ | |
| // JS isn't good with tiny numbers, so we do all calculations | |
| // (eg. division with mass) beforehand | |
| var g = -9.82; | |
| var bPrM = 0.002185; | |
| var cPrM = 0.2033; | |
| function dX(x,y){ | |
| return -bPrM * x - cPrM*Math.sqrt(x*x+y*y)*x; | |
| } | |
| function dY(x,y){ | |
| return g - bPrM * y - cPrM*Math.sqrt(x*x+y*y)*y; | |
| } | |
| var data = Euler(dX,dY,8.845,1.946,0,10,.01); | |
| var outp = '"t";"Vx";"Vy"\n'; | |
| for (var i = 0; i < data.x.length; ++i) { | |
| outp += (data.x[i][0]+"").replace(".",",")+ | |
| ";"+ | |
| (data.x[i][1]+"").replace(".",",") | |
| +";"+ | |
| (data.y[i][1]+"").replace(".",",") | |
| +"\n"; | |
| } | |
| var t = document.createElement("textarea"); | |
| document.body.appendChild(t); | |
| t.value = outp; | |
| t.style.position = "fixed"; | |
| t.style.top = "50%"; | |
| t.style.left = "50%"; | |
| t.style.zIndex = "9999999"; | |
| t.style.boxShadow = "0 0 0 100vw rgba(0,0,0,.5)"; | |
| t.style.transform = "translate(-50%,-50%)"; | |
| /** | |
| * Numerically solve coupled differential functions | |
| * Func1 and func2 are called with | |
| * (val1, val2) | |
| */ | |
| function Euler(func1,func2,start1,start2,minVar,maxVar,stepVar){ | |
| var points1 = []; | |
| var points2 = []; | |
| var t = minVar; | |
| var p1 = [t,start1]; | |
| var p2 = [t,start2]; | |
| points1.push(p1); | |
| points2.push(p2); | |
| // we have our starting point | |
| // loop until we've reached end | |
| while (t < maxVar) { | |
| p1 = getNext(p1, stepVar, func1, p1[1],p2[1]); | |
| p2 = getNext(p2, stepVar, func2, p1[1],p2[1]); | |
| points1.push(p1); | |
| points2.push(p2); | |
| t += stepVar; | |
| } | |
| return {"x": points1, "y": points2}; | |
| } | |
| function getNext(prevP, stepVar, func,val1,val2) { | |
| var a = getAngle(func,val1,val2); | |
| console.log("Got angle",func,a,prevP[0]); | |
| return [ | |
| prevP[0] + stepVar, | |
| prevP[1] + stepVar*a | |
| ]; | |
| } | |
| function getAngle(func,val1,val2) { | |
| return func( | |
| val1, | |
| val2 | |
| ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment