ChaosHTMLJavascript

Use the text editor of your choice and save as Chaos.html

<!DOCTYPE html><html><head></head><body onload="setState()">
<canvas id="myCanvas" width="500" height="500" style="border:1px solid #d3d3d3;">Your browser does not support the HTML5 canvas tag.</canvas><br /> <div id="calc" style="position:relative; left:200px; top:-17px; color:red;">Calculating ...</div>
<input type="text" id="vertices" size="2" value="3" onfocus="this.select()" /><span id="numVertices" style="color: blue;"> = Number Of Vertices</span><br /><input type="text" id="radius" size="2" value="1" onfocus="this.select()" /><span id="pointRadius" style="color: blue;"> = PointRadius</span><br /><input type="text" id="orientation" size="4" value="0" onfocus="this.select()" /><span id="verticesOrientation" style="color: blue;"> = Vertices Orientation (degrees)</span><br /><br /><input type="text" id="ratio" size="4" value="0.5" onfocus="this.select()" /><span id="plotRatio" style="color: blue;"> = Plot Ratio</span><br /><input type="text" id="mag" size="4" value="0.9" onfocus="this.select()" /><span id="magnification" style="color: blue;"> = Magnification</span><br /><input type="text" id="maxIters" size="6" value="10000" /><span id="maxIterations" style="color: blue;"> = Max Number of Iterations</span><br /><br />
<script>
var canvas = document.getElementById("myCanvas");var context = canvas.getContext("2d");
var xmax = document.getElementById('myCanvas').width;var ymax = document.getElementById('myCanvas').height;
var rgba = context.getImageData(0, 0, xmax, ymax);
var maxIterations = 10000; // number of points plottedvar magnification = 0.9; // fraction of dim / 2 used for plot var plotRatio = 0.5; // fraction of dist. from curr. pt. to vertex// .5, .55, .62, .67, .69, .71, .73, .74 var numberOfVertices = 3;var verticesOrientation = 0; // Nico Suggestion (radians)var vertsOrient = -2*Math.PI * verticesOrientation/360; // Nico Suggestion (radians)
var isCalculating = 0; // track state of click actionvar isMouseDown = 0;var clickState = 0;var startx = 100;var starty = 100;var endx = 0;var endy = 0;var currentx = 0;var currenty = 0;var dim = Math.min(xmax, ymax);var xUnit = magnification * (dim / 2); var yUnit = xUnit; // number of pixels for 1 unit of distance var maxNumberOfVertices = 20;var color = new Array(maxNumberOfVertices); // color for each vertex
for (rep = 0; rep < maxNumberOfVertices; rep++){ color[rep] = new Array(3); }
color[0] = [255, 0, 0]; // each color is an array of 3 integers color[1] = [0, 255, 0]; // in [0, 255] for red, green, and blue color[2] = [0, 0, 255];color[3] = [255, 111, 255];color[4] = [138, 111, 226];color[5] = [100, 55, 180];color[6] = [0, 155, 255];color[7] = [0, 255, 255];color[8] = [155, 155, 155];color[9] = [255, 155, 255];color[10] = [200, 055, 155];color[11] = [55, 55, 255];color[12] = [55, 255, 155];color[13] = [0, 0, 55];color[14] = [0, 0, 55];color[15] = [0, 0, 255];color[16] = [0, 255, 0];color[17] = [255, 0, 155];color[18] = [55, 155, 155];color[19] = [55, 55, 255];
//============= Mouse Functions =============
function getMousePos(canvas, evt) { var rect = canvas.getBoundingClientRect(); return { x: evt.clientX - rect.left, y: evt.clientY - rect.top };}
canvas.addEventListener('mousemove', function(evt) { var mousePos = getMousePos(canvas, evt); currentx = mousePos.x; currenty = mousePos.y; setState();}, false);
canvas.addEventListener('mousedown', function(evt) {
isCalculating = 1; setState();}, false);
canvas.addEventListener('mouseup', function(evt) {
isCalculating = 0; if (clickState != 1) { drawFractal(); } isMouseDown = 0; setState();}, false);
//============= Drawing Functions =============
function drawRectangle(x, y){ updateCanvas(); context.beginPath(); context.globalCompositeOperation="xor"; context.rect(startx, starty, x - startx, y - starty); context.strokeStyle="000000"; context.stroke(); context.putImageData(rgba, 0, 0);}
function drawPixel (x, y, r, g, b, a){ var index = (x + y * xmax) * 4;
rgba.data[index + 0] = r; rgba.data[index + 1] = g; rgba.data[index + 2] = b; rgba.data[index + 3] = a;}
function dotPlot(xPixelCoord, yPixelCoord, radius, red, green, blue){ xPixelCoord = Math.trunc(xPixelCoord); yPixelCoord = Math.trunc(yPixelCoord); for (xco = xPixelCoord - radius; xco <= xPixelCoord + radius; xco++) { for (yco = yPixelCoord - radius; yco <= yPixelCoord + radius; yco++) { if ( inRange(xco, yco) && inCircle(xPixelCoord, yPixelCoord, radius, xco, yco) ){ drawPixel(xco, yco, red, green, blue, 255); } } }}
function inRange(x, y){ return x >= 0 && y >= 0 && x < xmax && y < ymax;}
function inCircle(cx, cy, r, x, y){ return Math.pow( Math.abs(cx - x), 2 ) + Math.pow( Math.abs(cy - y), 2 ) < r*r; } // bug had r instead of r*r function updateCanvas() { context.putImageData(rgba, 0, 0);}
//============= State Functions ===============
function setState(){ function setPrecision(num, digits) { return Math.round(num / Math.pow(10, digits - 1)) * Math.pow(10, digits - 1); }
var temp = "Number of Vertices = " + numberOfVertices; document.getElementById("vertices").innerHTML = temp; temp = "Plot Ratio = " + plotRatio; document.getElementById("ratio").innerHTML = temp; temp = "Magnification = " + magnification; document.getElementById("mag").innerHTML = temp; temp = "Max Iterations = " + maxIterations; document.getElementById("maxIters").innerHTML = temp; temp = "Vertices Orientation = " + verticesOrientation; document.getElementById("orientation").innerHTML = temp; if (isCalculating == 1) { document.getElementById("calc").innerHTML="Calculating ..."; } else { document.getElementById("calc").innerHTML="&nbsp;"; }}
//============= Fractal Functions =============
function convertCoordToXPixel( coord ) { // convert coord to pixel value for creative displays // return Math.trunc( xmax / 2 + 1.5*Math.cos(coord*coord)*xUnit*coord ); return Math.trunc( xmax / 2 + xUnit * coord ); // traditional }
function convertCoordToYPixel( coord ) { // convert coord to pixel value for creative displays // return Math.trunc( ymax / 2 - 1.1*Math.sin(1.2*Math.PI*coord) * yUnit * coord ); return Math.trunc( ymax / 2 - yUnit * coord ); // traditional}
function setVerticies(numberOfVertices, xUnit, yUnit) { vertex = new Array(numberOfVertices); // array for vertex coords for (rep = 0; rep < numberOfVertices; rep++){ vertex[rep] = new Array(2); // array of 2 coordinates per vertex } var tempx = 0.0; // x = x'cosT - y'sinT var tempy = 1.0; // y = x'sinT + y'cosT angle = 2 * Math.PI / numberOfVertices; theta = angle; // rotate vertex[0] theta to obtain other vertices vertex[0][0] = tempx * Math.cos(vertsOrient) - tempy * Math.sin(vertsOrient); vertex[0][1] = tempx * Math.sin(vertsOrient) + tempy * Math.cos(vertsOrient); dotPlot(convertCoordToXPixel(vertex[0][0]), convertCoordToYPixel(vertex[0][1]), 3*radius, color[0][0], color[0][1], color[0][2]);
for (rep = 1; rep < numberOfVertices; rep++){ vertex[rep][0] = vertex[0][0] * Math.cos(theta) - vertex[0][1] * Math.sin(theta); vertex[rep][1] = vertex[0][0] * Math.sin(theta) + vertex[0][1] * Math.cos(theta); theta += angle; dotPlot(convertCoordToXPixel(vertex[rep][0]), convertCoordToYPixel(vertex[rep][1]), 3*radius, color[rep][0], color[rep][1], color[rep][2]); } currVx = vertex[0][0]; // inital point for start of game currVy = vertex[0][1]; nextVx = currVx; nextVy = currVy; return vertex;}
function getNextXCoordinate(next, vert, plotRatio) { // add to the current coordinate the plotRatio // of the distance to the chosen vertex // return next + 0.75*Math.tan((vert - next) * plotRatio ); return next + (vert - next) * plotRatio; }
function getNextYCoordinate(next, vert, plotRatio) { // add to the current coordinate the plotRatio // of the distance to the chosen vertex // return next + 0.3*Math.tan(vert - next) * plotRatio; return next + (vert - next) * plotRatio; }
function errorCheckCorrect(elem, min, max, defaultValue){ var tempVal = document.getElementById(elem).value; if ( tempVal == "" || isNaN(tempVal) ) { tempVal = defaultValue; } else { tempVal = eval(tempVal); if (tempVal < min || tempVal > max) { tempVal = defaultValue; } } document.getElementById(elem).value = tempVal; return tempVal;}
function drawFractal(){ updateCanvas(); numberOfVertices = errorCheckCorrect("vertices", 1, 20, 1); plotRatio = errorCheckCorrect("ratio", 0.0, 3.0, 0.5); magnification = errorCheckCorrect("mag", 0.0, 2.0, 0.9); maxIterations = errorCheckCorrect("maxIters", 1, 100000, 10000); verticesOrientation = errorCheckCorrect("orientation", -360000, 360000, 0); vertsOrient = -2*Math.PI * verticesOrientation / 360; // rotate counterclockwise radius = errorCheckCorrect("radius", 0, 10, 1); vertex = setVerticies(numberOfVertices, xUnit, yUnit); for (rep = 0; rep < maxIterations; rep++) { updateCanvas(); vert = Math.floor( Math.random() * numberOfVertices ); currVx = getNextXCoordinate(currVx, vertex[vert][0], plotRatio); currVy = getNextYCoordinate(currVy, vertex[vert][1], plotRatio); pixelX = Math.floor( convertCoordToXPixel(currVx) ); pixelY = Math.floor( convertCoordToYPixel(currVy) ); if (pixelX >= 0 && pixelX < xmax && pixelY >= 0 && pixelY < ymax ) { dotPlot(pixelX, pixelY, radius, color[vert][0], color[vert][1], color[vert][2]); } } isCalculating = 0; clickSate = 0;}
</script>
</body></html>