diff options
author | pommicket <leonardomtenenbaum@gmail.com> | 2016-10-16 15:54:48 -0400 |
---|---|---|
committer | pommicket <leonardomtenenbaum@gmail.com> | 2016-10-16 15:54:48 -0400 |
commit | 9b477c4c5d298ae32cb10a3be947b5525348324b (patch) | |
tree | 64ce285bd85691ff31bdf6e4c1afee46ce5bcaa0 | |
parent | 5f8337921b775d9262822deab39a23eab6e5146d (diff) |
Added log, multiple functions & width/height control to RPN.
-rw-r--r-- | complexfunctions.html | 18 | ||||
-rw-r--r-- | js/complex.js | 13 | ||||
-rw-r--r-- | js/complexfunctions.js | 70 |
3 files changed, 80 insertions, 21 deletions
diff --git a/complexfunctions.html b/complexfunctions.html index 2b67a3a..5917c00 100644 --- a/complexfunctions.html +++ b/complexfunctions.html @@ -9,7 +9,6 @@ Graph complex functions (C->C) <link rel="shortcut icon" type="image/png" href="favicon.png"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.js"></script> - <script src="http://www.numericjs.com/lib/numeric-1.2.6.min.js"></script> <script src="js/complex.js"></script> <script src="js/complexfunctions.js"></script> <script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> @@ -39,6 +38,20 @@ Graph complex functions (C->C) </div> </div> <br> + <div class="container-fluid row"> + <div class="input-group input-group-md col-lg-3 col-md-6 col-sm-8 col-xs-10"> + <span class="input-group-addon">Width</span> + <input id="width" class="form-control" type="number" value="750"> + </div> + </div> + <br> + <div class="container-fluid row"> + <div class="input-group input-group-md col-lg-3 col-md-6 col-sm-8 col-xs-10"> + <span class="input-group-addon">Height</span> + <input id="height" class="form-control" type="number" value="750"> + </div> + </div> + <br> <button id="animate" class="btn btn-default">Animate</button> <div id="canvas"></div> </div> @@ -56,6 +69,7 @@ Graph complex functions (C->C) Postfix notation looks like this: $$a\ b + c \sin +$$ For a more simple example, $a + b$ would be $a\ b\ +$, and $\sin x$ would be $x \sin$. + You can plot multiple functions by separating them with commas, but it will be slow. <h3>List of all functions and constants</h3> <table class='table table-bordered table-hover'> <tr><th>Function or constant</th> <th>What it means</th></tr> @@ -77,6 +91,8 @@ Graph complex functions (C->C) <tr><td>sin</td> <td>Sine</td></tr> <tr><td>cos</td> <td>Cosine</td></tr> <tr><td>tan</td> <td>Tangent</td></tr> + <tr><td>ln</td> <td>Natural logarithm ($\log_e x$)</td></tr> + <tr><td>log</td> <td>Logarithm ($\log_a b$)</td></tr> <tr><td>sinh</td> <td>Hyperbolic sine</td></tr> <tr><td>cosh</td> <td>Hyperbolic cosine</td></tr> <tr><td>tanh</td> <td>Hyperbolic tangent</td></tr> diff --git a/js/complex.js b/js/complex.js index 3f009bd..a66cbb0 100644 --- a/js/complex.js +++ b/js/complex.js @@ -203,6 +203,8 @@ complex.rpn = function (s) token = tokens[i]; switch (token) { + case "": + break; case "+": stack.push(complex.add(stack.pop(), stack.pop())); break; @@ -224,9 +226,17 @@ complex.rpn = function (s) var val1 = stack.pop(); stack.push(complex.pow(val1, val2)); break; + case "log": + var val2 = stack.pop(); + var val1 = stack.pop(); + stack.push(complex.log(val1, val2)); + break; case "sqrt": stack.push(complex.sqrt(stack.pop())); break; + case "ln": + stack.push(complex.ln(stack.pop())); + break; case "exp": stack.push(complex.exp(stack.pop())); break; @@ -260,6 +270,9 @@ complex.rpn = function (s) case "i": stack.push(complex.i); break; + case "-i": + stack.push(complex.neg(complex.i)); + break; case "e": stack.push(complex.E); break; diff --git a/js/complexfunctions.js b/js/complexfunctions.js index fce70a6..f71c23b 100644 --- a/js/complexfunctions.js +++ b/js/complexfunctions.js @@ -3,30 +3,52 @@ var rangePoints; var animating = false; var t = 0; var SCALE = 5; +var nFunctions; +var colors; function drawPoints(points) { background(255); for (var i = 0; i < points.length; i++) { - point((points[i][0]/SCALE+0.5)*width, (points[i][1]/SCALE+0.5)*height); + point((points[i][0]/(SCALE*width/750)+0.5)*width, (points[i][1]/(SCALE*height/750)+0.5)*height); } } +function drawManyPoints(points) +{ + background(255); + for (var f = 0; f < nFunctions; f++) + { + stroke(colors[f][0], colors[f][1], colors[f][2]); + for (var i = 0; i < points[f].length; i++) + { + point((points[f][i][0]/SCALE+0.5)*width, (points[f][i][1]/SCALE+0.5)*height); + } + } +} -function mapFunc(func) + +function mapFuncs(funcs) { - var f = complex.rpn(func); + var fs = funcs.map(complex.rpn); rangePoints = []; - for (var i = 0; i < domainPoints.length; i++) + var f; + for (var i = 0; i < funcs.length; i++) { - rangePoints.push(f(domainPoints[i])); + rangePoints.push([]); + f = fs[i]; + for (var j = 0; j < domainPoints.length; j++) + { + rangePoints[i].push(f(domainPoints[j])); + } } + nFunctions = fs.length; } -function drawFunc(func) +function drawFuncs(funcs) { - mapFunc(func); + mapFuncs(funcs); animating = true; } @@ -36,49 +58,57 @@ function draw() if (animating) { var midpoints = []; - for (var i = 0; i < domainPoints.length; i++) - midpoints.push(complex.add(complex.mult(domainPoints[i], complex.reToC(1-t)), complex.mult(rangePoints[i], complex.reToC(t)))); - - drawPoints(midpoints); + for (var f = 0; f < nFunctions; f++) + { + midpoints.push([]); + for (var i = 0; i < domainPoints.length; i++) + midpoints[f].push(complex.add(complex.mult(domainPoints[i], complex.reToC(1-t)), complex.mult(rangePoints[f][i], complex.reToC(t)))); + } + drawManyPoints(midpoints); t += 0.01; if (t >= 1) { animating = false; - drawPoints(rangePoints); + drawManyPoints(rangePoints); } } } -function setup() +function makeCanvas(w, h) { - var canvas = createCanvas(750, 750); + $("#canvas").html(); + var canvas = createCanvas(w, h); canvas.parent("canvas"); - stroke(0,0,100); domainPoints = []; for (var i = 10; i < width; i += 50) { for (var j = 0; j < height; j++) { - domainPoints.push([(j/width-0.5)*SCALE, (i/height-0.5)*SCALE]); - domainPoints.push([(i/width-0.5)*SCALE, (j/height-0.5)*SCALE]); + domainPoints.push([(j/width-0.5)*SCALE*width/750, (i/height-0.5)*SCALE*height/750]); + domainPoints.push([(i/width-0.5)*SCALE*width/750, (j/height-0.5)*SCALE*height/750]); } } drawPoints(domainPoints); } + $(function() { $("#animate").click(function() { + makeCanvas(parseInt($("#width").val()), parseInt($("#height").val())); t = 0; animating = false; - var func = $("#function").val(); - drawFunc(func); + var funcs = $("#function").val().split(","); + colors = []; + for (var i = 0; i < funcs.length; i++) + colors.push([Math.random() * 255, Math.random() * 255, Math.random() * 255]); + drawFuncs(funcs); }); - $("#function").keydown(function(e) + $(".form-control").keydown(function(e) { if (e.keyCode == 13) $("#animate").click(); |