tag:blogger.com,1999:blog-3378592448613414722024-03-20T01:06:37.799-07:00Be DiscreteAnonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.comBlogger33125tag:blogger.com,1999:blog-337859244861341472.post-21977057672306319142017-01-24T08:03:00.000-08:002017-01-24T09:41:00.078-08:00The Swarmalator<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>The Swarmalator</title>
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function slider(_min, _max, _inc, _val, _left, _right, _yp, _sliderw){
this.minv= _min,
this.maxv= _max;
this.inc= _inc;
this.val= _val;
this.range = (_max - _min)
this.left = _left;
this.right = _right;
this.width = (_right - _left);
this.get_sp = function(){ return this.width*(this.val - this.minv)/this.range }
this.sp = this.get_sp();
this.yp = _yp;
this.sliderw = _sliderw;
this.update = function(tinitx){
this.val = Math.min( this.maxv,Math.max( this.minv + this.range*(tinitx - this.left)/this.width, this.minv ) );
}
this.draw = function(ctx){
this.sp = this.get_sp();
ctx.beginPath();
ctx.moveTo(this.left,this.yp);
ctx.lineTo(this.right,this.yp);
ctx.stroke();
ctx.fillRect(this.left + this.sp-this.sliderw/2, this.yp-this.sliderw,this.sliderw,2*this.sliderw);
}
}
var canvas;
var context;
var canvas2;
var context2;
var size = 400;
var shw=35;
var shh=35;
var N = 250;
var oN = 1.0/N;
var runAnimation = {value: true};
var twopi = 2.0*Math.PI;
var torad = Math.PI/180;
var todeg = 180/Math.PI;
var birdrad = 3;
var birds = new Array(N);
var vel = new Array(N);
for (var i = 0; i < N; i++) {
birds[i] = new Array(3); //x, y, angle
vel[i] = new Array(3); //vx, vy, vangle
}
var J = 1;
var K = 0;
var dt = 0.05;
var sliderw=10;
var mysliderN = new slider(1,500,1,N, size/4, 3*size/4, 15 ,sliderw);
var mysliderJ = new slider(-2,2,0.01,J, size/4, 3*size/4, 40 ,sliderw);
var mysliderK = new slider(-2,2,0.01,K, size/4, 3*size/4, 65 ,sliderw);
var mysliderdt = new slider(0.01,0.05,0.01,dt, size/4, 3*size/4, 90 ,sliderw);
var sliders = new Array(4);
sliders[0] = mysliderN;
sliders[1] = mysliderJ;
sliders[2] = mysliderK;
sliders[3] = mysliderdt;
function random_init(){
for (var i = 0; i < N; i++) {
birds[i][0] = 2*Math.random();
birds[i][1] = 2*Math.random();
birds[i][2] = twopi * Math.random();
}
}
var offset = size*0.05;
var scale = size*0.45;
function draw_birds(){
for (var i = 0; i < N; i++) {
if( offset + birds[i][0]*scale > 0 &&
offset + birds[i][0]*scale < size &&
offset + birds[i][1]*scale > 0 &&
offset + birds[i][1]*scale < size){
context.beginPath();
context.arc(offset + birds[i][0]*scale, offset + birds[i][1]*scale,birdrad,0,twopi,0);
context.fillStyle="hsl("+birds[i][2]*todeg+", 100%, 50%)";
context.fill();
}
}
}
var close = (1.0*birdrad)/scale;
function update_velocity(){
for (var i = 0; i < N; i++) { vel[i][0] = 0; vel[i][1] = 0; vel[i][2] = 0; }
for (var i = 0; i < N; i++) {
for (var j = i+1; j < N; j++) {
if( j!= i ){
var dist0 = (birds[j][0] - birds[i][0]);
var dist1 = (birds[j][1] - birds[i][1]);
var dist2 = (birds[j][2] - birds[i][2]);
var distmag2 = dist0*dist0 + dist1*dist1;
var distmag = Math.sqrt(distmag2);
var radinc = ((1 + (1 + J*Math.cos(dist2)) )*distmag - 1)/distmag2;
vel[i][0] += dist0 * radinc; vel[j][0] -= dist0 * radinc;
vel[i][1] += dist1 * radinc; vel[j][1] -= dist1 * radinc;
var ang = Math.sin(dist2) / distmag;
vel[i][2] += ang; vel[j][2] -= ang;
}
}
}
}
function update_swarm(){
update_velocity();
var toN = dt*oN;
var KtoN = dt*K*oN;
for (var i = 0; i < N; i++) {
birds[i][0] += toN * vel[i][0];
birds[i][1] += toN * vel[i][1];
birds[i][2] += KtoN * vel[i][2];
}
}
function animate_birds(runAnimation, canvas, context) {
if(runAnimation.value) {
context.clearRect(-size,-size,3*size,3*size);
context.strokeRect(0,0,size,size);
update_swarm();
draw_birds();
}
setTimeout(function() {
requestAnimFrame(function() {
animate_birds( runAnimation, canvas, context);
});
}, 0);
}
function draw_sliders(){
context3.clearRect(0,0,size,size);
for(var i=0; i<4; ++i){ sliders[i].draw(context3); }
context3.fillStyle="black";
context3.font="15px Verdana";
var width = 40;
var fs = "N = " + N.toFixed(0).toString();
context3.fillText(fs ,sliders[0].left-80, sliders[0].yp, 70);
fs = "J = " + J.toFixed(2).toString(); context3.fillText(fs ,sliders[1].left-80, sliders[1].yp, 70);
fs = "K = " + K.toFixed(2).toString(); context3.fillText(fs ,sliders[2].left-80, sliders[2].yp, 70);
fs = "dt = " + dt.toFixed(2).toString(); context3.fillText(fs ,sliders[3].left-80, sliders[3].yp, 70);
}
function update_data(which_slider, tinitx){
sliders[which_slider].update(tinitx);
switch(which_slider){
case 0:
runAnimation = {value: false};
N = Math.round( sliders[which_slider].val );
birds = new Array(N);
vel = new Array(N);
for (var i = 0; i < N; i++) {
birds[i] = new Array(3); //x, y, angle
vel[i] = new Array(3); //vx, vy, vangle
}
random_init();
draw_birds();
runAnimation = {value: true};
break;
case 1:
J = sliders[which_slider].val;
break;
case 2:
K = sliders[which_slider].val;
break;
case 3:
dt = sliders[which_slider].val;
break;
default:
return 1;
}
draw_sliders();
return 0;
}
function add_event_listeners3(){
canvas3.addEventListener('mousedown', mdown3, false);
}
function remove_event_listeners3(){
canvas3.removeEventListener('mousemove', mmove3);
canvas3.removeEventListener('mouseup', mup3);
}
var which_slider;
function mdown3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
for(var i=0; i<4; i++){
//check for slider position
if( ( tinitx > sliders[i].left ) && ( tinitx < sliders[i].right ) && Math.abs( tinity - sliders[i].yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = i;
update_data(which_slider, tinitx);
return 0
}
}
}
function mmove3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
update_data(which_slider, tinitx);
}
function mup3(evt){
remove_event_listeners3();
}
function init_swarm(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(shw, shh);
canvas3 = document.getElementById("canvas3");
context3 = canvas3.getContext("2d");
context3.translate(shw, shh);
context.strokeRect(0,0,size,size);
random_init();
draw_birds();
draw_sliders();
add_event_listeners3();
animate_birds(runAnimation, canvas, context);
}
</script>
</head>
<body onLoad="init_swarm();">
<div id="SwarmContainer" style="width: 600px">
<div id="Swarm" style="float: left;">
<canvas id="canvas" width="512" height="450"></canvas>
</div>
<div id="matrix" style="float: left;">
<canvas id="canvas3" width="512" height="151"></canvas>
</div>
</div>
<div id="textContainer" style="width: 501px">
<p>The Swarmalator taken from O'Keeffe and Strogatz <a href="https://arxiv.org/abs/1701.05670">(arXiv)</a>. N is
the number of particles, K is the strength of the phase coupling (neighbours want to have same colour for
K > 0, as different as possible for K < 0) and J is the attraction between phases (J > 0 like attracts like,
J < 0 opposite phases attract). dt is the timestep for Euler integration (warning can go unstable for large dt!).
Restart by clicking the N slider below which moves all the particles to a random position and gives then a random phase/colour.
</p>
<p>
Phases:
<ul>
<li>Static Sync. e.g. (J,K) = (0.1,1)</li>
<li>Static Async. e.g. (J,K) = (0.1,-1)</li>
<li>Static Phase Wave. e.g. (J,K) = (1,0)</li>
<li>Splintered Phase Wave. e.g. (J,K) = (2,-0.3) this can take some time to fully develop.</li>
<li>Active Phase Wave. e.g. (J,K) = (1,-0.8)</li>
</ul>
</p>
</div>
</body>
</html>
Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com4tag:blogger.com,1999:blog-337859244861341472.post-35763305829955574302016-10-05T05:54:00.001-07:002016-10-06T02:02:55.752-07:00Markov Model<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Markov Model</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
tfs = ctx.fillStyle;
ctx.fillStyle=fs;
ctx.fill();
ctx.fillStyle = tfs;
}
function drawdot_t(ctx,x,y,r,fs, al){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.globalAlpha = al;
ctx.fillStyle=fs;
ctx.fill();
ctx.globalAlpha = 1;
}
var canvas;
var context;
var h = 500;
var w = 500;
var runAnimation = {value: true};
var shw = 65;
var shh = 65;
var rad = w/2;
var dt = 1;
var t = 0;
var node_pos;
var A;
var num;
var state = 0;
var node_rad = 15;
var node_rad2 = node_rad*node_rad;
var t=100;
var arrow_width = 6;
var arrow_len = 16;
function draw_arrow(xstart, ystart, xend, yend, r, col, arrow_start){
context.translate(xstart, ystart);
xend -= xstart;
yend -= ystart;
var len=Math.sqrt(xend*xend + yend*yend) - r;
var cost = xend/len;
var sint = yend/len;
//draw
context.beginPath();
var ow = context.lineWidth;
context.lineWidth=1.5;
context.fillStyle=col;
context.strokeStyle=col;
//first bit
var xen = arrow_start*len*cost;
var yen = arrow_start*len*sint;
context.moveTo(r*cost,r*sint);
context.lineTo(xen, yen);
context.stroke();
//arrowhead
context.lineWidth=ow;
context.lineTo(xen + arrow_width*sint, yen - arrow_width*cost);
context.lineTo(xen + arrow_len*cost, yen + arrow_len*sint);
context.lineTo(xen - arrow_width*sint, yen + arrow_width*cost);
context.lineTo(xen, yen);
context.stroke();
context.fill();
//last bit
context.lineWidth=1.5;
context.moveTo(xen + arrow_len*cost,yen + arrow_len*sint);
context.lineTo(xend -r*cost, yend - r*sint);
context.stroke();
context.lineWidth=ow;
context.fillStyle="black";
context.strokeStyle="black";
context.translate(-xstart, -ystart);
}
function draw_looparrow(xend, yend, loop, r, col){
var len=Math.sqrt(xend*xend + yend*yend);
var cost = xend/len;
var sint = yend/len;
//draw
context.beginPath();
var ow = context.lineWidth;
context.lineWidth=1.5;
context.fillStyle=col;
context.strokeStyle=col;
//first bit
var xen = xend + 2*r*cost;
var yen = yend + 2*r*sint;
context.arc(xen,yen,loop,0.0,2.0*Math.PI,0);
context.stroke();
//arrowhead
var xen = xend + (2*r+loop)*cost;
var yen = yend + (2*r+loop)*sint;
context.beginPath();
context.lineWidth=ow;
context.moveTo(xen, yen);
context.lineTo(xen + arrow_width*cost, yen + arrow_width*sint);
context.lineTo(xen - arrow_len*sint, yen + arrow_len*cost);
context.lineTo(xen - arrow_width*cost, yen - arrow_width*sint);
context.lineTo(xen, yen);
context.stroke();
context.fill();
context.fillStyle="black";
context.strokeStyle="black";
}
function setup_nodes(num_){
num = num_;
node_pos = new Array(num);
A = new Array(num);
for(var i=0; i<num; i++){ node_pos[i] = new Array(2); A[i] = new Array(num); }
var dt = 2.0*Math.PI / num;
for(var i=0; i<num; i++){
var x = rad * Math.sin(i*dt); //top of circle -> t = 0;
var y = rad * Math.cos(i*dt);
node_pos[i][0] = x;
node_pos[i][1] = y;
for(var j=0; j<num; j++){ A[i][j] = 0.0; }
A[i][ (i+1)%num ] = 1;
}
/*A[0][0] = 0; A[0][1] = 1; A[0][2] = 0; A[0][3] = 0;
A[1][0] = 0; A[1][1] = 0; A[1][2] = 1; A[1][3] = 0;
A[2][0] = 0; A[2][1] = 0; A[2][2] = 0; A[2][3] = 1;
A[3][0] = 1; A[3][1] = 0; A[3][2] = 0; A[3][3] = 0;*/
}
function multinomial_sample(){
var rand = Math.random();
cum = A[state][0];
if( rand < cum ){return 0; }
for(var i=1; i<num; i++){
cum += A[state][i];
if(rand < cum){ return i; }
}
return num-1;
}
function set_A(){
A[0][0] = parseFloat(document.getElementById('h00').value);
A[0][1] = parseFloat(document.getElementById('h01').value);
A[0][2] = parseFloat(document.getElementById('h02').value);
A[0][3] = parseFloat(document.getElementById('h03').value);
A[0][4] = parseFloat(document.getElementById('h04').value);
A[1][0] = parseFloat(document.getElementById('h10').value);
A[1][1] = parseFloat(document.getElementById('h11').value);
A[1][2] = parseFloat(document.getElementById('h12').value);
A[1][3] = parseFloat(document.getElementById('h13').value);
A[1][4] = parseFloat(document.getElementById('h14').value);
A[2][0] = parseFloat(document.getElementById('h20').value);
A[2][1] = parseFloat(document.getElementById('h21').value);
A[2][2] = parseFloat(document.getElementById('h22').value);
A[2][3] = parseFloat(document.getElementById('h23').value);
A[2][4] = parseFloat(document.getElementById('h24').value);
A[3][0] = parseFloat(document.getElementById('h30').value);
A[3][1] = parseFloat(document.getElementById('h31').value);
A[3][2] = parseFloat(document.getElementById('h32').value);
A[3][3] = parseFloat(document.getElementById('h33').value);
A[3][4] = parseFloat(document.getElementById('h34').value);
A[4][0] = parseFloat(document.getElementById('h40').value);
A[4][1] = parseFloat(document.getElementById('h41').value);
A[4][2] = parseFloat(document.getElementById('h42').value);
A[4][3] = parseFloat(document.getElementById('h43').value);
A[4][4] = parseFloat(document.getElementById('h44').value);
}
function draw_mm(){
context.clearRect(-shw-rad,-shh-rad,w + 2*shw,h+2*shh);
for(var i=0; i<num; i++){
for(var j=0; j<num; j++){
if( A[i][j] > 0 ){
if( i!= j){
draw_arrow(node_pos[i][0], node_pos[i][1], node_pos[j][0], node_pos[j][1],node_rad, "black", 0.66);
} else {
draw_looparrow(node_pos[i][0], node_pos[i][1], 30, node_rad, "black");
}
}
}
}
for(var i=0; i<num; i++){
if(i==state){
drawdot(context,node_pos[i][0], node_pos[i][1],node_rad,"red");
} else {
drawdot(context,node_pos[i][0], node_pos[i][1],node_rad,"blue");
}
}
}
function animate_mm(runAnimation, canvas, context) {
if(runAnimation.value ) {
state = multinomial_sample();
draw_mm();
}
setTimeout(function() {
requestAnimFrame(function() {
animate_mm( runAnimation, canvas, context);
});
}, t);
}
function set_state(tinitx, tinity){
for(var i=0; i<num; i++){
if( (tinitx - node_pos[i][0])*(tinitx - node_pos[i][0])
+ (tinity - node_pos[i][1])*(tinity - node_pos[i][1]) < node_rad2 ){
state = i;
break;
}
}
}
function mup1(){
runAnimation.value = true;
}
function mdown1(evt){
runAnimation.value = false;
evt.preventDefault();
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - rad;
var tinity = evt.clientY - rect.top - shh - rad;
set_state(tinitx, tinity)
draw_mm();
}
function mend1(){
runAnimation.value = false;
}
function mstart1(evt){
runAnimation.value = false;
evt.preventDefault();
var rect = canvas .getBoundingClientRect();
var tinitx = evt.touches[0].clientX - rect.left - shw - rad;
var tinity = evt.touches[0].clientY - rect.top - shh - rad;
set_state(tinitx, tinity)
draw_mm();
}
function add_event_listeners(){
canvas.addEventListener('mousedown', mdown1, false);
canvas.addEventListener('touchstart', mstart1, false);
canvas.addEventListener('mouseup', mup1, false);
canvas.addEventListener('touchend', mend1, false);
}
function init_mm(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(shw, shh);
context.font="italic 15px Helvetica";
//centre
context.translate(rad,rad);
add_event_listeners();
setup_nodes(5);
draw_mm(15);
runAnimation.value = true;
animate_mm( runAnimation, canvas, context);
}
</script>
<style type="text/css">
table{
border: 1px solid black;
table-layout: fixed;
width: 250px;
}
th, td {
border: 1px solid black;
overflow: hidden;
width: 50px;
}
</style>
</head>
<body onLoad="init_mm();">
</BR>
<div id="mmContainer" style="width: 600px; margin-left: 0px;">
<div id="mm" style="margin-left: 0px; float: left;">
<canvas id="canvas" width="700" height="700"></canvas>
</div>
<div id="Hform">
<label style="margin: 60px; font-weight: bold; font-size: 20px; float: left;">A</label>
<form id="theForm" method="get" action="submitData" style="float: left;">
<table style="width: 200px; table-layout=fixed" >
<tr>
<td width = "20"><input type="text" id="h00" name="h00" class="box" value="0.5"/></td>
<td width = "20"><input type="text" id="h01" name="h01" class="box" value="0.5"/></td>
<td width = "20"><input type="text" id="h02" name="h02" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h03" name="h03" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h04" name="h04" class="box" value="0"/></td>
</tr>
<tr>
<td width = "20"><input type="text" id="h10" name="h10" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h11" name="h11" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h12" name="h12" class="box" value="1"/></td>
<td width = "20"><input type="text" id="h13" name="h13" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h14" name="h14" class="box" value="0"/></td>
</tr>
<tr>
<td width = "20"><input type="text" id="h20" name="h20" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h21" name="h21" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h22" name="h22" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h23" name="h23" class="box" value="1"/></td>
<td width = "20"><input type="text" id="h24" name="h24" class="box" value="0"/></td>
</tr>
<tr>
<td width = "20"><input type="text" id="h30" name="h30" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h31" name="h31" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h32" name="h32" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h33" name="h33" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h34" name="h34" class="box" value="1"/></td>
</tr>
<tr>
<td width = "20"><input type="text" id="h40" name="h40" class="box" value="1"/></td>
<td width = "20"><input type="text" id="h41" name="h41" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h42" name="h42" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h43" name="h43" class="box" value="0"/></td>
<td width = "20"><input type="text" id="h44" name="h44" class="box" value="0"/></td>
</tr>
</table>
</BR>
<INPUT TYPE="button" NAME="run" Value="Update A" onClick="set_A()">
</form>
</div>
</div>
</body>
</html>
Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-70588508719340526312016-03-27T10:16:00.000-07:002016-03-27T10:16:59.311-07:00Moiré patterns<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Moire</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
var canvas;
var context;
var shw=0;
var shh=0;
var width = 300;
var height = 300;
var rw = 10;
var runAnimation = {value: true};
function draw_pattern1(){
var num = 2*width/rw;
for(var i=0; i<num; i++){
context1.fillRect(-width + i*2*rw,-height,rw,3*height);
}
}
function draw_pattern_rot1(theta){
context1.translate(width/2,height/2)
context1.rotate(theta);
context1.translate(-width/2,-height/2)
draw_pattern1();
context1.translate(width/2,height/2)
context1.rotate(-theta);
context1.translate(-width/2,-height/2)
}
function draw_pattern2(){
var num = 4*width/rw;
for(var j=0; j<num; j+=2){
for(var i=0; i<num; i++){
context2.fillRect(-2*width + i*2*rw,-2*height + j*rw,rw,rw);
context2.fillRect(-2*width + i*2*rw+rw,-2*height + j*rw+rw,rw,rw);
}
}
}
function draw_pattern_rot2(theta){
context2.translate(width/2,height/2)
context2.rotate(theta);
context2.translate(-width/2,-height/2)
draw_pattern2();
context2.translate(width/2,height/2)
context2.rotate(-theta);
context2.translate(-width/2,-height/2)
}
var sq32 = Math.sqrt(3)/2;
function triangle(x, y, w){
context3.beginPath();
context3.moveTo(x,y);
context3.lineTo(x+w,y);
context3.lineTo(x+w/2,y-sq32*w);
context3.fill();
}
function draw_pattern3(){
var num = 4*width/rw;
for(var j=0; j<num; j+=2){
for(var i=0; i<num; i++){
triangle(-2*width + i*rw,-2*height + j*rw,rw);
triangle(-2*width + i*rw+rw/2,-2*height + j*rw+rw,rw);
}
}
}
function draw_pattern_rot3(theta){
context3.translate(width/2,height/2)
context3.rotate(theta);
context3.translate(-width/2,-height/2)
draw_pattern3();
context3.translate(width/2,height/2)
context3.rotate(-theta);
context3.translate(-width/2,-height/2)
}
var angle1 = 0;
var angle2 = 0;
var angle3 = 0;
function animate_grid1(runAnimation, canvas, context) {
if(runAnimation.value) {
context.clearRect(-shw,-shh,width + 2*shw, height + 2*shh);
draw_pattern_rot1(0);
draw_pattern_rot1(angle1);
angle1 = (angle1 + 0.01);
}
setTimeout( function() {
requestAnimFrame(function() {
animate_grid1( runAnimation, canvas, context);
});
}, 20);
}
function animate_grid2(runAnimation, canvas, context) {
if(runAnimation.value) {
context.clearRect(-shw,-shh,width + 2*shw, height + 2*shh);
draw_pattern_rot2(0);
draw_pattern_rot2(angle2);
angle2 = (angle2 + 0.01);
}
setTimeout( function() {
requestAnimFrame(function() {
animate_grid2( runAnimation, canvas, context);
});
}, 20);
}
function animate_grid3(runAnimation, canvas, context) {
if(runAnimation.value) {
context.clearRect(-shw,-shh,width + 2*shw, height + 2*shh);
draw_pattern_rot3(0);
draw_pattern_rot3(angle3);
angle3 = (angle3 + 0.01);
}
setTimeout( function() {
requestAnimFrame(function() {
animate_grid3( runAnimation, canvas, context);
});
}, 20);
}
function init_tower(){
canvas1 = document.getElementById("canvas1");
context1 = canvas1.getContext("2d");
canvas2 = document.getElementById("canvas2");
context2 = canvas2.getContext("2d");
canvas3 = document.getElementById("canvas3");
context3 = canvas3.getContext("2d");
animate_grid1(runAnimation, canvas1, context1);
animate_grid2(runAnimation, canvas2, context2);
animate_grid3(runAnimation, canvas3, context3);
}
</script>
</head>
<body onLoad="init_tower();">
<div id="PendContainer" style="width: 300px">
<div id="Pend" style="float: left;">
<canvas id="canvas1" width="290" height="290"></canvas>
</div>
</div>
<div id="PendContainer" style="width: 300px">
<div id="Pend" style="float: left;">
<canvas id="canvas2" width="290" height="290"></canvas>
</div>
</div>
<div id="PendContainer" style="width: 300px">
<div id="Pend" style="float: left;">
<canvas id="canvas3" width="290" height="290"></canvas>
</div>
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-10669033687816487512016-01-24T12:36:00.000-08:002016-01-25T09:54:49.035-08:00Co-ordinate Change<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Parabolscoords</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
ctx.fillStyle="black";
}
var canvas;
var context;
var canvas3;
var context3;
var size = 500;
var hsize = size;
var tot = 750;
var shw = 1;
var shh = 1;
var shiftx = 0;
var shifty = 0;
var theta = 0*Math.PI/180;
var a = 1;
var b = 0;
var c = 0;
var d = 0;
var e = 1;
var f = 0;
var P = 1;
var Q = 0;
var R = 0;
var S = 0;
var T = 1;
var U = 0;
var reset_col = "red"
var bw = 100;
var bh = 33;
var resetx = size/2 - bw/2;
var resety = 135;
function plot_function(x){
return -x*x;
}
function update_params(){
var ct = Math.cos(theta);
var st = Math.sin(theta);
var xt = shiftx/hsize;
var yt = -shifty/size;
a = ct*ct;
b = -2*ct*st;
c = st*st;
d = -st + 2*ct*st*yt - 2*ct*ct*xt;
e = -ct + 2*ct*st*xt - 2*st*st*yt;
f = -2*ct*st*xt*yt + st*st*yt*yt + ct*ct*xt*xt + st*xt + ct*yt;
P = ct;
Q = st;
R = -ct*xt - st*yt;
S = -st;
T = ct;
U = st*xt - ct*yt;
//var check = a*xt*xt + b*xt*yt + c*yt*yt + d*xt + e*yt + f;
//var ww = (P*xt + Q*yt + R);
//var tt = (S*xt + T*yt + U);
//var check2 = (ww*ww - tt)
//console.log( xt, yt, theta, check, check2 );
}
function draw_parabola(left, right, dx, dy, theta, fs){
var inc = (right-left)/100;
var x = left;
context.strokeStyle=fs;
context.translate(hsize/2, size/2);
context.translate(dx, dy);
context.rotate(theta);
context.beginPath();
context.moveTo(x*hsize,plot_function(x)*hsize);
x+=inc;
for(var i=1; i<=100; i++){
context.lineTo(x*hsize,plot_function(x)*hsize);
x+=inc;
}
context.stroke();
context.rotate(-theta);
context.translate(-dx, -dy);
context.translate(-hsize/2, -size/2);
context.strokeStyle="Black"
}
function draw_axis(dx, dy, theta, fs){
context.strokeStyle=fs;
context.translate(hsize/2, size/2);
context.translate(dx, dy);
context.rotate(theta);
context.setLineDash([5])
context.beginPath();
context.moveTo(-hsize,0);
context.lineTo(hsize,0);
context.stroke();
context.beginPath();
context.moveTo(0,-size);
context.lineTo(0,size);
context.stroke();
context.setLineDash([]);
context.strokeStyle="Black";
context.rotate(-theta);
context.translate(-dx, -dy);
context.translate(-hsize/2, -size/2);
}
function draw_all(){
context.clearRect(-shw,-shh,tot,tot);
context.strokeRect(0,0,size,hsize);
draw_axis(0,0,0,"Black");
draw_axis(shiftx,shifty,theta,"Red");
//draw_parabola(-2, 2, 0, 0, 0, "Black");
draw_parabola(-2, 2, shiftx, shifty, theta, "Red");
update_params();
context3.clearRect(-shw,-shh,tot,tot);
context3.fillStyle="black";
context3.font="15px Verdana";
var left_off = size/10;
var fs = a.toFixed(2).toString() + "x";
context3.fillText(fs ,left_off, 25, 40);
context3.font="12px Verdana";
context3.fillText("2" ,left_off+40, 15, 10);
context3.font="15px Verdana";
fs = ""
if( b < 0 ){
fs += " - " + (-b).toFixed(2).toString();
} else {
fs += " + " + b.toFixed(2).toString()
}
fs += "xy"
context3.fillText(fs ,left_off+50, 25, 80);
fs="";
if( c < 0 ){
fs += " - " + (-c).toFixed(2).toString();
} else {
fs += " + " + c.toFixed(2).toString()
}
fs += "y";
context3.fillText(fs ,left_off+130, 25, 60);
context3.font="12px Verdana";
context3.fillText("2" ,left_off+190, 15, 10);
context3.font="15px Verdana";
fs = "";
if( d < 0 ){
fs += " - " + (-d).toFixed(2).toString();
} else {
fs += " + " + d.toFixed(2).toString()
}
fs += "x"
if( e < 0 ){
fs += " - " + (-e).toFixed(2).toString();
} else {
fs += " + " + e.toFixed(2).toString()
}
fs += "y"
if( f < 0 ){
fs += " - " + (-f).toFixed(2).toString();
} else {
fs += " + " + f.toFixed(2).toString()
}
fs += " = 0"
context3.fillText(fs ,left_off+200, 25, 250);
fs = "X = ";
if( P < 0 ){
fs += " - " + (-P).toFixed(2).toString();
} else {
fs += P.toFixed(2).toString()
}
fs += "x"
if( Q < 0 ){
fs += " - " + (-Q).toFixed(2).toString();
} else {
fs += " + " + Q.toFixed(2).toString()
}
fs += "y"
if( R < 0 ){
fs += " - " + (-R).toFixed(2).toString();
} else {
fs += " + " + R.toFixed(2).toString()
}
context3.fillText(fs ,size/4, 55, 200);
fs = "Y = ";
if( S < 0 ){
fs += " - " + (-S).toFixed(2).toString();
} else {
fs += S.toFixed(2).toString()
}
fs += "x"
if( T < 0 ){
fs += " - " + (-T).toFixed(2).toString();
} else {
fs += " + " + T.toFixed(2).toString()
}
fs += "y"
if( U < 0 ){
fs += " - " + (-U).toFixed(2).toString();
} else {
fs += " + " + U.toFixed(2).toString()
}
context3.fillText(fs ,size/4, 85, 200);
fs = "\u03B8 = ";
var angle = (theta + Math.PI*2)%(2 * Math.PI)
if( angle < 0 ){
fs += " - " + (-angle ).toFixed(2).toString();
} else {
fs += angle .toFixed(2).toString()
}
var dxt = shiftx/hsize;
var dyt = shifty/size;
fs += " (\u0394x, \u0394y) = ("
if( dxt < 0 ){
fs += "-" + (-dxt).toFixed(2).toString();
} else {
fs += dxt.toFixed(2).toString()
}
fs += ","
if( dyt < 0 ){
fs += "-" + (-dyt).toFixed(2).toString();
} else {
fs += dyt.toFixed(2).toString()
}
fs+=")"
context3.fillText(fs ,size/5, 115, 3*size/5);
context3.fillStyle=reset_col;
context3.fillRect(resetx, resety, bw, bh);
context3.strokeRect(resetx, resety, bw, bh);
context3.fillStyle="black";
}
function remove_event_listeners(){
canvas.removeEventListener('mousemove', mmove1);
canvas.removeEventListener('mouseup', mup1);
canvas.removeEventListener('touchmove', mtouch1);
canvas.removeEventListener('touchend', mend1);
canvas3.removeEventListener('mouseup', mup3);
canvas3.removeEventListener('touchend', mend3);
}
function add_event_listeners(){
canvas.addEventListener('mousedown', mdown1, false);
canvas.addEventListener('touchstart', mstart1, false);
canvas3.addEventListener('mousedown', mdown3, false);
canvas3.addEventListener('touchstart', mstart3, false);
}
function mdown3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
reset(tinitx,tinity);
}
function mstart3(evt){
evt.preventDefault();
var rect = canvas .getBoundingClientRect();
var tinitx = evt.touches[0].clientX - rect.left - shw;
var tinity = evt.touches[0].clientY - rect.top - shh;
reset(tinitx,tinity);
}
function reset(tinitx, tinity){
if( tinitx > resetx && tinitx < resetx + bw && tinity > resety && tinity < resety+bh ){
reset_col = "Tomato"
draw_all();
canvas3.addEventListener('mouseup', mup3, false);
canvas3.addEventListener('touchend', mend3, false);
}
}
function mup3(evt){
reset_all();
}
function mend3(evt){
reset_all();
}
function reset_all(){
reset_col = "Red";
theta = 0;
shiftx = 0;
shifty = 0;
draw_all();
}
var mot=0;
function mdown1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize/2;
var tinity = evt.clientY - rect.top - shh - size/2;
//console.log("mouse", evt.clientX, evt.clientY);
init_press(tinitx, tinity);
}
function mstart1(evt){
evt.preventDefault();
var rect = canvas .getBoundingClientRect();
var tinitx = evt.touches[0].clientX - rect.left - shw - hsize/2;
var tinity = evt.touches[0].clientY - rect.top - shh - size/2;
//console.log("touch", evt.touches[0].clientX, evt.touches[0].clientY);
init_press(tinitx, tinity);
}
var finger_fatness = 20;
function init_press(tinitx, tinity){
//x axis
var x1 = shiftx;
var y1 = shifty;
var x2 = 0.1*hsize*Math.cos(theta)+shiftx;
var y2 = 0.1*hsize*Math.sin(theta)+shifty;
//drawdot(context, x1+hsize/2,y1+hsize/2,5,"Green");
//drawdot(context, x2+hsize/2,y2+hsize/2,5,"Green");
var xdist = Math.abs( (y2 -y1)*tinitx - (x2-x1)*tinity + x2*y1 - y2*x1 )/Math.sqrt( (y2 -y1)*(y2 -y1) + (x2-x1)*(x2-x1) );
//y axis
x2 = 0.1*hsize*Math.cos(theta+Math.PI/2)+shiftx;
y2 = 0.1*hsize*Math.sin(theta+Math.PI/2)+shifty;
//drawdot(context, x1+hsize/2,y1+hsize/2,5,"Green");
//drawdot(context, x2+hsize/2,y2+hsize/2,5,"Green");
var ydist = Math.abs( (y2 -y1)*tinitx - (x2-x1)*tinity + x2*y1 - y2*x1 )/Math.sqrt( (y2 -y1)*(y2 -y1) + (x2-x1)*(x2-x1) );
//console.log(xdist, ydist);
if( xdist < finger_fatness && ydist < finger_fatness ){
drawdot(context, tinitx+hsize/2, tinity+size/2, 5, "Blue");
canvas.addEventListener('mousemove', mmove1, false);
canvas.addEventListener('mouseup', mup1, false);
canvas.addEventListener('touchmove', mtouch1, false);
canvas.addEventListener('touchend', mend1, false);
mot = 0;
}
else if( xdist < finger_fatness && ydist > finger_fatness ){
drawdot(context, tinitx+hsize/2, tinity+size/2, 5, "Blue");
canvas.addEventListener('mousemove', mmove1, false);
canvas.addEventListener('mouseup', mup1, false);
canvas.addEventListener('touchmove', mtouch1, false);
canvas.addEventListener('touchend', mend1, false);
if(tinitx > shiftx ){ mot = 1; }
else{ mot = 2; }
}
else if( xdist > finger_fatness && ydist < finger_fatness ){
drawdot(context, tinitx+hsize/2, tinity+size/2, 5, "Blue");
canvas.addEventListener('mousemove', mmove1, false);
canvas.addEventListener('mouseup', mup1, false);
canvas.addEventListener('touchmove', mtouch1, false);
canvas.addEventListener('touchend', mend1, false);
if(tinity > shifty ){ mot = 3; }
else{ mot = 4; }
}
}
function mmove1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize/2;
var tinity = evt.clientY - rect.top - shh - size/2;
drag(tinitx, tinity);
}
function mtouch1(evt){
evt.preventDefault();
var rect = canvas .getBoundingClientRect();
var tinitx = evt.touches[0].clientX - rect.left - shw - hsize/2;
var tinity = evt.touches[0].clientY - rect.top - shh - size/2;
drag(tinitx, tinity);
}
function drag(tinitx, tinity){
if(mot == 0){
shiftx = tinitx;
shifty = tinity;
draw_all();
drawdot(context, tinitx+hsize/2, tinity+size/2, 5, "Blue");
}
if(mot == 1){
if( tinitx-shiftx > 0){
theta = Math.atan( (tinity-shifty)/ (tinitx-shiftx) );
} else if (tinitx-shiftx < 0){
theta = Math.PI+Math.atan( (tinity-shifty)/ (tinitx-shiftx) );
}
draw_all();
drawdot(context, tinitx+hsize/2, tinity+size/2, 5, "Blue");
}
if(mot == 2){
if( tinitx-shiftx > 0){
theta = Math.PI + Math.atan( (tinity-shifty)/ (tinitx-shiftx) );
} else if (tinitx-shiftx < 0){
theta = Math.atan( (tinity-shifty)/ (tinitx-shiftx) );
}
draw_all();
drawdot(context, tinitx+hsize/2, tinity+size/2, 5, "Blue");
}
if(mot == 3){
if( tinity-shifty > 0){
theta = - Math.atan( (tinitx-shiftx)/ (tinity-shifty) );
} else if (tinity-shifty < 0){
theta = -Math.PI -Math.atan( (tinitx-shiftx)/ (tinity-shifty) );
}
draw_all();
drawdot(context, tinitx+hsize/2, tinity+size/2, 5, "Blue");
}
if(mot == 4){
if( tinity-shifty > 0){
theta = -Math.PI-Math.atan( (tinitx-shiftx)/ (tinity-shifty) );
} else if (tinity-shifty < 0){
theta = - Math.atan( (tinitx-shiftx)/ (tinity-shifty) );
}
draw_all();
drawdot(context, tinitx+hsize/2, tinity+size/2, 5, "Blue");
}
}
function mup1(evt){
draw_all();
remove_event_listeners();
}
function mend1(evt){
draw_all();
remove_event_listeners();
}
function init_diff(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
if (!context.setLineDash) {
context.setLineDash = function () {}
}
context.translate(shw, shh);
canvas3 = document.getElementById("canvas3");
context3 = canvas3.getContext("2d");
if (!context3.setLineDash) {
context3.setLineDash = function () {}
}
context3.translate(shw, shh);
add_event_listeners();
draw_all();
}
</script>
</head>
<body onLoad="init_diff();">
</BR>
<div id="matrixContainer" style="width: 501px">
<div id="matrix" style="float: left;">
<canvas id="canvas" width="501" height="501"></canvas>
</div>
<div id="matrix" style="float: left;">
<canvas id="canvas3" width="501" height="251"></canvas>
</div>
</div>
<div id="textContainer" style="width: 501px">
The parabola $Y = X^2$. Click and drag the origin to translate and click and drag the axes to rotate.
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-80134336115071512712015-12-23T01:19:00.003-08:002015-12-23T01:22:02.815-08:00Cubic Integration<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Integrate cubic</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
ctx.fillStyle="black";
}
function slider(_min, _max, _inc, _val, _left, _right, _yp, _sliderw){
this.minv= _min,
this.maxv= _max;
this.inc= _inc;
this.val= _val;
this.range = (_max - _min)
this.left = _left;
this.right = _right;
this.width = (_right - _left);
this.get_sp = function(){ return this.width*(this.val - this.minv)/this.range }
this.sp = this.get_sp();
this.yp = _yp;
this.sliderw = _sliderw;
this.update = function(tinitx){
this.val = Math.min( this.maxv,Math.max( this.minv + this.range*(tinitx - this.left)/this.width, this.minv ) );
}
this.draw = function(ctx){
this.sp = this.get_sp();
ctx.beginPath();
ctx.moveTo(this.left,this.yp);
ctx.lineTo(this.right,this.yp);
ctx.stroke();
ctx.fillRect(this.left + this.sp-this.sliderw/2, this.yp-this.sliderw,this.sliderw,2*this.sliderw);
}
}
var canvas;
var context;
var canvas2;
var context2;
var canvas3;
var context3;
var size = 500;
var hsize = size/2;
var tot = 750;
var shw = 1;
var shh = 1;
var a = 1;
var b = 0;
var c = 0;
var d = 0
var sliderw=10;
var myslidera = new slider(-1,1,0.01,a, size/4, 3*size/4, 25 ,sliderw);
var mysliderb = new slider(-1,1,0.01,b, size/4, 3*size/4, 50 ,sliderw);
var mysliderc = new slider(-1,1,0.01,c, size/4, 3*size/4, 75 ,sliderw);
var mysliderd = new slider(-1,1,0.01,d, size/4, 3*size/4, 100 ,sliderw);
var start = 0;
var end = size/4;
var num_dots = 0;
function plot_function(x){
return -(a*x*x*x + b*x*x + c*x+d);
}
function dplot_function(x){
return -(a*x*x*x*x/4 + b*x*x*x/3 + c*x*x/2+d*x);
}
var fnx = new Array(101);
var fn = new Array(101);
var dfn = new Array(101);
var show = new Array(101);
function generate_cubic(left, right){
var inc = (right-left)/100;
var x = left;
for(var i=0; i<=100; i++){
fnx[i] = x*hsize/2;
fn[i] = plot_function(x)*hsize/2;
dfn[i] = dplot_function(x)*hsize/2;
show[i] = false;
x += inc;
}
}
function update_data(which_slider, tinitx){
switch(which_slider){
case 0:
myslidera.update(tinitx);
a = myslidera.val;
generate_cubic(-2, 2);
break;
case 1:
mysliderb.update(tinitx);
b = mysliderb.val;
generate_cubic(-2, 2);
break;
case 2:
mysliderc.update(tinitx);
c = mysliderc.val;
generate_cubic(-2, 2);
break;
case 3:
mysliderd.update(tinitx);
d = mysliderd.val;
generate_cubic(-2, 2);
break;
default:
return 1;
}
draw_axis();
return 0;
}
function draw_cubic(){
context.translate(hsize, hsize/2);
if(num_dots>=2){
var l = start;
var r = end;
if( end < start ){
l = end; r = start;
}
for(var i=0; i<100; i++){
if( fnx[i] >= l && fnx[i] < r ){
context.beginPath();
context.strokeStyle="LightSkyBlue"
context.fillStyle="LightSkyBlue"
context.moveTo(fnx[i],0);
context.lineTo(fnx[i],fn[i]);
context.lineTo(fnx[i+1],fn[i+1]);
context.lineTo(fnx[i+1],0);
context.closePath();
context.fill();
}
}
context.strokeStyle="Black"
}
context.beginPath();
context.moveTo(fnx[0],fn[0]);
for(var i=1; i<=100; i++){
context.lineTo(fnx[i],fn[i]);
}
context.stroke();
if(num_dots>=1){ drawdot(context, start, 0, 3, "black"); }
if(num_dots>=2){ drawdot(context, end, 0, 3, "black"); }
context.translate(-hsize, -hsize/2);
}
function draw_linear(){
context2.translate(hsize, hsize/2);
context2.beginPath();
context2.moveTo(fnx[0],dfn[0]);
for(var i=1; i<=100; i++){
if(show[i]){
drawdot( context2, fnx[i],dfn[i], 3, "Tomato" );
}
}
context2.stroke();
context2.translate(-hsize, -hsize/2);
}
function draw_axis(){
context.clearRect(-shw,-shh,tot,tot);
context.strokeRect(0,0,size,hsize);
context.setLineDash([5])
context.beginPath();
context.moveTo(hsize,0);
context.lineTo(hsize,size);
context.stroke();
context.beginPath();
context.moveTo(0,size/4);
context.lineTo(size,size/4);
context.stroke();
context.setLineDash([]);
draw_cubic();
context2.clearRect(-shw,-shh,tot,tot);
context2.strokeRect(0,0,size,hsize);
context2.setLineDash([5])
context2.beginPath();
context2.moveTo(hsize,0);
context2.lineTo(hsize,hsize);
context2.stroke();
context2.beginPath();
context2.moveTo(0,size/4);
context2.lineTo(size,size/4);
context2.stroke();
context2.setLineDash([]);
draw_linear()
context3.clearRect(-shw,-shh,tot,tot);
myslidera.draw(context3);
mysliderb.draw(context3);
mysliderc.draw(context3);
mysliderd.draw(context3);
context3.fillStyle="black";
context3.font="15px Verdana";
var fs = a.toFixed(2).toString() + "x";
context3.fillText(fs ,size/4, 135, 40);
context3.font="12px Verdana";
context3.fillText("3" ,size/4+40, 125, 10);
context3.font="15px Verdana";
fs = ""
if( b < 0 ){
fs += " - " + (-b).toFixed(2).toString();
} else {
fs += " + " + b.toFixed(2).toString()
}
fs += "x"
context3.fillText(fs ,size/4+50, 135, 60);
context3.font="12px Verdana";
context3.fillText("2" ,size/4+110, 125, 10);
context3.font="15px Verdana";
fs = "";
if( c < 0 ){
fs += " - " + (-c).toFixed(2).toString();
} else {
fs += " + " + c.toFixed(2).toString()
}
fs += "x"
if( d < 0 ){
fs += " - " + (-d).toFixed(2).toString();
} else {
fs += " + " + d.toFixed(2).toString()
}
context3.fillText(fs ,size/4+120, 135, 200);
}
function remove_event_listeners(){
canvas.removeEventListener('mousemove', mmove1);
canvas.removeEventListener('mouseup', mup1);
}
function remove_event_listeners3(){
canvas3.removeEventListener('mousemove', mmove3);
canvas3.removeEventListener('mouseup', mup3);
}
function add_event_listeners(){
canvas3.addEventListener('mousedown', mdown3, false);
canvas.addEventListener('mousedown', mdown1, false);
}
var qinc = 4/100;
function mdown1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize;
var tinity = evt.clientY - rect.top - shh - hsize/2;
var id = Math.max( 0, Math.min( Math.floor( 100*((2*tinitx/hsize)+2)/4 ) , 100) );
//console.log(tinitx, tinity, fnx[id], fn[id], Math.abs( fn[id] - tinity ))
if( Math.abs( tinity ) < 8 ){
num_dots = (num_dots+1)%3;
if( num_dots == 0){
for(var i=0; i<=100; i++){
show[i] = false;
}
}
if( num_dots == 1){ start = fnx[id]; }
if( num_dots == 2){
end = fnx[id];
show[id] = true;
dfn[id] = (dplot_function(end*2/hsize) - dplot_function(start*2/hsize)) * hsize/2;
canvas.addEventListener('mousemove', mmove1, false);
canvas.addEventListener('mouseup', mup1, false);
}
draw_axis();
}
}
function mmove1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize;
var tinity = evt.clientY - rect.top - shh - hsize/2;
var id = Math.max( 0, Math.min( Math.floor( 100*((2*tinitx/hsize)+2)/4 ) , 100) );
if( num_dots == 1){ start = fnx[id]; }
if( num_dots == 2){ end = fnx[id]; }
show[id] = true;
dfn[id] = (dplot_function(end*2/hsize) - dplot_function(start*2/hsize)) * hsize/2;
draw_axis();
}
function mup1(evt){
remove_event_listeners();
}
var which_slider;
function mdown3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
//check for slider position
if( ( tinitx > myslidera.left ) && ( tinitx < myslidera.right ) && Math.abs( tinity - myslidera.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 0;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderb.left ) && ( tinitx < mysliderb.right ) && Math.abs( tinity - mysliderb.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 1;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderc.left ) && ( tinitx < mysliderc.right ) && Math.abs( tinity - mysliderc.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 2;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderd.left ) && ( tinitx < mysliderd.right ) && Math.abs( tinity - mysliderd.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 3;
update_data(which_slider, tinitx);
return 0
}
}
function mmove3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
update_data(which_slider, tinitx);
}
function mup3(evt){
remove_event_listeners3();
}
function init_diff(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
if (!context.setLineDash) {
context.setLineDash = function () {}
}
context.translate(shw, shh);
canvas2 = document.getElementById("canvas2");
context2 = canvas2.getContext("2d");
if (!context2.setLineDash) {
context2.setLineDash = function () {}
}
context2.translate(shw, shh);
canvas3 = document.getElementById("canvas3");
context3 = canvas3.getContext("2d");
if (!context3.setLineDash) {
context3.setLineDash = function () {}
}
context3.translate(shw, shh);
generate_cubic(-2, 2);
draw_axis();
add_event_listeners();
}
</script>
</head>
<body onLoad="init_diff();">
</BR>
<div id="matrixContainer" style="width: 501px">
<div id="matrix" style="float: left;">
<canvas id="canvas" width="501" height="251"></canvas>
</div>
<div id="matrix" style="float: left;">
<canvas id="canvas2" width="501" height="251"></canvas>
</div>
<div id="matrix" style="float: left;">
<canvas id="canvas3" width="501" height="251"></canvas>
</div>
</div>
<div id="textContainer" style="width: 501px">
Click on the x-axis to set the left limit, then click and drag to evaluate the integral. Click again to reset.
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com1tag:blogger.com,1999:blog-337859244861341472.post-61724561420978196092015-10-11T05:15:00.003-07:002015-10-11T05:15:46.073-07:00Verhulst Diagram<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Differentiate cubic</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
ctx.fillStyle="black";
}
function slider(_min, _max, _inc, _val, _left, _right, _yp, _sliderw){
this.minv= _min,
this.maxv= _max;
this.inc= _inc;
this.val= _val;
this.range = (_max - _min)
this.left = _left;
this.right = _right;
this.width = (_right - _left);
this.get_sp = function(){ return this.width*(this.val - this.minv)/this.range }
this.sp = this.get_sp();
this.yp = _yp;
this.sliderw = _sliderw;
this.update = function(tinitx){
this.val = Math.min( this.maxv,Math.max( this.minv + this.range*(tinitx - this.left)/this.width, this.minv ) );
}
this.draw = function(ctx){
this.sp = this.get_sp();
ctx.beginPath();
ctx.moveTo(this.left,this.yp);
ctx.lineTo(this.right,this.yp);
ctx.stroke();
ctx.fillRect(this.left + this.sp-this.sliderw/2, this.yp-this.sliderw,this.sliderw,2*this.sliderw);
}
}
var runAnimation = {value: false};
var canvas;
var context;
var canvas2;
var context2;
var canvas3;
var context3;
var size = 500;
var hsize = size/2;
var tot = 750;
var shw = 1;
var shh = 1;
var show_guess = false;
var init_guess = 0;
var init_guessy = 0;
var old_guess = 0;
var nguess = 0;
var guessx = 0;
var guessy = 0;
var edge = 50;
var gl = -4;
var gr = 4;
var range = gr - gl;
var a = 0;
var b = -4;
var c = 4;
var d = 0
var sliderw=10;
var myslidera = new slider(-4,4,0.01,a, size/4, 3*size/4, 25 ,sliderw);
var mysliderb = new slider(-4,4,0.01,b, size/4, 3*size/4, 50 ,sliderw);
var mysliderc = new slider(-4,4,0.01,c, size/4, 3*size/4, 75 ,sliderw);
var mysliderd = new slider(-4,4,0.01,d, size/4, 3*size/4, 100 ,sliderw);
function plot_function(x){
return -(a*x*x*x + b*x*x + c*x+d);
}
function dplot_function(x){
return -(3*a*x*x + 2*b*x + c);
}
var nump = 1600;
var fnx = new Array(nump+1);
var fn = new Array(nump+1);
var dfn = new Array(nump+1);
var show = new Array(nump+1);
function generate_cubic(left, right){
var inc = (right-left)/nump;
var x = left;
for(var i=0; i<=nump; i++){
fnx[i] = x*hsize/2;
fn[i] = plot_function(x)*hsize/2;
dfn[i] = dplot_function(x)*hsize/2;
show[i] = false;
x += inc;
}
}
function update_data(which_slider, tinitx){
switch(which_slider){
case 0:
myslidera.update(tinitx);
a = myslidera.val;
generate_cubic(gl, gr);
break;
case 1:
mysliderb.update(tinitx);
b = mysliderb.val;
generate_cubic(gl, gr);
break;
case 2:
mysliderc.update(tinitx);
c = mysliderc.val;
generate_cubic(gl, gr);
break;
case 3:
mysliderd.update(tinitx);
d = mysliderd.val;
generate_cubic(gl, gr);
break;
default:
return 1;
}
draw_axis();
return 0;
}
function draw_diag(){
context.translate(hsize, hsize);
context.beginPath();
context.moveTo(-hsize,hsize);
context.lineTo(hsize,-hsize);
context.stroke();
context.translate(-hsize, -hsize);
}
function update_cobweby(x){
context.translate(hsize, hsize);
context.setLineDash([1])
context.beginPath();
context.moveTo(x,guessy);
guessy = plot_function(x*2/hsize)*hsize/2;
context.lineTo(x,guessy);
context.strokeStyle="red"
context.stroke();
context.strokeStyle="black"
context.setLineDash([]);
context.translate(-hsize, -hsize);
}
function update_cobwebx(){
context.translate(hsize, hsize);
context.setLineDash([1])
context.beginPath();
context.moveTo(guessx,guessy);
context.lineTo(-guessy,guessy);
context.strokeStyle="red"
context.stroke();
context.strokeStyle="black"
context.setLineDash([]);
old_guess = guessx;
guessx = -guessy;
context.translate(-hsize, -hsize);
}
function draw_cobweb(level){
guessx = init_guess;
guessy = 0;
for(var i=0; i<level; i++){
if(i%2==0){ update_cobweby(guessx); }
else{ update_cobwebx(); }
}
}
function draw_cubic(){
context.translate(hsize, hsize);
context.beginPath();
context.moveTo(fnx[0],fn[0]);
for(var i=1; i<=nump; i++){
context.lineTo(fnx[i],fn[i]);
}
context.stroke();
/*for(var i=1; i<=100; i++){
if(show[i]){
drawdot(context, fnx[i], fn[i], 3, "red");
}
}*/
context.translate(-hsize, -hsize);
}
function draw_tangent(m, x, y){
context.translate(hsize, hsize);
drawdot(context, x,y, 3, "red");
context.beginPath();
var t0 = y + m * (fnx[0] - x) * 2 / hsize;
context.moveTo(fnx[0], t0);
var t1 = y + m * (fnx[nump] - x) * 2 / hsize;
context.lineTo(fnx[nump], t1);
context.strokeStyle="red"
context.stroke();
context.strokeStyle="black"
var is = (x -y/(m*2/hsize));
context.setLineDash([1])
context.beginPath();
context.moveTo(is,0);
var nf = plot_function(is*2/hsize)*hsize/2;
context.lineTo( is , nf );
context.stroke();
context.setLineDash([])
drawdot(context, is,0, 3, "blue");
drawdot(context, is,nf, 3, "blue");
context.translate(-hsize, -hsize);
}
function draw_axis(){
context.clearRect(-shw,-shh,tot,tot);
context.strokeRect(0,0,size,size);
//context.translate(-hsize+edge,hsize-edge);
context.setLineDash([5])
context.beginPath();
context.moveTo(hsize,-hsize);
context.lineTo(hsize,size);
context.stroke();
context.beginPath();
context.moveTo(0,hsize);
context.lineTo(2*size,hsize);
context.stroke();
context.setLineDash([]);
draw_cubic();
draw_diag()
//context.translate(hsize-edge,-hsize+edge);
context3.clearRect(-shw,-shh,tot,tot);
myslidera.draw(context3);
mysliderb.draw(context3);
mysliderc.draw(context3);
mysliderd.draw(context3);
context3.fillStyle="black";
context3.font="15px Verdana";
var fs = a.toFixed(2).toString() + "x";
context3.fillText(fs ,size/4, 135, 40);
context3.font="12px Verdana";
context3.fillText("3" ,size/4+40, 125, 10);
context3.font="15px Verdana";
fs = ""
if( b < 0 ){
fs += " - " + (-b).toFixed(2).toString();
} else {
fs += " + " + b.toFixed(2).toString()
}
fs += "x"
context3.fillText(fs ,size/4+50, 135, 60);
context3.font="12px Verdana";
context3.fillText("2" ,size/4+110, 125, 10);
context3.font="15px Verdana";
fs = "";
if( c < 0 ){
fs += " - " + (-c).toFixed(2).toString();
} else {
fs += " + " + c.toFixed(2).toString()
}
fs += "x"
if( d < 0 ){
fs += " - " + (-d).toFixed(2).toString();
} else {
fs += " + " + d.toFixed(2).toString()
}
context3.fillText(fs ,size/4+120, 135, 200);
}
function animate_grid(runAnimation) {
if(runAnimation.value) {
draw_axis( );
draw_cobweb(nguess);
++nguess;
}
setTimeout(function() {
requestAnimFrame(function() {
animate_grid( runAnimation, canvas, context);
});
}, 300);
}
function remove_event_listeners(){
//canvas.removeEventListener('mousemove', mmove1);
//canvas.removeEventListener('mouseup', mup1);
}
function remove_event_listeners3(){
canvas3.removeEventListener('mousemove', mmove3);
canvas3.removeEventListener('mouseup', mup3);
}
function add_event_listeners(){
canvas3.addEventListener('mousedown', mdown3, false);
canvas.addEventListener('mousedown', mdown1, false);
}
var qinc = range/nump;
function mdown1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize;
var tinity = evt.clientY - rect.top - shh - hsize;
var id = Math.max( 0, Math.min( Math.floor( nump*((2*tinitx/hsize)+range/2)/range ) , nump) );
if( Math.abs( 0 - tinity ) < 8 ){
runAnimation.value = false;
draw_axis();
show_guess = true;
init_guess = fnx[id];
guessy = 0;
nguess = 0;
runAnimation.value = true;
}
}
function mmove1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize;
var tinity = evt.clientY - rect.top - shh - hsize;
var id = Math.max( 0, Math.min( Math.floor( nump*((2*tinitx/hsize)+2)/4 ) , nump) );
show[id] = true;
//draw_axis();
//draw_tangent( dfn[id], fnx[id], fn[id]);
}
function mup1(evt){
//remove_event_listeners();
}
var which_slider;
function mdown3(evt){
runAnimation.value = false;
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
//check for slider position
if( ( tinitx > myslidera.left ) && ( tinitx < myslidera.right ) && Math.abs( tinity - myslidera.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 0;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderb.left ) && ( tinitx < mysliderb.right ) && Math.abs( tinity - mysliderb.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 1;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderc.left ) && ( tinitx < mysliderc.right ) && Math.abs( tinity - mysliderc.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 2;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderd.left ) && ( tinitx < mysliderd.right ) && Math.abs( tinity - mysliderd.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 3;
update_data(which_slider, tinitx);
return 0
}
}
function mmove3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
update_data(which_slider, tinitx);
}
function mup3(evt){
remove_event_listeners3();
}
function init_diff(){
runAnimation.value = false;
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
if (!context.setLineDash) {
context.setLineDash = function () {}
}
context.translate(shw, shh);
canvas3 = document.getElementById("canvas3");
context3 = canvas3.getContext("2d");
if (!context3.setLineDash) {
context3.setLineDash = function () {}
}
context3.translate(shw, shh);
generate_cubic(gl, gr);
draw_axis();
add_event_listeners();
animate_grid( runAnimation );
}
</script>
</head>
<body onLoad="init_diff();">
</BR>
<div id="matrixContainer" style="width: 501px">
<div id="matrix" style="float: left;">
<canvas id="canvas" width="501" height="501"></canvas>
</div>
<div id="matrix" style="float: left;">
<canvas id="canvas3" width="501" height="251"></canvas>
</div>
</div>
<div id="textContainer" style="width: 501px">
Click somewhere on the x-axis to start the iteration.
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-29498077949908748032015-10-08T13:36:00.000-07:002015-10-10T01:34:57.613-07:00Regula Falsi<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Differentiate cubic</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
ctx.fillStyle="black";
}
function slider(_min, _max, _inc, _val, _left, _right, _yp, _sliderw){
this.minv= _min,
this.maxv= _max;
this.inc= _inc;
this.val= _val;
this.range = (_max - _min)
this.left = _left;
this.right = _right;
this.width = (_right - _left);
this.get_sp = function(){ return this.width*(this.val - this.minv)/this.range }
this.sp = this.get_sp();
this.yp = _yp;
this.sliderw = _sliderw;
this.update = function(tinitx){
this.val = Math.min( this.maxv,Math.max( this.minv + this.range*(tinitx - this.left)/this.width, this.minv ) );
}
this.draw = function(ctx){
this.sp = this.get_sp();
ctx.beginPath();
ctx.moveTo(this.left,this.yp);
ctx.lineTo(this.right,this.yp);
ctx.stroke();
ctx.fillRect(this.left + this.sp-this.sliderw/2, this.yp-this.sliderw,this.sliderw,2*this.sliderw);
}
}
var canvas;
var context;
var canvas2;
var context2;
var canvas3;
var context3;
var size = 500;
var hsize = size/2;
var tot = 750;
var shw = 1;
var shh = 1;
var show_guess = false;
var guessx= new Array(2);
var guessy= new Array(2);
var nguess=0;
var a = 0;
var b = 1;
var c = 0;
var d = -0.5;
var sliderw=10;
var myslidera = new slider(-1,1,0.01,a, size/4, 3*size/4, 25 ,sliderw);
var mysliderb = new slider(-1,1,0.01,b, size/4, 3*size/4, 50 ,sliderw);
var mysliderc = new slider(-1,1,0.01,c, size/4, 3*size/4, 75 ,sliderw);
var mysliderd = new slider(-1,1,0.01,d, size/4, 3*size/4, 100 ,sliderw);
function plot_function(x){
return -(a*x*x*x + b*x*x + c*x+d);
}
function dplot_function(x){
return -(3*a*x*x + 2*b*x + c);
}
var nump = 400;
var fnx = new Array(nump+1);
var fn = new Array(nump+1);
var dfn = new Array(nump+1);
var show = new Array(nump+1);
function generate_cubic(left, right){
var inc = (right-left)/nump;
var x = left;
for(var i=0; i<=nump; i++){
fnx[i] = x*hsize/2;
fn[i] = plot_function(x)*hsize/2;
dfn[i] = dplot_function(x)*hsize/2;
show[i] = false;
x += inc;
}
}
function update_data(which_slider, tinitx){
switch(which_slider){
case 0:
myslidera.update(tinitx);
a = myslidera.val;
generate_cubic(-2, 2);
break;
case 1:
mysliderb.update(tinitx);
b = mysliderb.val;
generate_cubic(-2, 2);
break;
case 2:
mysliderc.update(tinitx);
c = mysliderc.val;
generate_cubic(-2, 2);
break;
case 3:
mysliderd.update(tinitx);
d = mysliderd.val;
generate_cubic(-2, 2);
break;
default:
return 1;
}
draw_axis();
return 0;
}
function draw_cubic(){
context.translate(hsize, hsize);
context.beginPath();
context.moveTo(fnx[0],fn[0]);
for(var i=1; i<=nump; i++){
context.lineTo(fnx[i],fn[i]);
}
context.stroke();
/*for(var i=1; i<=100; i++){
if(show[i]){
drawdot(context, fnx[i], fn[i], 3, "red");
}
}*/
context.translate(-hsize, -hsize);
}
function draw_tangent(m, x, y){
context.translate(hsize, hsize);
drawdot(context, x,y, 3, "red");
context.beginPath();
var t0 = y + m * (fnx[0] - x) * 2 / hsize;
context.moveTo(fnx[0], t0);
var t1 = y + m * (fnx[nump] - x) * 2 / hsize;
context.lineTo(fnx[nump], t1);
context.strokeStyle="red"
context.stroke();
context.strokeStyle="black"
var is = (x -y/(m*2/hsize));
context.setLineDash([1])
context.beginPath();
context.moveTo(is,0);
var nf = plot_function(is*2/hsize)*hsize/2;
context.lineTo( is , nf );
context.stroke();
context.setLineDash([])
drawdot(context, is,0, 3, "blue");
drawdot(context, is,nf, 3, "blue");
context.translate(-hsize, -hsize);
}
function draw_axis(){
context.clearRect(-shw,-shh,tot,tot);
context.strokeRect(0,0,size,size);
context.setLineDash([5])
context.beginPath();
context.moveTo(hsize,0);
context.lineTo(hsize,size);
context.stroke();
context.beginPath();
context.moveTo(0,hsize);
context.lineTo(size,hsize);
context.stroke();
context.setLineDash([]);
draw_cubic();
context3.clearRect(-shw,-shh,tot,tot);
myslidera.draw(context3);
mysliderb.draw(context3);
mysliderc.draw(context3);
mysliderd.draw(context3);
context3.fillStyle="black";
context3.font="15px Verdana";
var fs = a.toFixed(2).toString() + "x";
context3.fillText(fs ,size/4, 135, 40);
context3.font="12px Verdana";
context3.fillText("3" ,size/4+40, 125, 10);
context3.font="15px Verdana";
fs = ""
if( b < 0 ){
fs += " - " + (-b).toFixed(2).toString();
} else {
fs += " + " + b.toFixed(2).toString()
}
fs += "x"
context3.fillText(fs ,size/4+50, 135, 60);
context3.font="12px Verdana";
context3.fillText("2" ,size/4+110, 125, 10);
context3.font="15px Verdana";
fs = "";
if( c < 0 ){
fs += " - " + (-c).toFixed(2).toString();
} else {
fs += " + " + c.toFixed(2).toString()
}
fs += "x"
if( d < 0 ){
fs += " - " + (-d).toFixed(2).toString();
} else {
fs += " + " + d.toFixed(2).toString()
}
context3.fillText(fs ,size/4+120, 135, 200);
}
//y - y1 = (y2-y1/x2-x1)(x-x1)
// (-y1/m) + x1 = x;
function draw_line(){
if( (guessy[0] < 0 && guessy[1] > 0) ||
(guessy[0] > 0 && guessy[1] < 0)
)
{
context.translate(hsize, hsize);
context.setLineDash([1])
context.beginPath();
context.moveTo(guessx[0],guessy[0]);
context.lineTo( guessx[1],guessy[1] );
context.stroke();
context.setLineDash([])
drawdot(context, guessx[0], guessy[0], 3, "red");
drawdot(context, guessx[1], guessy[1], 3, "red");
var xs = guessx[0] - guessy[0] * ( guessx[1] - guessx[0] ) / ( guessy[1] - guessy[0] );
drawdot(context, xs, 0, 3, "blue");
var nf = plot_function(xs*2/hsize)*hsize/2;
context.setLineDash([1])
context.beginPath();
context.moveTo(xs, 0);
context.lineTo( xs, nf );
context.stroke();
context.setLineDash([])
drawdot(context, xs, nf, 3, "blue");
context.translate(-hsize, -hsize);
} else {
draw_axis();
}
}
function remove_event_listeners(){
canvas.removeEventListener('mousemove', mmove1);
canvas.removeEventListener('mouseup', mup1);
}
function remove_event_listeners3(){
canvas3.removeEventListener('mousemove', mmove3);
canvas3.removeEventListener('mouseup', mup3);
}
function add_event_listeners(){
canvas3.addEventListener('mousedown', mdown3, false);
canvas.addEventListener('mousedown', mdown1, false);
}
var qinc = 4/nump;
function mdown1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize;
var tinity = evt.clientY - rect.top - shh - hsize;
var id = Math.max( 0, Math.min( Math.floor( nump*((2*tinitx/hsize)+2)/4 ) , nump) );
//console.log(tinitx, tinity, fnx[id], fn[id], Math.abs( fn[id] - tinity ))
if( Math.abs( fn[id] - tinity ) < 8 ){
show[id] = true;
//if(nguess==0) draw_axis();
show_guess = true;
guessx[nguess] = fnx[id];
guessy[nguess] = fn[id];
console.log(nguess);
drawdot(context, guessx[nguess] + hsize, guessy[nguess] + hsize, 3, "red");
canvas.addEventListener('mouseup', mup1, false);
nguess++;
}
}
function mmove1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize;
var tinity = evt.clientY - rect.top - shh - hsize;
var id = Math.max( 0, Math.min( Math.floor( nump*((2*tinitx/hsize)+2)/4 ) , nump) );
show[id] = true;
draw_axis();
draw_tangent( dfn[id], fnx[id], fn[id]);
}
function mup1(evt){
if(nguess >= 2){
draw_line();
nguess=0;
}
}
var which_slider;
function mdown3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
//check for slider position
if( ( tinitx > myslidera.left ) && ( tinitx < myslidera.right ) && Math.abs( tinity - myslidera.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 0;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderb.left ) && ( tinitx < mysliderb.right ) && Math.abs( tinity - mysliderb.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 1;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderc.left ) && ( tinitx < mysliderc.right ) && Math.abs( tinity - mysliderc.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 2;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderd.left ) && ( tinitx < mysliderd.right ) && Math.abs( tinity - mysliderd.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 3;
update_data(which_slider, tinitx);
return 0
}
}
function mmove3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
update_data(which_slider, tinitx);
}
function mup3(evt){
remove_event_listeners3();
}
function init_diff(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
if (!context.setLineDash) {
context.setLineDash = function () {}
}
context.translate(shw, shh);
canvas3 = document.getElementById("canvas3");
context3 = canvas3.getContext("2d");
if (!context3.setLineDash) {
context3.setLineDash = function () {}
}
context3.translate(shw, shh);
generate_cubic(-2, 2);
draw_axis();
add_event_listeners();
}
</script>
</head>
<body onLoad="init_diff();">
</BR>
<div id="matrixContainer" style="width: 501px">
<div id="matrix" style="float: left;">
<canvas id="canvas" width="501" height="501"></canvas>
</div>
<div id="matrix" style="float: left;">
<canvas id="canvas3" width="501" height="251"></canvas>
</div>
</div>
<div id="textContainer" style="width: 501px">
Click on the graph at two points to construct the linear approximation to the root. The two points must have opposite sign or you'll have to start again!
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-53210461585422734232015-09-07T12:59:00.001-07:002015-09-07T12:59:47.660-07:00Newton–Raphson method<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Differentiate cubic</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
ctx.fillStyle="black";
}
function slider(_min, _max, _inc, _val, _left, _right, _yp, _sliderw){
this.minv= _min,
this.maxv= _max;
this.inc= _inc;
this.val= _val;
this.range = (_max - _min)
this.left = _left;
this.right = _right;
this.width = (_right - _left);
this.get_sp = function(){ return this.width*(this.val - this.minv)/this.range }
this.sp = this.get_sp();
this.yp = _yp;
this.sliderw = _sliderw;
this.update = function(tinitx){
this.val = Math.min( this.maxv,Math.max( this.minv + this.range*(tinitx - this.left)/this.width, this.minv ) );
}
this.draw = function(ctx){
this.sp = this.get_sp();
ctx.beginPath();
ctx.moveTo(this.left,this.yp);
ctx.lineTo(this.right,this.yp);
ctx.stroke();
ctx.fillRect(this.left + this.sp-this.sliderw/2, this.yp-this.sliderw,this.sliderw,2*this.sliderw);
}
}
var canvas;
var context;
var canvas2;
var context2;
var canvas3;
var context3;
var size = 500;
var hsize = size/2;
var tot = 750;
var shw = 1;
var shh = 1;
var show_guess = false;
var guessx = 0;
var guessy = 0;
var a = 1;
var b = 0;
var c = 0;
var d = 0
var sliderw=10;
var myslidera = new slider(-1,1,0.01,a, size/4, 3*size/4, 25 ,sliderw);
var mysliderb = new slider(-1,1,0.01,b, size/4, 3*size/4, 50 ,sliderw);
var mysliderc = new slider(-1,1,0.01,c, size/4, 3*size/4, 75 ,sliderw);
var mysliderd = new slider(-1,1,0.01,d, size/4, 3*size/4, 100 ,sliderw);
function plot_function(x){
return -(a*x*x*x + b*x*x + c*x+d);
}
function dplot_function(x){
return -(3*a*x*x + 2*b*x + c);
}
var nump = 400;
var fnx = new Array(nump+1);
var fn = new Array(nump+1);
var dfn = new Array(nump+1);
var show = new Array(nump+1);
function generate_cubic(left, right){
var inc = (right-left)/nump;
var x = left;
for(var i=0; i<=nump; i++){
fnx[i] = x*hsize/2;
fn[i] = plot_function(x)*hsize/2;
dfn[i] = dplot_function(x)*hsize/2;
show[i] = false;
x += inc;
}
}
function update_data(which_slider, tinitx){
switch(which_slider){
case 0:
myslidera.update(tinitx);
a = myslidera.val;
generate_cubic(-2, 2);
break;
case 1:
mysliderb.update(tinitx);
b = mysliderb.val;
generate_cubic(-2, 2);
break;
case 2:
mysliderc.update(tinitx);
c = mysliderc.val;
generate_cubic(-2, 2);
break;
case 3:
mysliderd.update(tinitx);
d = mysliderd.val;
generate_cubic(-2, 2);
break;
default:
return 1;
}
draw_axis();
return 0;
}
function draw_cubic(){
context.translate(hsize, hsize);
context.beginPath();
context.moveTo(fnx[0],fn[0]);
for(var i=1; i<=nump; i++){
context.lineTo(fnx[i],fn[i]);
}
context.stroke();
/*for(var i=1; i<=100; i++){
if(show[i]){
drawdot(context, fnx[i], fn[i], 3, "red");
}
}*/
context.translate(-hsize, -hsize);
}
function draw_tangent(m, x, y){
context.translate(hsize, hsize);
drawdot(context, x,y, 3, "red");
context.beginPath();
var t0 = y + m * (fnx[0] - x) * 2 / hsize;
context.moveTo(fnx[0], t0);
var t1 = y + m * (fnx[nump] - x) * 2 / hsize;
context.lineTo(fnx[nump], t1);
context.strokeStyle="red"
context.stroke();
context.strokeStyle="black"
var is = (x -y/(m*2/hsize));
context.setLineDash([1])
context.beginPath();
context.moveTo(is,0);
var nf = plot_function(is*2/hsize)*hsize/2;
context.lineTo( is , nf );
context.stroke();
context.setLineDash([])
drawdot(context, is,0, 3, "blue");
drawdot(context, is,nf, 3, "blue");
context.translate(-hsize, -hsize);
}
function draw_axis(){
context.clearRect(-shw,-shh,tot,tot);
context.strokeRect(0,0,size,size);
context.setLineDash([5])
context.beginPath();
context.moveTo(hsize,0);
context.lineTo(hsize,size);
context.stroke();
context.beginPath();
context.moveTo(0,hsize);
context.lineTo(size,hsize);
context.stroke();
context.setLineDash([]);
draw_cubic();
context3.clearRect(-shw,-shh,tot,tot);
myslidera.draw(context3);
mysliderb.draw(context3);
mysliderc.draw(context3);
mysliderd.draw(context3);
context3.fillStyle="black";
context3.font="15px Verdana";
var fs = a.toFixed(2).toString() + "x";
context3.fillText(fs ,size/4, 135, 40);
context3.font="12px Verdana";
context3.fillText("3" ,size/4+40, 125, 10);
context3.font="15px Verdana";
fs = ""
if( b < 0 ){
fs += " - " + (-b).toFixed(2).toString();
} else {
fs += " + " + b.toFixed(2).toString()
}
fs += "x"
context3.fillText(fs ,size/4+50, 135, 60);
context3.font="12px Verdana";
context3.fillText("2" ,size/4+110, 125, 10);
context3.font="15px Verdana";
fs = "";
if( c < 0 ){
fs += " - " + (-c).toFixed(2).toString();
} else {
fs += " + " + c.toFixed(2).toString()
}
fs += "x"
if( d < 0 ){
fs += " - " + (-d).toFixed(2).toString();
} else {
fs += " + " + d.toFixed(2).toString()
}
context3.fillText(fs ,size/4+120, 135, 200);
}
function remove_event_listeners(){
canvas.removeEventListener('mousemove', mmove1);
canvas.removeEventListener('mouseup', mup1);
}
function remove_event_listeners3(){
canvas3.removeEventListener('mousemove', mmove3);
canvas3.removeEventListener('mouseup', mup3);
}
function add_event_listeners(){
canvas3.addEventListener('mousedown', mdown3, false);
canvas.addEventListener('mousedown', mdown1, false);
}
var qinc = 4/nump;
function mdown1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize;
var tinity = evt.clientY - rect.top - shh - hsize;
var id = Math.max( 0, Math.min( Math.floor( nump*((2*tinitx/hsize)+2)/4 ) , nump) );
//console.log(tinitx, tinity, fnx[id], fn[id], Math.abs( fn[id] - tinity ))
if( Math.abs( fn[id] - tinity ) < 8 ){
show[id] = true;
draw_axis();
show_guess = true;
guessx = fnx[id];
guessy = fn[id];
draw_tangent( dfn[id], fnx[id], fn[id]);
canvas.addEventListener('mousemove', mmove1, false);
canvas.addEventListener('mouseup', mup1, false);
}
}
function mmove1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize;
var tinity = evt.clientY - rect.top - shh - hsize;
var id = Math.max( 0, Math.min( Math.floor( nump*((2*tinitx/hsize)+2)/4 ) , nump) );
show[id] = true;
draw_axis();
draw_tangent( dfn[id], fnx[id], fn[id]);
}
function mup1(evt){
remove_event_listeners();
}
var which_slider;
function mdown3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
//check for slider position
if( ( tinitx > myslidera.left ) && ( tinitx < myslidera.right ) && Math.abs( tinity - myslidera.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 0;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderb.left ) && ( tinitx < mysliderb.right ) && Math.abs( tinity - mysliderb.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 1;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderc.left ) && ( tinitx < mysliderc.right ) && Math.abs( tinity - mysliderc.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 2;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderd.left ) && ( tinitx < mysliderd.right ) && Math.abs( tinity - mysliderd.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 3;
update_data(which_slider, tinitx);
return 0
}
}
function mmove3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
update_data(which_slider, tinitx);
}
function mup3(evt){
remove_event_listeners3();
}
function init_diff(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
if (!context.setLineDash) {
context.setLineDash = function () {}
}
context.translate(shw, shh);
canvas3 = document.getElementById("canvas3");
context3 = canvas3.getContext("2d");
if (!context3.setLineDash) {
context3.setLineDash = function () {}
}
context3.translate(shw, shh);
generate_cubic(-2, 2);
draw_axis();
add_event_listeners();
}
</script>
</head>
<body onLoad="init_diff();">
</BR>
<div id="matrixContainer" style="width: 501px">
<div id="matrix" style="float: left;">
<canvas id="canvas" width="501" height="501"></canvas>
</div>
<div id="matrix" style="float: left;">
<canvas id="canvas3" width="501" height="251"></canvas>
</div>
</div>
<div id="textContainer" style="width: 501px">
Perform one step of the Newton-Rhapson metthod by clicking on the function.
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-65389323844362519172015-08-21T02:26:00.001-07:002015-08-21T02:26:33.429-07:00Complex Operations<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Complex</title>
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
ctx.fillStyle="black";
}
function slider(_min, _max, _inc, _val, _left, _right, _yp, _sliderw){
this.minv= _min,
this.maxv= _max;
this.inc= _inc;
this.val= _val;
this.range = (_max - _min)
this.left = _left;
this.right = _right;
this.width = (_right - _left);
this.get_sp = function(){ return this.width*(this.val - this.minv)/this.range }
this.sp = this.get_sp();
this.yp = _yp;
this.sliderw = _sliderw;
this.update = function(tinitx){
this.val = Math.min( this.maxv,Math.max( this.minv + this.range*(tinitx - this.left)/this.width, this.minv ) );
}
this.draw = function(ctx){
this.sp = this.get_sp();
ctx.beginPath();
ctx.moveTo(this.left,this.yp);
ctx.lineTo(this.right,this.yp);
ctx.stroke();
ctx.fillRect(this.left + this.sp-this.sliderw/2, this.yp-this.sliderw,this.sliderw,2*this.sliderw);
}
}
var canvas;
var context;
var canvas2;
var context2;
var size = 500;
var hsize = size/2;
var tot = 750;
var shw = 1;
var shh = 1;
var x = new Array(2);
x[0] = 0; x[1] = 1;
var y = new Array(2);
y[0] = 1; y[1] = 1;
var z = new Array(2);
z[0] = 0; z[1] = 0;
var show_z = false;
var do_add = false;
var do_sub = false;
var do_mul = false;
var do_div = false;
function add(){
z[0] = x[0] + y[0];
z[1] = x[1] + y[1];
}
function sub(){
z[0] = x[0] - y[0];
z[1] = x[1] - y[1];
}
function mul(){
z[0] = x[0]*y[0] - x[1]*y[1];
z[1] = x[0]*y[1] + x[1]*y[0];
}
function div(){
var len = y[0]*y[0] + y[1]*y[1];
z[0] = (x[0]*y[0] + x[1]*y[1])/len;
z[1] = (x[0]*y[1] - x[1]*y[0])/len;
}
function update(){
if(do_add){
add(); return 0;
} else if (do_sub){
sub(); return 0;
} else if (do_mul){
mul(); return 0;
} else if (do_div){
div(); return 0;
}
return 0;
}
function set_add(){ do_add=true; do_sub=false; do_mul=false; do_div=false; }
function set_sub(){ do_add=false; do_sub=true; do_mul=false; do_div=false; }
function set_mul(){ do_add=false; do_sub=false; do_mul=true; do_div=false; }
function set_div(){ do_add=false; do_sub=false; do_mul=false; do_div=true; }
var scl = size/8;
function draw_button(ctx, x, y, w, state, string, sx, sy, fs){
var of = ctx.fillStyle;
if( !state ){ drawdot(ctx,x,y,w,"LightGray"); }
else { drawdot(ctx,x,y,w,"DarkGray"); }
ctx.fillStyle="black";
var oft = ctx.font;
ctx.font=fs.toString()+"px Arial";
ctx.fillText(string, sx, sy, 2*w);
ctx.fillStyle = of;
ctx.font=oft;
}
var br = size/25;
var by = size/10;
var bxinc = size/8;
var bx = (size/2) -2*bxinc + 2*br-br/2;
var bp = new Array(4);
bp[0] = bx;
bp[1] = bp[0] + bxinc;
bp[2] = bp[1] + bxinc;
bp[3] = bp[2] + bxinc;
function draw_axis(){
context.clearRect(-shw,-shh,tot,tot);
context.strokeRect(0,0,size,size);
context.translate(hsize, hsize);
context.setLineDash([5])
context.beginPath();
context.moveTo(-hsize,0);
context.lineTo(hsize,0);
context.stroke();
context.beginPath();
context.moveTo(0,-hsize);
context.lineTo(0,hsize);
context.stroke();
context.setLineDash([]);
drawdot(context, x[0]*scl, -x[1]*scl, 5, "red")
drawdot(context, y[0]*scl, -y[1]*scl, 5, "red")
if(show_z) drawdot(context, z[0]*scl, -z[1]*scl, 5, "blue")
context.translate(-hsize, -hsize);
//context2.strokeRect(size/12,size/12,size/8,size/12);
context2.clearRect(-shw,-shh,tot,tot);
draw_button(context2, bp[0], by, br, do_add, "+", bp[0]-br/2-2, by+br/2+2, 2*br);
draw_button(context2, bp[1], by, br, do_sub, "-", bp[1]-br/2+3, by+br/2, 2*br);
draw_button(context2, bp[2], by, br, do_mul, "\xD7", bp[2]-br/2-2, by+br/2+2, 2*br);
draw_button(context2, bp[3], by, br, do_div, "\xF7", bp[3]-br/2-1, by+br/2+2, 2*br);
context2.fillStyle="black";
context2.font="15px Verdana";
var left = size/8;
context2.fillText("("+x[0].toFixed(2).toString() ,left, size/4, 40);
fs = ""
if( x[1] < 0 ){
fs += " - " + (-x[1]).toFixed(2).toString() + "i)";
} else {
fs += " + " + x[1].toFixed(2).toString() + "i)";
}
context2.fillText(fs ,left+40, size/4, 80);
if(do_add){ context2.fillText("+" ,left+120, size/4, 20); }
else if(do_sub){ context2.fillText("-" ,left+120, size/4, 20); }
else if(do_mul){ context2.fillText("\xD7" ,left+120, size/4, 20); }
else if(do_div){ context2.fillText("\xF7" ,left+120, size/4, 20); }
else{ context2.fillText(" " ,left+120, size/4, 20); }
context2.fillText("("+y[0].toFixed(2).toString() ,left+140, size/4, 40);
fs = ""
if( y[1] < 0 ){
fs += " - " + (-y[1]).toFixed(2).toString() + "i)";
} else {
fs += " + " + y[1].toFixed(2).toString() + "i)";
}
context2.fillText(fs ,left+180, size/4, 80);
if( show_z ){
context2.fillText("=" ,left+260, size/4, 20);
context2.fillText("("+z[0].toFixed(2).toString() ,left+280, size/4, 40);
fs = ""
if( z[1] < 0 ){
fs += " - " + (-z[1]).toFixed(2).toString() + "i)";
} else {
fs += " + " + z[1].toFixed(2).toString() + "i)";
}
context2.fillText(fs ,left+320, size/4, 80);
}
}
function remove_event_listeners2(){ canvas2.removeEventListener('mouseup', mup2); }
function add_event_listeners(){ canvas.addEventListener('mousedown', mdown, false); }
function add_event_listeners2(){ canvas2.addEventListener('mousedown', mdown2, false); }
var movex = false;
var movey = false;
function mdown(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw-hsize;
var tinity = evt.clientY - rect.top - shh-hsize;
if( (tinitx - x[0]*scl)*(tinitx - x[0]*scl) + (tinity + x[1]*scl)*(tinity + x[1]*scl) <= 25 ){
canvas.addEventListener('mousemove', mmove1, false);
canvas.addEventListener('mouseup', mup1, false);
movex = true; movey = false;
return;
}
if( (tinitx - y[0]*scl)*(tinitx - y[0]*scl) + (tinity + y[1]*scl)*(tinity + y[1]*scl) <= 25 ){
canvas.addEventListener('mousemove', mmove1, false);
canvas.addEventListener('mouseup', mup1, false);
movex = false; movey = true;
return;
}
}
function mmove1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw-hsize;
var tinity = evt.clientY - rect.top - shh-hsize;
if(movex){ x[0] = tinitx/scl; x[1] = -tinity/scl; }
else if(movey){ y[0] = tinitx/scl; y[1] = -tinity/scl; }
update();
draw_axis();
}
function mup1(evt){
canvas.removeEventListener('mousemove', mmove1);
canvas.removeEventListener('mouseup', mup1);
movex = false; movey = false;
}
function mdown2(evt){
var rect = canvas2 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw;
var tinity = evt.clientY - rect.top - shh;
var ydiff = (tinity - by)*(tinity - by);
if( (tinitx - bp[0])*(tinitx - bp[0]) + ydiff <= br*br ){
set_add();
canvas2.addEventListener('mouseup', mup2, false);
}
if( (tinitx - bp[1])*(tinitx - bp[1]) + ydiff <= br*br ){
set_sub();
canvas2.addEventListener('mouseup', mup2, false);
}
if( (tinitx - bp[2])*(tinitx - bp[2]) + ydiff <= br*br ){
set_mul();
canvas2.addEventListener('mouseup', mup2, false);
}
if( (tinitx - bp[3])*(tinitx - bp[3]) + ydiff <= br*br ){
set_div();
canvas2.addEventListener('mouseup', mup2, false);
}
}
function mup2(evt){
show_z = true;
update();
draw_axis();
}
function init_complex(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
if (!context.setLineDash) {
context.setLineDash = function () {}
}
context.translate(shw, shh);
canvas2 = document.getElementById("canvas2");
context2 = canvas2.getContext("2d");
if (!context2.setLineDash) {
context2.setLineDash = function () {}
}
context2.translate(shw, shh);
add_event_listeners();
add_event_listeners2();
draw_axis();
}
</script>
</head>
<body onLoad="init_complex();">
</BR>
<div id="matrixContainer" style="width: 501px">
<div id="matrix" style="float: left;">
<canvas id="canvas" width="501" height="501"></canvas>
</div>
<div id="matrix" style="float: left;">
<canvas id="canvas2" width="501" height="251"></canvas>
</div>
</div>
<div id="textContainer" style="width: 501px">
Click a button to see the effect of that operation. Move the red dots around to change the inputs.
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-33121256347173830652015-08-19T10:25:00.002-07:002015-08-19T10:28:19.047-07:00Cubic Differentiation<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Differentiate cubic</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
ctx.fillStyle="black";
}
function slider(_min, _max, _inc, _val, _left, _right, _yp, _sliderw){
this.minv= _min,
this.maxv= _max;
this.inc= _inc;
this.val= _val;
this.range = (_max - _min)
this.left = _left;
this.right = _right;
this.width = (_right - _left);
this.get_sp = function(){ return this.width*(this.val - this.minv)/this.range }
this.sp = this.get_sp();
this.yp = _yp;
this.sliderw = _sliderw;
this.update = function(tinitx){
this.val = Math.min( this.maxv,Math.max( this.minv + this.range*(tinitx - this.left)/this.width, this.minv ) );
}
this.draw = function(ctx){
this.sp = this.get_sp();
ctx.beginPath();
ctx.moveTo(this.left,this.yp);
ctx.lineTo(this.right,this.yp);
ctx.stroke();
ctx.fillRect(this.left + this.sp-this.sliderw/2, this.yp-this.sliderw,this.sliderw,2*this.sliderw);
}
}
var canvas;
var context;
var canvas2;
var context2;
var canvas3;
var context3;
var size = 500;
var hsize = size/2;
var tot = 750;
var shw = 1;
var shh = 1;
var a = 1;
var b = 0;
var c = 0;
var d = 0
var sliderw=10;
var myslidera = new slider(-1,1,0.01,a, size/4, 3*size/4, 25 ,sliderw);
var mysliderb = new slider(-1,1,0.01,b, size/4, 3*size/4, 50 ,sliderw);
var mysliderc = new slider(-1,1,0.01,c, size/4, 3*size/4, 75 ,sliderw);
var mysliderd = new slider(-1,1,0.01,d, size/4, 3*size/4, 100 ,sliderw);
function plot_function(x){
return -(a*x*x*x + b*x*x + c*x+d);
}
function dplot_function(x){
return -(3*a*x*x + 2*b*x + c);
}
var fnx = new Array(101);
var fn = new Array(101);
var dfn = new Array(101);
var show = new Array(101);
function generate_cubic(left, right){
var inc = (right-left)/100;
var x = left;
for(var i=0; i<=100; i++){
fnx[i] = x*hsize/2;
fn[i] = plot_function(x)*hsize/2;
dfn[i] = dplot_function(x)*hsize/2;
show[i] = false;
x += inc;
}
}
function update_data(which_slider, tinitx){
switch(which_slider){
case 0:
myslidera.update(tinitx);
a = myslidera.val;
generate_cubic(-2, 2);
break;
case 1:
mysliderb.update(tinitx);
b = mysliderb.val;
generate_cubic(-2, 2);
break;
case 2:
mysliderc.update(tinitx);
c = mysliderc.val;
generate_cubic(-2, 2);
break;
case 3:
mysliderd.update(tinitx);
d = mysliderd.val;
generate_cubic(-2, 2);
break;
default:
return 1;
}
draw_axis();
return 0;
}
function draw_cubic(){
context.translate(hsize, hsize/2);
context.beginPath();
context.moveTo(fnx[0],fn[0]);
for(var i=1; i<=100; i++){
context.lineTo(fnx[i],fn[i]);
}
context.stroke();
/*for(var i=1; i<=100; i++){
if(show[i]){
drawdot(context, fnx[i], fn[i], 3, "red");
}
}*/
context.translate(-hsize, -hsize/2);
}
function draw_tangent(m, x, y){
context.translate(hsize, hsize/2);
drawdot(context, x,y, 3, "red");
context.beginPath();
var t0 = y + m * (fnx[0] - x) * 2 / hsize;
context.moveTo(fnx[0], t0);
var t1 = y + m * (fnx[100] - x) * 2 / hsize;
context.lineTo(fnx[100], t1);
context.strokeStyle="red"
context.stroke();
context.strokeStyle="black"
context.translate(-hsize, -hsize/2);
}
function draw_linear(){
context2.translate(hsize, hsize/2);
context2.beginPath();
context2.moveTo(fnx[0],dfn[0]);
for(var i=1; i<=100; i++){
if(show[i]){
drawdot( context2, fnx[i],dfn[i], 3, "blue" );
}
}
context2.stroke();
context2.translate(-hsize, -hsize/2);
}
function draw_axis(){
context.clearRect(-shw,-shh,tot,tot);
context.strokeRect(0,0,size,hsize);
context.setLineDash([5])
context.beginPath();
context.moveTo(hsize,0);
context.lineTo(hsize,size);
context.stroke();
context.beginPath();
context.moveTo(0,size/4);
context.lineTo(size,size/4);
context.stroke();
context.setLineDash([]);
draw_cubic();
context2.clearRect(-shw,-shh,tot,tot);
context2.strokeRect(0,0,size,hsize);
context2.setLineDash([5])
context2.beginPath();
context2.moveTo(hsize,0);
context2.lineTo(hsize,hsize);
context2.stroke();
context2.beginPath();
context2.moveTo(0,size/4);
context2.lineTo(size,size/4);
context2.stroke();
context2.setLineDash([]);
draw_linear()
context3.clearRect(-shw,-shh,tot,tot);
myslidera.draw(context3);
mysliderb.draw(context3);
mysliderc.draw(context3);
mysliderd.draw(context3);
context3.fillStyle="black";
context3.font="15px Verdana";
var fs = a.toFixed(2).toString() + "x";
context3.fillText(fs ,size/4, 135, 40);
context3.font="12px Verdana";
context3.fillText("3" ,size/4+40, 125, 10);
context3.font="15px Verdana";
fs = ""
if( b < 0 ){
fs += " - " + (-b).toFixed(2).toString();
} else {
fs += " + " + b.toFixed(2).toString()
}
fs += "x"
context3.fillText(fs ,size/4+50, 135, 60);
context3.font="12px Verdana";
context3.fillText("2" ,size/4+110, 125, 10);
context3.font="15px Verdana";
fs = "";
if( c < 0 ){
fs += " - " + (-c).toFixed(2).toString();
} else {
fs += " + " + c.toFixed(2).toString()
}
fs += "x"
if( d < 0 ){
fs += " - " + (-d).toFixed(2).toString();
} else {
fs += " + " + d.toFixed(2).toString()
}
context3.fillText(fs ,size/4+120, 135, 200);
}
function remove_event_listeners(){
canvas.removeEventListener('mousemove', mmove1);
canvas.removeEventListener('mouseup', mup1);
}
function remove_event_listeners3(){
canvas3.removeEventListener('mousemove', mmove3);
canvas3.removeEventListener('mouseup', mup3);
}
function add_event_listeners(){
canvas3.addEventListener('mousedown', mdown3, false);
canvas.addEventListener('mousedown', mdown1, false);
}
var qinc = 4/100;
function mdown1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize;
var tinity = evt.clientY - rect.top - shh - hsize/2;
var id = Math.max( 0, Math.min( Math.floor( 100*((2*tinitx/hsize)+2)/4 ) , 100) );
//console.log(tinitx, tinity, fnx[id], fn[id], Math.abs( fn[id] - tinity ))
if( Math.abs( fn[id] - tinity ) < 8 ){
show[id] = true;
draw_axis();
draw_tangent( dfn[id], fnx[id], fn[id]);
canvas.addEventListener('mousemove', mmove1, false);
canvas.addEventListener('mouseup', mup1, false);
}
}
function mmove1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize;
var tinity = evt.clientY - rect.top - shh - hsize/2;
var id = Math.max( 0, Math.min( Math.floor( 100*((2*tinitx/hsize)+2)/4 ) , 100) );
show[id] = true;
draw_axis();
draw_tangent( dfn[id], fnx[id], fn[id]);
}
function mup1(evt){
remove_event_listeners();
}
var which_slider;
function mdown3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
//check for slider position
if( ( tinitx > myslidera.left ) && ( tinitx < myslidera.right ) && Math.abs( tinity - myslidera.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 0;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderb.left ) && ( tinitx < mysliderb.right ) && Math.abs( tinity - mysliderb.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 1;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderc.left ) && ( tinitx < mysliderc.right ) && Math.abs( tinity - mysliderc.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 2;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderd.left ) && ( tinitx < mysliderd.right ) && Math.abs( tinity - mysliderd.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 3;
update_data(which_slider, tinitx);
return 0
}
}
function mmove3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
update_data(which_slider, tinitx);
}
function mup3(evt){
remove_event_listeners3();
}
function init_diff(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
if (!context.setLineDash) {
context.setLineDash = function () {}
}
context.translate(shw, shh);
canvas2 = document.getElementById("canvas2");
context2 = canvas2.getContext("2d");
if (!context2.setLineDash) {
context2.setLineDash = function () {}
}
context2.translate(shw, shh);
canvas3 = document.getElementById("canvas3");
context3 = canvas3.getContext("2d");
if (!context3.setLineDash) {
context3.setLineDash = function () {}
}
context3.translate(shw, shh);
generate_cubic(-2, 2);
draw_axis();
add_event_listeners();
}
</script>
</head>
<body onLoad="init_diff();">
</BR>
<div id="matrixContainer" style="width: 501px">
<div id="matrix" style="float: left;">
<canvas id="canvas" width="501" height="251"></canvas>
</div>
<div id="matrix" style="float: left;">
<canvas id="canvas2" width="501" height="251"></canvas>
</div>
<div id="matrix" style="float: left;">
<canvas id="canvas3" width="501" height="251"></canvas>
</div>
</div>
<div id="textContainer" style="width: 501px">
Use the sliders to adjust the function, click the function to see the tangent lines.
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-74534072729504958212015-08-19T10:23:00.000-07:002015-08-19T10:28:30.514-07:00Quadratic Differentiation<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Differentiate Quadratic</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
ctx.fillStyle="black";
}
function slider(_min, _max, _inc, _val, _left, _right, _yp, _sliderw){
this.minv= _min,
this.maxv= _max;
this.inc= _inc;
this.val= _val;
this.range = (_max - _min)
this.left = _left;
this.right = _right;
this.width = (_right - _left);
this.get_sp = function(){ return this.width*(this.val - this.minv)/this.range }
this.sp = this.get_sp();
this.yp = _yp;
this.sliderw = _sliderw;
this.update = function(tinitx){
this.val = Math.min( this.maxv,Math.max( this.minv + this.range*(tinitx - this.left)/this.width, this.minv ) );
}
this.draw = function(ctx){
this.sp = this.get_sp();
ctx.beginPath();
ctx.moveTo(this.left,this.yp);
ctx.lineTo(this.right,this.yp);
ctx.stroke();
ctx.fillRect(this.left + this.sp-this.sliderw/2, this.yp-this.sliderw,this.sliderw,2*this.sliderw);
}
}
var canvas;
var context;
var canvas2;
var context2;
var canvas3;
var context3;
var size = 500;
var hsize = size/2;
var tot = 750;
var shw = 1;
var shh = 1;
var a = 1;
var b = 0;
var c = 0;
var sliderw=10;
var myslidera = new slider(-1,1,0.01,a, size/4, 3*size/4, 25 ,sliderw);
var mysliderb = new slider(-1,1,0.01,b, size/4, 3*size/4, 50 ,sliderw);
var mysliderc = new slider(-1,1,0.01,c, size/4, 3*size/4, 75 ,sliderw);
function plot_function(x){
return -(a*x*x + b*x + c);
}
function dplot_function(x){
return -(2*a*x + b);
}
var fnx = new Array(101);
var fn = new Array(101);
var dfn = new Array(101);
var show = new Array(101);
function generate_quadratic(left, right){
var inc = (right-left)/100;
var x = left;
for(var i=0; i<=100; i++){
fnx[i] = x*hsize/2;
fn[i] = plot_function(x)*hsize/2;
dfn[i] = dplot_function(x)*hsize/2;
show[i] = false;
x += inc;
}
}
function update_data(which_slider, tinitx){
switch(which_slider){
case 0:
myslidera.update(tinitx);
a = myslidera.val;
generate_quadratic(-2, 2);
break;
case 1:
mysliderb.update(tinitx);
b = mysliderb.val;
generate_quadratic(-2, 2);
break;
case 2:
mysliderc.update(tinitx);
c = mysliderc.val;
generate_quadratic(-2, 2);
break;
default:
return 1;
}
draw_axis();
return 0;
}
function draw_quadratic(){
context.translate(hsize, hsize/2);
context.beginPath();
context.moveTo(fnx[0],fn[0]);
for(var i=1; i<=100; i++){
context.lineTo(fnx[i],fn[i]);
}
context.stroke();
/*for(var i=1; i<=100; i++){
if(show[i]){
drawdot(context, fnx[i], fn[i], 3, "red");
}
}*/
context.translate(-hsize, -hsize/2);
}
function draw_tangent(m, x, y){
context.translate(hsize, hsize/2);
drawdot(context, x,y, 3, "red");
context.beginPath();
var t0 = y + m * (fnx[0] - x) * 2 / hsize;
context.moveTo(fnx[0], t0);
var t1 = y + m * (fnx[100] - x) * 2 / hsize;
context.lineTo(fnx[100], t1);
context.strokeStyle="red"
context.stroke();
context.strokeStyle="black"
context.translate(-hsize, -hsize/2);
}
function draw_linear(){
context2.translate(hsize, hsize/2);
context2.beginPath();
context2.moveTo(fnx[0],dfn[0]);
for(var i=1; i<=100; i++){
if(show[i]){
drawdot( context2, fnx[i],dfn[i], 3, "blue" );
}
}
context2.stroke();
context2.translate(-hsize, -hsize/2);
}
function draw_axis(){
context.clearRect(-shw,-shh,tot,tot);
context.strokeRect(0,0,size,hsize);
context.setLineDash([5])
context.beginPath();
context.moveTo(hsize,0);
context.lineTo(hsize,size);
context.stroke();
context.beginPath();
context.moveTo(0,size/4);
context.lineTo(size,size/4);
context.stroke();
context.setLineDash([]);
draw_quadratic();
context2.clearRect(-shw,-shh,tot,tot);
context2.strokeRect(0,0,size,hsize);
context2.setLineDash([5])
context2.beginPath();
context2.moveTo(hsize,0);
context2.lineTo(hsize,hsize);
context2.stroke();
context2.beginPath();
context2.moveTo(0,size/4);
context2.lineTo(size,size/4);
context2.stroke();
context2.setLineDash([]);
draw_linear()
context3.clearRect(-shw,-shh,tot,tot);
myslidera.draw(context3);
mysliderb.draw(context3);
mysliderc.draw(context3);
context3.fillStyle="black";
context3.font="15px Verdana";
var fs = a.toFixed(2).toString() + "x";
context3.fillText(fs ,size/3, 110, 40);
context3.font="12px Verdana";
context3.fillText("2" ,size/3+40, 100, 10);
context3.font="15px Verdana";
fs = ""
if( b < 0 ){
fs += " - " + (-b).toFixed(2).toString();
} else {
fs += " + " + b.toFixed(2).toString()
}
fs += "x"
if( c < 0 ){
fs += " - " + (-c).toFixed(2).toString();
} else {
fs += " + " + c.toFixed(2).toString()
}
context3.fillText(fs ,size/3+50, 110, 200);
}
function remove_event_listeners(){
canvas.removeEventListener('mousemove', mmove1);
canvas.removeEventListener('mouseup', mup1);
}
function remove_event_listeners3(){
canvas3.removeEventListener('mousemove', mmove3);
canvas3.removeEventListener('mouseup', mup3);
}
function add_event_listeners(){
canvas3.addEventListener('mousedown', mdown3, false);
canvas.addEventListener('mousedown', mdown1, false);
}
var qinc = 4/100;
function mdown1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize;
var tinity = evt.clientY - rect.top - shh - hsize/2;
var id = Math.max( 0, Math.min( Math.floor( 100*((2*tinitx/hsize)+2)/4 ) , 100) );
//console.log(tinitx, tinity, fnx[id], fn[id], Math.abs( fn[id] - tinity ))
if( Math.abs( fn[id] - tinity ) < 8 ){
show[id] = true;
draw_axis();
draw_tangent( dfn[id], fnx[id], fn[id]);
canvas.addEventListener('mousemove', mmove1, false);
canvas.addEventListener('mouseup', mup1, false);
}
}
function mmove1(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - hsize;
var tinity = evt.clientY - rect.top - shh - hsize/2;
var id = Math.max( 0, Math.min( Math.floor( 100*((2*tinitx/hsize)+2)/4 ) , 100) );
show[id] = true;
draw_axis();
draw_tangent( dfn[id], fnx[id], fn[id]);
}
function mup1(evt){
remove_event_listeners();
}
var which_slider;
function mdown3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
//check for slider position
if( ( tinitx > myslidera.left ) && ( tinitx < myslidera.right ) && Math.abs( tinity - myslidera.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 0;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderb.left ) && ( tinitx < mysliderb.right ) && Math.abs( tinity - mysliderb.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 1;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > mysliderc.left ) && ( tinitx < mysliderc.right ) && Math.abs( tinity - mysliderc.yp ) < sliderw ){
canvas3.addEventListener('mousemove', mmove3, false);
canvas3.addEventListener('mouseup', mup3, false);
which_slider = 2;
update_data(which_slider, tinitx);
return 0
}
}
function mmove3(evt){
var rect = canvas3 .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
update_data(which_slider, tinitx);
}
function mup3(evt){
remove_event_listeners3();
}
function init_diff(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
if (!context.setLineDash) {
context.setLineDash = function () {}
}
context.translate(shw, shh);
canvas2 = document.getElementById("canvas2");
context2 = canvas2.getContext("2d");
if (!context2.setLineDash) {
context2.setLineDash = function () {}
}
context2.translate(shw, shh);
canvas3 = document.getElementById("canvas3");
context3 = canvas3.getContext("2d");
if (!context3.setLineDash) {
context3.setLineDash = function () {}
}
context3.translate(shw, shh);
generate_quadratic(-2, 2);
draw_axis();
add_event_listeners();
}
</script>
</head>
<body onLoad="init_diff();">
<div id="matrixContainer" style="width: 501px">
<div id="matrix" style="float: left;">
<canvas id="canvas" width="501" height="251"></canvas>
</div>
<div id="matrix" style="float: left;">
<canvas id="canvas2" width="501" height="251"></canvas>
</div>
<div id="matrix" style="float: left;">
<canvas id="canvas3" width="501" height="251"></canvas>
</div>
</div>
<div id="textContainer" style="width: 501px">
Use the sliders to adjust the function, click the function to see the tangent lines.
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-79161402822292168542015-08-19T05:42:00.000-07:002015-08-19T05:42:15.134-07:00Matrix Action 2<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Matrix Square</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function slider(_min, _max, _inc, _val, _left, _right, _yp, _sliderw){
this.minv= _min,
this.maxv= _max;
this.inc= _inc;
this.val= _val;
this.range = (_max - _min)
this.left = _left;
this.right = _right;
this.width = (_right - _left);
this.get_sp = function(){ return this.width*(this.val - this.minv)/this.range }
this.sp = this.get_sp();
this.yp = _yp;
this.sliderw = _sliderw;
this.update = function(tinitx){
this.val = Math.min( this.maxv,Math.max( this.minv + this.range*(tinitx - this.left)/this.width, this.minv ) );
}
this.draw = function(ctx){
this.sp = this.get_sp();
ctx.beginPath();
ctx.moveTo(this.left,this.yp);
ctx.lineTo(this.right,this.yp);
ctx.stroke();
ctx.fillRect(this.sp-this.sliderw/2, this.yp-this.sliderw,this.sliderw,2*this.sliderw);
}
}
var canvas;
var context;
var size = 450;
var tot = 850;
var runAnimation = {value: false};
var shw = 25;
var shh = 25;
var zero=0;
var left=-size/2;
var right=left+size;
var bottom=-size/2;
var ttop=bottom+size;
var draw1 = false;
var xcor1=0;
var ycor1=0;
var xcor2=0;
var ycor2=0;
function point(_x, _y){
this.x = _x;
this.y = _y;
}
var spos = size/8;
point0 = new point(spos, spos);
point1 = new point(spos, -spos);
point2 = new point(-spos, -spos);
point3 = new point(-spos, spos);
var mtx = new Array(2);
mtx[0] = new Array(2);
mtx[1] = new Array(2);
mtx[0][0] = 1; mtx[0][1] = 0;
mtx[1][0] = 0; mtx[1][1] = 1;
var sliderw=10;
var myslider00 = new slider(-2,2,0.01,mtx[0][0], zero, zero+size/2, ttop+25 ,sliderw);
var myslider10 = new slider(-2,2,0.01,mtx[1][0], zero, zero+size/2, ttop+50 ,sliderw);
var myslider01 = new slider(-2,2,0.01,mtx[0][1], zero, zero+size/2, ttop+75 ,sliderw);
var myslider11 = new slider(-2,2,0.01,mtx[1][1], zero, zero+size/2, ttop+100,sliderw);
var arrow_width = 5;
var arrow_len = 40;
function update_arrow(){
xcor2 = mtx[0][0] * xcor1 + mtx[0][1] *ycor1;
ycor2 = mtx[1][0] * xcor1 + mtx[1][1] *ycor1;
}
function update_point(pt, ox, oy){
pt.x = mtx[0][0] * ox + mtx[0][1] * oy;
pt.y = mtx[1][0] * ox + mtx[1][1] * oy;
}
function update_points(){
update_point(point0, spos, spos);
update_point(point1, spos, -spos);
update_point(point2, -spos, -spos);
update_point(point3, -spos, spos);
}
function update_data(which_slider, tinitx){
switch(which_slider){
case 0:
myslider00.update(tinitx);
mtx[0][0] = myslider00.val;
break;
case 1:
myslider01.update(tinitx);
mtx[0][1] = myslider01.val;
break;
case 2:
myslider10.update(tinitx);
mtx[1][0] = myslider10.val;
break;
case 3:
myslider11.update(tinitx);
mtx[1][1] = myslider11.val;
break;
default:
return 1;
}
update_points()
draw_axis();
return 0;
}
function draw_square(col){
context.beginPath();
context.strokeStyle=col;
context.moveTo(zero, zero);
context.beginPath();
context.moveTo(point0.x, point0.y);
context.lineTo(point1.x, point1.y);
context.lineTo(point2.x, point2.y);
context.lineTo(point3.x, point3.y);
context.lineTo(point0.x, point0.y);
context.stroke();
context.strokeStyle="black";
}
function draw_axis(){
context.clearRect(-2*size,-2*size,4*size,4*size);
context.strokeRect(left,bottom,size,size);
context.beginPath();
context.moveTo(zero, bottom);
context.lineTo(zero, ttop);
context.moveTo(left,zero);
context.lineTo(right,zero);
context.stroke();
context.beginPath();
context.moveTo(spos, spos);
context.lineTo(spos, -spos);
context.lineTo(-spos, -spos);
context.lineTo(-spos, spos);
context.lineTo(spos, spos);
context.stroke();
context.fillStyle="black";
context.font="90px Veranda";
context.fillText("(", left, ttop+80 );
context.fillText(")", left+175, ttop+80 );
context.font="30px Verdana";
context.fillText(mtx[0][0].toFixed(2).toString() ,left+35, ttop + 40, 60);
context.fillText(mtx[0][1].toFixed(2).toString() ,left+115, ttop + 40, 60);
context.fillText(mtx[1][0].toFixed(2).toString() ,left+35, ttop + 85, 60);
context.fillText(mtx[1][1].toFixed(2).toString() ,left+115, ttop + 85, 60);
myslider00.draw(context);
myslider10.draw(context);
myslider01.draw(context);
myslider11.draw(context);
draw_square("red");
}
function remove_event_listeners(){
canvas.removeEventListener('mousemove', mmove);
canvas.removeEventListener('mouseup', mup);
}
function add_event_listeners(){
canvas.addEventListener('mousedown', mdown, false);
}
var which_slider;
function mdown(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - size/2
var tinity = evt.clientY - rect.top - shh - size/2
//check for slider position
if( ( tinitx > myslider00.left ) && ( tinitx < myslider00.right ) && Math.abs( tinity - myslider00.yp ) < sliderw ){
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mouseup', mup, false);
which_slider = 0;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > myslider01.left ) && ( tinitx < myslider01.right ) && Math.abs( tinity - myslider01.yp ) < sliderw ){
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mouseup', mup, false);
which_slider = 1;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > myslider10.left ) && ( tinitx < myslider10.right ) && Math.abs( tinity - myslider10.yp ) < sliderw ){
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mouseup', mup, false);
which_slider = 2;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > myslider11.left ) && ( tinitx < myslider11.right ) && Math.abs( tinity - myslider11.yp ) < sliderw ){
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mouseup', mup, false);
which_slider = 3;
update_data(which_slider, tinitx);
return 0
}
}
function mmove(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - size/2
var tinity = evt.clientY - rect.top - shh - size/2
update_data(which_slider, tinitx);
}
function mup(evt){
remove_event_listeners();
}
function init_matrix(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(shw+size/2, shh+size/2);
context.font="italic 15px Helvetica";
draw_axis();
//draw_arrow(xcor, ycor);
add_event_listeners();
//animate_matrix( runAnimation, canvas, context);
}
</script>
</head>
<body onLoad="init_matrix();">
</BR>
<div id="matrixContainer" style="width: 700px">
<div id="matrix" style="float: left;">
<canvas id="canvas" width="650" height="625"></canvas>
</div>
</div>
Use the sliders to change the matrix to see the effect on the unit square.
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-66406376624071266482015-08-18T13:15:00.001-07:002015-08-19T05:28:02.868-07:00Matrix Action<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Matrix</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function slider(_min, _max, _inc, _val, _left, _right, _yp, _sliderw){
this.minv= _min,
this.maxv= _max;
this.inc= _inc;
this.val= _val;
this.range = (_max - _min)
this.left = _left;
this.right = _right;
this.width = (_right - _left);
this.get_sp = function(){ return this.width*(this.val - this.minv)/this.range }
this.sp = this.get_sp();
this.yp = _yp;
this.sliderw = _sliderw;
this.update = function(tinitx){
this.val = Math.min( this.maxv,Math.max( this.minv + this.range*(tinitx - this.left)/this.width, this.minv ) );
}
this.draw = function(ctx){
this.sp = this.get_sp();
ctx.beginPath();
ctx.moveTo(this.left,this.yp);
ctx.lineTo(this.right,this.yp);
ctx.stroke();
ctx.fillRect(this.sp-this.sliderw/2, this.yp-this.sliderw,this.sliderw,2*this.sliderw);
}
}
var canvas;
var context;
var size = 450;
var tot = 850;
var runAnimation = {value: false};
var shw = 25;
var shh = 25;
var zero=0;
var left=-size/2;
var right=left+size;
var bottom=-size/2;
var ttop=bottom+size;
var draw1 = false;
var xcor1=0;
var ycor1=0;
var xcor2=0;
var ycor2=0;
var mtx = new Array(2);
mtx[0] = new Array(2);
mtx[1] = new Array(2);
mtx[0][0] = 1; mtx[0][1] = 0;
mtx[1][0] = 0; mtx[1][1] = 1;
var sliderw=10;
var myslider00 = new slider(-2,2,0.01,mtx[0][0], zero, zero+size/2, ttop+25 ,sliderw);
var myslider10 = new slider(-2,2,0.01,mtx[1][0], zero, zero+size/2, ttop+50 ,sliderw);
var myslider01 = new slider(-2,2,0.01,mtx[0][1], zero, zero+size/2, ttop+75 ,sliderw);
var myslider11 = new slider(-2,2,0.01,mtx[1][1], zero, zero+size/2, ttop+100,sliderw);
var arrow_width = 5;
var arrow_len = 40;
function update_arrow(){
xcor2 = mtx[0][0] * xcor1 + mtx[0][1] *ycor1;
ycor2 = mtx[1][0] * xcor1 + mtx[1][1] *ycor1;
}
function update_data(which_slider, tinitx){
switch(which_slider){
case 0:
myslider00.update(tinitx);
mtx[0][0] = myslider00.val;
break;
case 1:
myslider01.update(tinitx);
mtx[0][1] = myslider01.val;
break;
case 2:
myslider10.update(tinitx);
mtx[1][0] = myslider10.val;
break;
case 3:
myslider11.update(tinitx);
mtx[1][1] = myslider11.val;
break;
default:
return 1;
}
update_arrow();
draw_axis();
return 0;
}
function draw_arrow(xend, yend, col){
context.beginPath();
var ow = context.lineWidth;
context.lineWidth=5;
context.fillStyle=col;
context.strokeStyle=col;
context.moveTo(zero, zero);
var len=Math.sqrt(xend*xend + yend*yend);
//if( len <= 0 ) len = arrow_len;
var cost = xend/len;
var sint = yend/len;
var xen = xend - arrow_len*cost;
var yen = yend - arrow_len*sint;
//triangle
context.lineTo(xen, yen);
context.stroke();
context.lineWidth=ow;
context.lineTo(xen + arrow_width*sint, yen - arrow_width*cost);
context.lineTo(xen + arrow_len*cost, yen + arrow_len*sint);
context.lineTo(xen - arrow_width*sint, yen + arrow_width*cost);
context.lineTo(xen, yen);
//arcTo sucks
context.stroke();
context.fill();
context.lineWidth=ow;
context.fillStyle="black";
context.strokeStyle="black";
}
function draw_axis(){
context.clearRect(-2*size,-2*size,4*size,4*size);
context.strokeRect(left,bottom,size,size);
context.beginPath();
context.moveTo(zero, bottom);
context.lineTo(zero, ttop);
context.moveTo(left,zero);
context.lineTo(right,zero);
context.stroke();
context.fillStyle="black";
context.font="90px Veranda";
context.fillText("(", left, ttop+80 );
context.fillText(")", left+175, ttop+80 );
context.font="30px Verdana";
context.fillText(mtx[0][0].toFixed(2).toString() ,left+35, ttop + 40, 60);
context.fillText(mtx[0][1].toFixed(2).toString() ,left+115, ttop + 40, 60);
context.fillText(mtx[1][0].toFixed(2).toString() ,left+35, ttop + 85, 60);
context.fillText(mtx[1][1].toFixed(2).toString() ,left+115, ttop + 85, 60);
myslider00.draw(context);
myslider10.draw(context);
myslider01.draw(context);
myslider11.draw(context);
if(draw1){
draw_arrow(xcor1, ycor1, "black");
draw_arrow(xcor2, ycor2, "red");
}
}
function remove_event_listeners(){
canvas.removeEventListener('mousemove', mmove);
canvas.removeEventListener('mouseup', mup);
}
function add_event_listeners(){
canvas.addEventListener('mousedown', mdown, false);
}
var which_slider;
function mdown(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - size/2
var tinity = evt.clientY - rect.top - shh - size/2
//check for slider position
if( ( tinitx > myslider00.left ) && ( tinitx < myslider00.right ) && Math.abs( tinity - myslider00.yp ) < sliderw ){
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mouseup', mup, false);
which_slider = 0;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > myslider01.left ) && ( tinitx < myslider01.right ) && Math.abs( tinity - myslider01.yp ) < sliderw ){
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mouseup', mup, false);
which_slider = 1;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > myslider10.left ) && ( tinitx < myslider10.right ) && Math.abs( tinity - myslider10.yp ) < sliderw ){
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mouseup', mup, false);
which_slider = 2;
update_data(which_slider, tinitx);
return 0
}
if( ( tinitx > myslider11.left ) && ( tinitx < myslider11.right ) && Math.abs( tinity - myslider11.yp ) < sliderw ){
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mouseup', mup, false);
which_slider = 3;
update_data(which_slider, tinitx);
return 0
}
which_slider=-1;
if( tinitx > left && tinitx < right && tinity < ttop && tinity > bottom){
if( !draw1 ){ draw1 = true; }
xcor1 = tinitx;
ycor1 = tinity;
draw1 = true;
update_arrow();
draw_axis();
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mouseup', mup, false);
}
}
function mmove(evt){
var rect = canvas .getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw - size/2
var tinity = evt.clientY - rect.top - shh - size/2
if( which_slider == -1 ){
xcor1 = tinitx;
ycor1 = tinity;
draw1 = true;
update_arrow();
draw_axis();
return 0;
}
update_data(which_slider, tinitx);
}
function mup(evt){
remove_event_listeners();
}
function init_matrix(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(shw+size/2, shh+size/2);
context.font="italic 15px Helvetica";
draw_axis();
//draw_arrow(xcor, ycor);
add_event_listeners();
//animate_matrix( runAnimation, canvas, context);
}
</script>
</head>
<body onLoad="init_matrix();">
</BR>
<div id="matrixContainer" style="width: 700px">
<div id="matrix" style="float: left;">
<canvas id="canvas" width="650" height="625"></canvas>
</div>
</div>
Click to create an arrow, you can drag it around. Use the sliders to change the matrix.
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-73091217877780814782015-03-03T04:18:00.000-08:002015-03-03T10:43:51.266-08:00Snakes in a Plane<!DOCTYPE html>
<html>
<script>
var context;
var x = Math.round(Math.random()*40)*10;
var y = Math.round(Math.random()*40)*10;
var snake = [[x,y]];
var speed = 10;
var dy = 0;
var dx = speed;
var food_x = Math.round(Math.random()*40)*10;
var food_y = Math.round(Math.random()*40)*10;
var counter = 0;
var score = 0;
var gamePlay = 0;
var char = getChar(event || window.event)
function moveSelection(evt) {
switch (evt.keyCode) {
case 37:
evt.preventDefault();
if (snake.length > 1 && snake[0][0]-snake[1][0] > 0){ break; }
else {
dx= -speed;
dy = 0;
break; }
case 39:
evt.preventDefault();
if (snake.length > 1 && snake[0][0]-snake[1][0] < 0){ break; }
else {
dx = speed;
dy = 0;
break; }
case 38:
evt.preventDefault();
if (snake.length > 1 && snake[0][1]-snake[1][1] > 0){ break; }
else {
dx = 0;
dy = -speed;
break; }
case 40:
evt.preventDefault();
if (snake.length > 1 && snake[0][1]-snake[1][1] < 0){ break; }
else {
dx = 0;
dy = speed;
break; }
case 32:
evt.preventDefault();
if (gamePlay === 1) {gamePlay = 0; break;}
else {gamePlay = 1; break;}
}
};
function init() {
context= myCanvas.getContext('2d');
setInterval(draw,10);
window.addEventListener('keydown', moveSelection);
}
function draw(){
counter +=1;
context.clearRect(0,0,400,400);
for (i = 0; i < snake.length; i++){
context.beginPath();
context.fillStyle="#0000ff";
// Draws a circle of radius 5 at the coordinates 100,100 on the canvas
context.arc(snake[i][0],snake[i][1],5,0,Math.PI*2,true);
context.closePath();
context.fill();
}
// draw food
context.beginPath();
context.fillStyle="red";
context.arc(food_x, food_y,5,0,Math.PI*2,true);
context.closePath();
context.fill();
if (counter % 10 === 0 && gamePlay === 1) {
x+=dx;
y+=dy;
if (Math.abs(snake[0][0]-food_x) < 10 && Math.abs(snake[0][1]-food_y) < 10) {
food_x = Math.round(Math.random()*40)*10;
food_y = Math.round(Math.random()*40)*10;
snake[snake.length] = [0,0];
score += 1;
}
for (i = snake.length-1; i > 0; i--){
snake[i][0] = snake[i-1][0];
snake[i][1] = snake[i-1][1];
}
snake[0][0]= x;
snake[0][1]= y;
if (snake[0][0] < 0 || snake[0][0] > 400 || snake[0][1] < 0 || snake[0][1] > 400) {
alert("GAME OVER! Your score: "+score);
score = 0;
x = Math.round(Math.random()*40)*10;
y = Math.round(Math.random()*40)*10;
snake = [[x,y]];
dy = 0;
dx = speed;
gamePlay = 0;
}
for (i = 1; i < snake.length - 1; i++){
if (snake[0][0] === snake[i][0] && snake[0][1] === snake[i][1]){
alert("GAME OVER! Your score: "+score);
score = 0;
x = Math.round(Math.random()*40)*10;
y = Math.round(Math.random()*40)*10;
snake = [[x,y]];
dy = 0;
dx = speed;
gamePlay = 0;
}
}
}
}
</script>
<body onLoad="init();" >
<p>We have a guest post from the lovely Arwen Nicholson. Press the spacebar to start and pause the game. Use the arrow keys to lead the snake to the food.</p>
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #000000;">
</canvas>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-69431554936097429692015-01-11T01:53:00.002-08:002015-01-11T10:47:24.000-08:00The Tower of Brahma<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Hanoi</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawpoint(ctx,x,y,fs){
ctx.beginPath();
ctx.arc(x,y,1,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
</script>
<script type="text/javascript">
var canvas;
var context;
var width = 600;
var height = 400;
var tower_h = 300;
var tower_w = 10;
var t = new Array(3);
t[0] = 100;
t[1] = (width-tower_w)/2;
t[2] = width - 100 - tower_w;
var shw=10;
var shh=10;
var runAnimation = {value: true};
var Nb = 12;
var b_max = 100;
var b_min = 30;
var b_step = (b_max - b_min)/(Nb-1); if(Nb == 1){ b_step = b_max; }
var bw = Math.min(10, tower_h/Nb );
var istack = new Array();
function ring (x, y, s) {
this.x = x;
this.y = y;
this.s = s;
}
var tstack = new Array(3);
function draw_towers( ){
context.clearRect(-shw,-shh,width + 2*shw, height + 2*shh);
context.fillStyle = "black";
context.fillRect(0,height,width,10);
context.fillRect(t[0], height-tower_h,tower_w,tower_h);
context.fillRect(t[1], height-tower_h,tower_w,tower_h);
context.fillRect(t[2], height-tower_h,tower_w,tower_h);
context.fillStyle = "red";
for(var i=0; i<3; i++){
for(var j=0; j<tstack[i].length; j++){
context.strokeRect(tstack[i][j].x - tstack[i][j].s/2, tstack[i][j].y, tstack[i][j].s, bw);
context.fillRect(tstack[i][j].x - tstack[i][j].s/2, tstack[i][j].y, tstack[i][j].s, bw);
}
}
}
function initialize(){
tstack[0] = new Array();
tstack[1] = new Array();
tstack[2] = new Array();
for(var i=0; i<Nb; i++){
tstack[0].push( new ring( t[0] + tower_w/2, height - (i+1)*bw, b_max - i*b_step) );
}
}
/*
var dx = 1;
var dy = 1;
var mh = false;
var mu = false;
var md = false;
function move_horiz(bi, tp, sgn){
if( Math.round( bpos[bi][0] ) != tp ){
bpos[bi][0] += sgn*dx;
mh = true;
} else {
mh = false;
}
}
function move_up(bi){
if( Math.round( bpos[bi][1] ) != height - tower_h - bw ){
bpos[bi][1] -= dy;
mu = true;
} else {
mu = false;
}
}
function move_down(bi, ti){
if( Math.round( bpos[bi][1] ) != height - tpile[ti] - bw ){
bpos[bi][1] += dy;
md = true;
} else {
md = false;
}
} */
function jump( from, to ){
if( tstack[from].length > 0 ){
var tmp = tstack[from].pop();
tmp.x = t[to] + tower_w/2;
if( tstack[to].length > 0){ tmp.y = tstack[to][tstack[to].length-1].y - bw; }
else{ tmp.y = height - bw; }
tstack[to].push( tmp );
}
}
function start_stop(){ runAnimation.value = !runAnimation.value }
function waste_time(){ for(var i=0; i<1; i++){ draw_towers(); } }
function movetower(N, start, fin, tmp){
if( N == 1 ){
//console.log(start, " ato ", fin );// jump(start, fin);
var ins = new Array(2); ins[0] = start; ins[1] = fin;
istack.push( ins );
}
else{
movetower( N-1, start, tmp, fin);
//console.log(start, " bto ", fin );// jump(start, fin);
var ins = new Array(2); ins[0] = start; ins[1] = fin;
istack.push( ins );
movetower( N-1, tmp, fin, start);
}
}
function animate_grid(runAnimation, canvas, context) {
if(runAnimation.value) {
draw_towers( );
if( istack.length > 0 ){
var last = istack.length - 1;
//console.log( istack[last][0], " to ", istack[last][1] );
move = istack.shift();
jump( move[0], move[1] );
}
}
setTimeout( function() {
requestAnimFrame(function() {
animate_grid( runAnimation, canvas, context);
});
}, 400);
}
function init_tower(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(shw, shh);
context.strokeRect(0,0,width, height);
initialize();
draw_towers();
animate_grid(runAnimation, canvas, context);
movetower(Nb, 0, 1, 2);
}
</script>
</head>
<body onLoad="init_tower();">
<i>
In the great temple at Benares beneath the dome which marks the centre of the world, rests a brass plate in which are fixed three diamond needles, each a cubit high and as thick as the body of a bee. On one of these needles at the creation, God placed sixty-four disks of pure gold, the largest disk resting on the brass plate and the others getting smaller and smaller up to the top one. This is the Tower of Brahma. Day and night unceasingly, the priests transfer the disks from one diamond needle to another according to the fixed and immutable laws of Brahma, which require that the priest on duty must not move more than one disk at a time and that he must place this disk on a needle so that there is no smaller disk below it. When all sixty-four disks shall have been thus transferred from the needle on which at creation God placed them to one of the other needles, tower, temple and Brahmins alike will crumble into dust, and with a thunderclap the world will vanish.
</i>
<div id="PendContainer" style="width: 800px">
<div id="Pend" style="float: left;">
<canvas id="canvas" width="800" height="800"></canvas>
</div>
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-14370504749856185242014-12-25T00:19:00.000-08:002014-12-25T05:09:18.545-08:00Christmas Tree<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>demon</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function drawdot_t(ctx,x,y,r,fs, al){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.globalAlpha = al;
ctx.fillStyle=fs;
ctx.fill();
ctx.globalAlpha = 1;
}
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
var canvas;
var context;
var h = 500;
var w = 500;
var runAnimation = {value: true};
var shw = 35;
var shh = 35;
var dt = 1;
var t = 0;
function PBall (xp, yp, xv, yv, r, col) {
this.xp = xp;
this.yp = yp;
this.xv = xv;
this.yv = yv;
this.vm = Math.sqrt(xv*xv + yv*yv);
this.r = r;
this.col = col;
this.spec = false;
}
PBall.prototype.draw = function() {
drawdot(context, this.xp, this.yp, this.r, this.col);
};
PBall.prototype.advance = function(time) {
this.xp += this.xv*time;
this.yp += this.yv*time;
};
var nrows = 12;
var nballs = nrows;
var peg_size = 2;
var ball = new Array(nrows);
var npegs = nrows*(nrows + 1)/2;
var pegs = new Array(npegs);
var ht_space = 25;
var hb_space = 150;
var dh = (h-ht_space - hb_space)/nrows;
var w_space = 40;
var dw = (w - 2*w_space)/nrows;
var ii = 0;
for(var i=1; i<=nrows; i++){
for(var j=0; j<i; j++){
pegs[ii] = new PBall( j*dw + w/2 - (i-1)*(dw/2), ht_space + i*dh,
0,0,peg_size, rgbToHex(0,255,0) );
ii++;
}
}
function drawStar(cx,cy,spikes,outerRadius,innerRadius, col){
var rot=(Math.PI/2)*3;
var x=cx;
var y=cy;
var step=Math.PI/spikes;
context.fillStyle = col;
context.strokeStyle = col;
context.beginPath();
context.moveTo(cx,cy-outerRadius)
for(i=0;i<spikes;i++){
x=cx+Math.cos(rot)*outerRadius;
y=cy+Math.sin(rot)*outerRadius;
context.lineTo(x,y)
rot+=step
x=cx+Math.cos(rot)*innerRadius;
y=cy+Math.sin(rot)*innerRadius;
context.lineTo(x,y)
rot+=step
}
context.lineTo(cx,cy-outerRadius);
context.fill();
context.stroke();
context.closePath();
}
function random_color(){
return rgbToHex( Math.round(255*Math.random()), Math.round(255*Math.random()), Math.round(255*Math.random()) )
}
var ndrops = 50;
var snow = new Array(ndrops);
var flake_rad = 3;
for(var i=0; i<ndrops; i++){
snow[i] = new PBall( Math.round( Math.random()*w ), Math.round( Math.random()*h ), 0, 0.3 + 0.1*Math.random(), flake_rad,
rgbToHex(255,255,255) );
}
function drawLine(x1, y1, x2, y2, brightness){
context.moveTo(x1, y1);
context.lineTo(x2, y2);
}
var deg_to_rad = Math.PI / 180.0;
var point = new Array(200);
var counter = 0;
var min_x = 0;
var min_y = h;
for(var i=0; i<200; i++){ point[i] = new Array(4); }
function makeTree(x1, y1, angle, depth){
if (depth > 0){
var x2 = x1 + (Math.cos(angle * deg_to_rad) * Math.pow(depth,0.5) * 20.0);
var y2 = y1 + (Math.sin(angle * deg_to_rad) * Math.pow(depth,0.5) * 20.0);
//drawLine(x1, y1, x2, y2, depth);
point[counter][0] = x1;
point[counter][1] = y1;
point[counter][2] = x2;
point[counter][3] = y2;
if( y1 < min_y ){ min_y = y1; min_x = x1; }
if( y2 < min_y ){ min_y = y2; min_x = x2; }
counter++;
makeTree(x2, y2, angle, depth - 1);
makeTree(x2, y2, angle - (120-(8-depth)), depth - 2);
makeTree(x2, y2, angle + (120-(8-depth)), depth - 2);
}
}
function draw_pong(base, x){
context.clearRect(-shw,-shh,w+2*shw,h+2*shh);
context.fillStyle = "black";
context.fillRect(0,0,w,h);
for(var i=0; i<ndrops; i++){ snow[i].draw(); }
context.beginPath();
context.lineWidth = 5;
context.strokeStyle = "green";
for(var i=0; i<counter; i++){
drawLine(point[i][0], point[i][1], point[i][2], point[i][3]);
}
context.stroke();
context.lineWidth = 1;
context.strokeStyle = "black";
for(var i=0; i<counter; i++){
drawdot(context, point[i][0], point[i][1], 8, random_color() );
drawdot(context, point[i][2], point[i][3], 8, random_color() );
}
var bord = 20;
/*context.beginPath();
context.moveTo(pegs[0].xp, pegs[0].yp - bord);
context.lineTo(pegs[npegs-1].xp + bord, pegs[npegs-1].yp + bord);
context.lineTo(pegs[npegs-nrows].xp - bord, pegs[npegs-1].yp + bord);
context.closePath();
context.fillStyle = "green";
context.strokeStyle = "green";
context.fill();
context.stroke();*/
drawStar(min_x, min_y, 5, 30, 15, "#FFDF00" );
//for(var i=0; i<npegs; i++){ pegs[i].col = random_color(); pegs[i].draw(); }
}
function animate_pong(runAnimation, canvas, context) {
t = 0;
if(runAnimation.value) {
for(var i=0; i<ndrops; i++){
snow[i].advance(dt);
if(snow[i].yp >= h - flake_rad){
snow[i].xp = Math.round( Math.random()*w );
snow[i].yp = 0;
}
}
draw_pong();
}
setTimeout(function() {
requestAnimFrame(function() {
animate_pong( runAnimation, canvas, context);
});
}, t);
}
function init_pong(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(shw, shh);
context.font="italic 15px Helvetica";
canvas.addEventListener('mouseup', close, false);
makeTree(250, 400, -90, 8);
draw_pong();
runAnimation.value = true;
animate_pong( runAnimation, canvas, context);
}
</script>
</head>
<body onLoad="init_pong();" bgcolor="black">
</BR>
<div id="pongContainer" style="width: 500px; margin-left: 0px;">
<div id="pong" style="margin-left: 0px; float: left;">
<canvas id="canvas" width="600" height="700"></canvas>
</div>
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-1604011762330184472014-10-20T09:59:00.001-07:002014-10-21T02:19:25.350-07:00A Murmuration of Arrows<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Viscek Model</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
ctx.stroke();
}
function bad_gaussian(mu, sigma){
var G = (-1.0 + 2.0*Math.random()) + (-1.0 + 2.0*Math.random()) + (-1.0 + 2.0*Math.random());
return G*sigma + mu;
}
var size = 512;
var Nmax = 600;
var N = 300;
var canvas;
var context;
var pi = Math.PI;
var runAnimation = {value: true};
var birds = new Array(Nmax);
var dt = 4;
var v0 = 1;
var bird_len = 20;
var arrow_width = 2;
var arrow_len = 5;
var visible = 20;
var visible2 = visible*visible;
var eta = 0.02;
var obs_rad = 20;
for (var i = 0; i < Nmax; i++) {
birds[i] = new Array(4); //x, y, v0, th0
birds[i][0] = Math.round( size * Math.random() );
birds[i][1] = Math.round( size * Math.random() );
birds[i][2] = v0; //bad_gaussian(1, 0.1);
birds[i][3] = Math.random() * 2* pi;
}
var Ndots = 0;
var Ndots_max = 30;
var dots = new Array(Ndots_max);
var dot_rad = 10;
for (var i = 0; i < Ndots_max; i++) {
dots[i] = new Array(3); //x, y, v0, th0
dots[i][0] = Math.round( size * Math.random() );
dots[i][1] = Math.round( size * Math.random() );
dots[i][2] = v0;
dots[i][3] = Math.random() * 2* pi;
}
function restart(){
var dt = 4;
for (var i = 0; i < N; i++) {
birds[i][0] = Math.round( size * Math.random() );
birds[i][1] = Math.round( size * Math.random() );
birds[i][2] = v0; //bad_gaussian(1, 0.1);
birds[i][3] = Math.random() * 2* pi;
}
Ndots = 0;
for (var i = 0; i < Ndots_max; i++) {
dots[i][0] = Math.round( size * Math.random() );
dots[i][1] = Math.round( size * Math.random() );
dots[i][2] = v0;
dots[i][3] = Math.random() * 2* pi;
}
}
function draw_bird(i){
context.beginPath();
context.moveTo(birds[i][0], birds[i][1]);
var cost = Math.cos( birds[i][3] );
var sint = Math.sin( birds[i][3] );
var xend = birds[i][0] + (bird_len)*cost;
var yend = birds[i][1] + (bird_len)*sint;
//triangle
context.lineTo(xend, yend);
context.lineTo(xend + arrow_width*sint, yend - arrow_width*cost);
context.lineTo(xend + arrow_len*cost, yend + arrow_len*sint);
context.lineTo(xend - arrow_width*sint, yend + arrow_width*cost);
context.lineTo(xend, yend);
//arcTo sucks
context.stroke();
context.fill();
}
function draw_birds(){
for(var i=0; i<N; i++){
draw_bird(i);
}
}
function draw_dots(){
for(var i=0; i<Ndots; i++){
if(dots[i][3] > 0 && dots[i][3] % 40 == 0 && dots[i][2] > 0){ dots[i][2]--; }
drawdot( context, dots[i][0], dots[i][1], dot_rad, "black");
//dots[i][3]++;
}
}
var vdots = 0;
function inc_birds(){
for(var i=0; i<N; i++){
//calc avspeed
var vx = 0;
var vy = 0;
var k = 0;
for(var j=0; j<N; j++){
if(i != j ){
if( (birds[i][0] - birds[j][0])*(birds[i][0] - birds[j][0])
+ (birds[i][1] - birds[j][1])*(birds[i][1] - birds[j][1])
< visible2 ){
vx += birds[j][2] * Math.cos( birds[j][3] );
vy += birds[j][2] * Math.sin( birds[j][3] );
k++;
}
}
}
if( k > 0){
vx /= k;
vy /= k;
}
var l = 0;
for( var j=0; j<Ndots; j++){
var dx = (birds[i][0] - dots[j][0]);
var dy = (birds[i][1] - dots[j][1]);
var dist = ( dx*dx + dy*dy );
if( dist <= (visible + dot_rad)*(visible + dot_rad) ){
//runAnimation.value = false;
//console.log( birds[i][0] , dots[j][0] , birds[i][1] , dots[j][1] );
var dist = Math.sqrt( dist );
//console.log(vx, vy, (size/dist) * (dx/dist), (size/dist) * (dy/dist) );
vx += (size/dist) * (dx/dist);
vy += (size/dist) * (dy/dist);
l++
}
}
if(k > 0 || l > 0){
vx += eta*Math.cos(2*pi*Math.random());
vy += eta*Math.sin(2*pi*Math.random());
var angle = Math.atan( Math.abs(vy/vx) );
if(vx > 0 && vy < 0){ angle = 2*pi - angle; }
else if(vx < 0 && vy > 0){ angle = pi - angle; }
else if(vx < 0 && vy < 0){ angle = pi + angle; }
birds[i][3] = angle;// + eta*2*pi*Math.random(); }
}
var cosb = Math.cos( birds[i][3] );
var sinb = Math.sin( birds[i][3] );
birds[i][0] = (birds[i][0] + dt*birds[i][2] * cosb );
if(birds[i][0] > size ){ birds[i][0] = birds[i][0] % size; }
else if(birds[i][0] < 0 ){ birds[i][0] = (size + birds[i][0]) % size; }
birds[i][1] = (birds[i][1] + dt*birds[i][2] * sinb );
if(birds[i][1] > size ){ birds[i][1] = birds[i][1] % size; }
else if(birds[i][1] < 0 ){ birds[i][1] = (size + birds[i][1]) % size; }
}
for(var i=0; i<Ndots; i++){
var cosb = Math.cos( dots[i][3] );
var sinb = Math.sin( dots[i][3] );
dots[i][0] = (dots[i][0] + dt*dots[i][2] * cosb );
if(dots[i][0] > size ){ dots[i][0] = dots[i][0] % size; }
else if(dots[i][0] < 0 ){ dots[i][0] = (size + dots[i][0]) % size; }
dots[i][1] = (dots[i][1] + dt*dots[i][2] * sinb );
if(dots[i][1] > size ){ dots[i][1] = dots[i][1] % size; }
else if(dots[i][1] < 0 ){ dots[i][1] = (size + dots[i][1]) % size; }
}
}
function animate_birds(runAnimation, canvas, context) {
if(runAnimation.value) {
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
draw_birds();
draw_dots();
inc_birds();
//runAnimation.value = false;
}
setTimeout(function() {
requestAnimFrame(function() {
animate_birds( runAnimation, canvas, context);
});
}, 0);
}
function mup(evt){
var rect = canvas.getBoundingClientRect();
var ix = evt.clientX - rect.left;
var iy = evt.clientY - rect.top;
if( Ndots < Ndots_max){
dots[Ndots][0] = ix;
dots[Ndots][1] = iy;
dots[Ndots][2] = v0;
dots[Ndots][3] = 2 * pi * Math.random();
Ndots++;
}
else{
for(i=1; i<Ndots; i++){
dots[i-1][0] = dots[i][0];
dots[i-1][1] = dots[i][1];
dots[i-1][2] = dots[i][2];
dots[i-1][3] = dots[i][3];
}
dots[Ndots-1][0] = ix;
dots[Ndots-1][1] = iy;
dots[Ndots-1][2] = v0; //dot_rad;
dots[Ndots-1][3] = 2 * pi * Math.random();
}
}
function init_birds(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(0,0);
context.font="italic 15px Helvetica";
canvas.addEventListener('mouseup', mup, false);
animate_birds(runAnimation, canvas, context);
}
$(function() {
$( "#SliderN" ).slider({
value: N,
min: 1,
max: 600,
step: 1,
slide: function( event, ui ) {
setTimeout(function() {
runAnimation.value = false;
N = $('#SliderN').slider("value");
restart();
runAnimation.value = true;
},0);
$( "#amountn" ).val( ui.value );
}
});
$( "#amountn" ).val( $( "#SliderN" ).slider( "value" ) );
});
</script>
</head>
<body onLoad="init_birds();">
<p>
Flocks of birds are an interesting example of complex dynamics arising from individual agents interacting without
a central controller. Computer models of flocks begin with <a href="http://www.red3d.com/cwr/boids/">boids</a> and get
more and more complicated. Here I made a program to run a simple model called the <a href="http://web.mit.edu/8.334/www/grades/projects/projects10/Hernandez-Lopez-Rogelio/dynamics_2.html">Viscek Model</a>. The rules are that every bird (drawn as an arrow) tries to fly in the average direction that all his neighbours are flying. There is a certain radius that each bird can see and a certain amount of randomness in the steering.
</p>
<p>
I also added a different kind of bird species that the birds do their best to avoid, drawn as dots, call them planes. If a bird is approaching a plane it tries to steer away from it, while also staying in the flock. The closer a bird is to a plane the more the plane affects the direction of the bird. Click the screen to make a plane appear. Notice that the flocks get denser with the planes flying around, similarly to predators chasing real herds, or dogs rounding up goats.
</p>
<div id="BirdContainer" style="width: 600px">
<div id="Bird" style="float: left;">
<canvas id="canvas" width="512" height="512"></canvas>
</div>
<div id="Damplab" style="margin-left: 25px; margin-top: 10px; width: 550px;float: left;">
<div id="lab" style="width: 150px; margin-right: 0px; float: left;"><label for="amountn"">Number of birds: </label></div>
<input type="text" id="amountn" style="border: 0px; margin: 0px; color: red; font-weight: bold; width: 25px; float: left;">
<div id="SliderN" style="width: 250px; margin-left: 25px; float: left;"></div>
</div>
<INPUT TYPE="button" NAME="rand_button" Value="random" onClick="restart()" style=" margin-top: 10px; margin-left: 25px; float: left;">
</div>
</body>
</html>
Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-33736314307936255492014-06-21T13:31:00.001-07:002014-06-21T14:58:19.745-07:00Pong (Expert Mode)<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>pong expert mode</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function drawdot_t(ctx,x,y,r,fs, al){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.globalAlpha = al;
ctx.fillStyle=fs;
ctx.fill();
ctx.globalAlpha = 1;
}
var canvas;
var context;
var size = 300;
var runAnimation = {value: true};
var shw = 35;
var shh = 35;
var vmag_init = 5.0;
var score1 = [0,0,0]; var s1=0;
var score2 = [0,0,0]; var s2=0;
var paddle_h = 40; var paddle_h2 = 20;
var paddle_w = 20; var paddle_w2 = 10;
var dt = 1;
var t = 0;
var p1y = size/2; var p1x = paddle_w*1.5
var p2y = size/2; var p2x = size - paddle_w*1.5
var vp1 = 0;
var fps = 1000 / 60;
var boxw = 5;
var boxh = 5;
var zero = [1, 1, 1, 1,0,1, 1,0,1, 1,0,1, 1, 1, 1];
var one = [0, 0, 1, 0,0,1, 0,0,1, 0,0,1, 0, 0, 1];
var two = [1, 1, 1, 0,0,1, 1,1,1, 1,0,0, 1, 1, 1];
var three =[1, 1, 1, 0,0,1, 1,1,1, 0,0,1, 1, 1, 1];
var four = [1, 0, 1, 1,0,1, 1,1,1, 0,0,1, 0, 0, 1];
var five = [1, 1, 1, 1,0,0, 1,1,1, 0,0,1, 1, 1, 1];
var six = [1, 1, 1, 1,0,0, 1,1,1, 1,0,1, 1, 1, 1];
var seven =[1, 1, 1, 1,0,1, 0,0,1, 0,0,1, 0, 0, 1];
var eight =[1, 1, 1, 1,0,1, 1,1,1, 1,0,1, 1, 1, 1];
var nine = [1, 1, 1, 1,0,1, 1,1,1, 0,0,1, 1, 1, 1];
var digits = [zero, one, two, three, four, five, six, seven, eight, nine]
var ncol = 6;
var col = new Array(ncol);
col[0] = "red";
col[1] = "green";
col[2] = "blue";
col[3] = "fuchsia";
col[4] = "aqua";
col[5] = "orange";
function draw_digit( dig, loc ){
context.fillStyle = "white";
for(var i=0; i<15; i++){
var j = i%3;
var k = Math.floor(i/3);
if(dig[i] != 0) context.fillRect( loc + j*boxw, paddle_w + k*boxh ,boxw,boxh);
}
}
function PBall (xp, yp, xv, yv, r, col) {
this.xp = xp;
this.yp = yp;
this.xv = xv;
this.yv = yv;
this.r = r;
this.col = col;
this.spec = false;
}
PBall.prototype.draw = function() {
drawdot(context, this.xp, this.yp, this.r, this.col);
};
PBall.prototype.advance = function(time) {
this.xp += this.xv*time;
this.yp += this.yv*time;
};
var nballs_min = 10;
var nballs_max = 20;
var nactive = nballs_min;
var ball = new Array(nballs_max);
var active = new Array(nballs_max);
for(var i=0; i<nballs_max; i++){ active[i] = false; }
for(var i=0; i<nactive; i++){ active[i] = true; }
for(var i=0; i<nballs_max; i++){ ball[i] = new PBall( size/2, size/2,
-vmag_init + vmag_init*(-1.0 + 2.0*Math.random())/2, 2*vmag_init*(-1.0 + 2.0*Math.random()),
4 + Math.round(6*Math.random()), col[ Math.floor(ncol*Math.random()) ] );
}
ball[0] = new PBall( size/2, size/2, -vmag_init, 0, 3, "yellow" ); ball[0].spec = true;
//ball[0] = new PBall( 1.5*paddle_w, paddle_h, 0, -vmag_init, "blue" );
//ball[0] = new PBall( size/4, 3*size/4, vmag_init,-vmag_init, "red" );
//ball[1] = new PBall( 3*size/4, size/4, -vmag_init,vmag_init, "blue" );
function draw_score(){
draw_digit(digits[ score1[2] ], size/2-paddle_h);
draw_digit(digits[ score1[1] ], size/2-1.5*paddle_h);
draw_digit(digits[ score1[0] ], size/2-2*paddle_h);
draw_digit(digits[ score2[0] ], size/2+paddle_h/2);
draw_digit(digits[ score2[1] ], size/2+2*paddle_h/2);
draw_digit(digits[ score2[2] ], size/2+3*paddle_h/2);
}
function draw_pong(base, x){
context.fillStyle = "white";
context.fillRect(-12,-12,size+24,size+24);
context.fillStyle = "black";
context.fillRect(0,0,size,size);
context.beginPath();
context.strokeStyle = "white";
context.moveTo(size/2, 0);
context.lineTo(size/2, size);
context.stroke();
context.fillStyle = "white";
context.fillRect( paddle_w ,p1y - (paddle_h/2),paddle_w,paddle_h); //left paddle
//context.fillRect(size-2*paddle_w,p2y - (paddle_h/2),paddle_w,paddle_h); //right paddle
context.strokeStyle = "black";
context.strokeRect(0,0,size,size);
for(var i=0; i<nballs_max; i++){ if(active[i]){ball[i].draw();} }
draw_score();
}
function collision(i, paddle){
var px;
var py;
var sign;
if( paddle == 1 ){
if( ball[i].xv > 0 ){ return false; }
px = p1x;
py = p1y;
sign = -1;
} else {
if( ball[i].xv < 0 ){ return false; }
px = p2x;
py = p2y;
sign = 1;
}
var xdiff = Math.abs(ball[i].xp - px) - ball[i].r - paddle_w2;
if( xdiff < sign*ball[i].xv){
var ydiff = Math.abs( ball[i].yp - p1y ) - ball[i].r - paddle_h2;
if(ydiff <= Math.abs(ball[i].yv) ){
var xtau = Math.abs( xdiff / ball[i].xv );
var ytau = Math.abs( ydiff / ball[i].yv );
if( xtau < ytau ){
ball[i].advance(xtau);
xtau = 1-xtau;
ball[i].xv *= -1;
ball[i].advance(xtau);
} else {
ball[i].advance(ytau);
ytau = 1-ytau;
if( ( (ball[i].yp - py) > 0 && ball[i].yv < 0) ||
( (ball[i].yp - py) < 0 && ball[i].yv > 0) ){
ball[i].yv *= -1;
}
ball[i].advance(ytau);
}
if( ball[i].spec && nactive < nballs_max ){
//console.log(nactive, nballs_max);
for(var k=1; k<nballs_max; k++){
if(!active[k]){
active[k] = true;
ball[k].xp = ball[i].xp;
ball[k].yp = ball[i].yp;
ball[k].xv = vmag_init*(-1.0 + 2.0*Math.random());
ball[k].yv = vmag_init*(-1.0 + 2.0*Math.random());
ball[k].spec = false;
ball[k].col = "yellow"
ball[k].r = 3;
}
}
nactive = nballs_max;
//console.log(nactive, nballs_max);
}
return true;
}
}
return false;
}
function ball_collision(i){
for(var j=0; j<nballs_max; j++){
if(j!=i){
var xprel = ball[i].xp - ball[j].xp;
var yprel = ball[i].yp - ball[j].yp;
var xvrel = ball[j].xv - ball[i].xv;
var yvrel = ball[j].yv - ball[i].yv;
var d2 = xprel*xprel + yprel*yprel; var d = Math.sqrt(d2);
var v2 = xvrel*xvrel + yvrel*yvrel; var v = Math.sqrt(v2);
var rsum = ball[i].r + ball[j].r;
if( d - rsum <= v && d > rsum ){
var dot = xprel*xvrel + yprel*yvrel;
if( dot>=0 ){
var e2 = dot*dot/v2;
var f2 = d2 - e2;
if( f2 <= rsum*rsum ){
var t2 = rsum*rsum - f2;
var tau = (Math.sqrt(e2) - Math.sqrt( t2 )) /v;
if( tau < 1 ){
ball[i].xp += ball[i].xv * tau;
ball[i].yp += ball[i].yv * tau;
ball[j].xp += ball[j].xv * tau;
ball[j].yp += ball[j].yv * tau;
tau = 1-tau;
proj = dot / d2;
ball[i].xv += proj * xprel;
ball[i].yv += proj * yprel;
ball[i].xp += ball[i].xv * tau;
ball[i].yp += ball[i].yv * tau;
proj = dot / d2;
ball[j].xv -= proj * xprel;
ball[j].yv -= proj * yprel;
ball[j].xp += ball[j].xv * tau;
ball[j].yp += ball[j].yv * tau;
return true;
}
}
}
}
}
}
return false;
}
function countn(){
var sum = 0;
for(var i=0; i<nballs_max; i++){ if(active[i]) sum++; }
return sum;
}
function animate_pong(runAnimation, canvas, context) {
t = 0;
if(runAnimation.value) {
for(var i=0; i<nballs_max; i++){
if(active[i]){
//console.log(i, ball[i].xp, ball[i].yp);
p2y = ball[i].yp;
//p1y = ball[i].yp;
if( !collision(i, 1) ){
if( !ball_collision(i) ){ ball[i].advance(dt); }
}
if(ball[i].yp < ball[i].r){ball[i].yv *= -1; ball[i].yp = ball[i].r;}
if(ball[i].yp > size - ball[i].r){ball[i].yv *= -1; ball[i].yp = size-ball[i].r;}
if( ball[i].xp <= 0 ){
if(ball[i].col == "yellow" &&nactive > nballs_min){
active[i] = false; nactive--;
}
else{
ball[i].xv = -vmag_init;
ball[i].xp = size/2;
ball[i].yp = size/2;
ball[i].xv = -vmag_init + vmag_init*(-1.0 + 2.0*Math.random())/2
ball[i].yv = 2*vmag_init*(-1.0 + 2.0*Math.random());
ball[i].r = 4 + Math.round(6*Math.random());
ball[i].col = col[ Math.floor(ncol*Math.random()) ];
ball[i].spec = false;
if(Math.random() < 0.1){
ball[i].col = "yellow";
ball[i].r = 3;
ball[i].spec = true;
ball[i].xv = -vmag_init;
ball[i].yv = 0;
}
}
//console.log(nactive);
if(ball[i].col != "yellow"){ s2+=10-ball[i].r; } if(s2 > 999){ s1 = 0; s2 = 0;
score2[2] = 0; score2[1] = 0; score2[0] = 0;}
var ts = s2;
score2[2] = ts%10;
ts -= score2[2]; ts /= 10;
score2[1] = ts%10;
ts -= score2[1]; ts /= 10;
score2[0] = ts%10;
}
if( ball[i].xp >= size - ball[i].r ){
if(ball[i].col != "yellow"){ s1+=10-ball[i].r; } if(s1 > 999){ s1 = 0; s2 = 0;
score1[2] = 0; score1[1] = 0; score1[0] = 0;}
var ts = s1;
score1[2] = ts%10;
ts -= score1[2]; ts /= 10;
score1[1] = ts%10;
ts -= score1[1]; ts /= 10;
score1[0] = ts%10;
}
if(ball[i].xp >= size - ball[i].r && ball[i].xv > 0){ball[i].xv *= -1; }
//if(ball[i].xp <= 0 ){ball[i].xv *= -1; ball[i].t++;}
}
}
draw_pong();
}
setTimeout(function() {
requestAnimFrame(function() {
animate_pong( runAnimation, canvas, context);
});
}, t);
}
function mmove(evt){
var rect = canvas.getBoundingClientRect();
var np1y = evt.clientY - rect.top - shh
if(np1y < paddle_h2){np1y = paddle_h2;}
if(np1y > size - paddle_h2){np1y = size - paddle_h2;}
var vp1 = (np1y - p1y);
for(var i=0; i<nballs_max; i++){
if(active[i]){
if( ball[i].xp + ball[i].r < p1x + paddle_w2 && ball[i].xp - ball[i].r > p1x - paddle_w2 ){
var ydiff = Math.abs( ball[i].yp - p1y ) - ball[i].r - paddle_h2;
if(ydiff <= Math.abs(vp1 - ball[i].yv) ){
var ytau = Math.abs( ydiff / (vp1 - ball[i].yv) );
if( np1y > p1y && ball[i].yp > p1y){ ball[i].yp = np1y + paddle_h2; }
if( np1y < p1y && ball[i].yp < p1y){ ball[i].yp = np1y - paddle_h2; }
}
}
}
}
p1y = np1y;
}
/*function mmove(evt){
var rect = canvas.getBoundingClientRect();
var np1y = evt.clientY - rect.top - shh
if(np1y < paddle_h/2){np1y = paddle_h/2;}
if(np1y > size - paddle_h/2){np1y = size - paddle_h/2;}
p1y = np1y;
}*/
function pause(evt){
runAnimation.value = !runAnimation.value;
}
function init_pong(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(shw, shh);
context.font="italic 15px Helvetica";
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mousedown', pause, false);
draw_pong();
runAnimation.value = false;
animate_pong( runAnimation, canvas, context);
}
</script>
</head>
<body onLoad="init_pong();">
<p>
Since pong was invented, games have become a lot more difficult. If you have mastered the 70s version try this. More points
for the smaller ones, colour is irrelevant except yellows sometimes explode and don't give any points.
</p>
<div id="pongContainer" style="width: 700px">
<div id="pong" style="float: left;">
<canvas id="canvas" width="700" height="700"></canvas>
</div>
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-56809632421599273352014-06-17T10:03:00.003-07:002014-06-21T13:28:06.020-07:00Pong<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>pong</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawpoint(ctx,x,y,fs){
ctx.beginPath();
ctx.arc(x,y,1,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function drawdot_t(ctx,x,y,r,fs, al){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.globalAlpha = al;
ctx.fillStyle=fs;
ctx.fill();
ctx.globalAlpha = 1;
}
</script>
<script type="text/javascript">
var canvas;
var context;
var size = 300;
var runAnimation = {value: true};
var shw = 35;
var shh = 35;
var nsweep = 40;
var sweep = new Array(nsweep);
for(var i=0; i<nsweep; i++){sweep[i] = new Array(2); sweep[i][0] = size/2; sweep[i][1] = size/2;}
var ballx = size/2;
var bally = size/2;
var vmag_init = 3.0;
var vmag = vmag_init;
var vx = -vmag;
var vy = vmag_init*(-1 + 2*Math.random());
var score1 = 0;
var score2 = 0;
var ball_size = 5;
var paddle_h = 40;
var paddle_w = 20;
var dt = 1;
var p1y = size/2; vp1 = 0;
var p2y = size/2; vp2 = 0;
var pw = 5;
var fuzz = 0.1;
var boxw = 5;
var boxh = 5;
var zero = [1, 1, 1, 1,0,1, 1,0,1, 1,0,1, 1, 1, 1];
var one = [0, 0, 1, 0,0,1, 0,0,1, 0,0,1, 0, 0, 1];
var two = [1, 1, 1, 0,0,1, 1,1,1, 1,0,0, 1, 1, 1];
var three =[1, 1, 1, 0,0,1, 1,1,1, 0,0,1, 1, 1, 1];
var four = [1, 0, 1, 1,0,1, 1,1,1, 0,0,1, 0, 0, 1];
var five = [1, 1, 1, 1,0,0, 1,1,1, 0,0,1, 1, 1, 1];
var six = [1, 1, 1, 1,0,0, 1,1,1, 1,0,1, 1, 1, 1];
var seven =[1, 1, 1, 1,0,1, 0,0,1, 0,0,1, 0, 0, 1];
var eight =[1, 1, 1, 1,0,1, 1,1,1, 1,0,1, 1, 1, 1];
var nine = [1, 1, 1, 1,0,1, 1,1,1, 0,0,1, 1, 1, 1];
var digits = [zero, one, two, three, four, five, six, seven, eight, nine]
function draw_digit( dig, loc ){
context.fillStyle = "white";
for(var i=0; i<15; i++){
var j = i%3;
var k = Math.floor(i/3);
if(dig[i] != 0) context.fillRect( loc + j*boxw, paddle_w + k*boxh ,boxw,boxh);
}
}
function draw_pong(base, x){
context.fillStyle = "black";
context.fillRect(0,0,size,size);
context.beginPath();
context.strokeStyle = "white";
context.moveTo(size/2, 0);
context.lineTo(size/2, size);
context.stroke();
context.fillStyle = "white";
context.fillRect( paddle_w ,p1y - (paddle_h/2),paddle_w,paddle_h); //left paddle
context.fillRect(size-2*paddle_w,p2y - (paddle_h/2),paddle_w,paddle_h); //right paddle
context.strokeStyle = "black";
context.strokeRect(0,0,size,size);
draw_digit(digits[score1], size/2-paddle_h);
draw_digit(digits[score2], size/2+paddle_h/2);
drawdot(context,ballx, bally, ball_size, "white");
//context.drawImage(image01,ballx, bally);
}
function draw_sweep(it){
for(var i=0; i<it; i++){
drawdot_t(context,sweep[i][0],sweep[i][1],ball_size,"white", (i + 1.0)/it );
}
}
function clean_sweep(it){
for(var i=0; i<it; i++){
sweep[i][0] = size/2; sweep[i][1] = size/2;
}
}
function random_sign(){
return -1 + Math.round(Math.random()) * 2
}
var t = 0;
var count=0;
var vmax = 5.0;
var acc = 0.05;
var nogo = false;
var nogor = false;
function animate_pong(runAnimation, canvas, context) {
t = 0;
if(runAnimation.value) {
if(count < nsweep){
sweep[count][0] = ballx;
sweep[count][1] = bally;
} else {
for(var i=1; i<nsweep; i++){
sweep[i-1][0] = sweep[i][0];
sweep[i-1][1] = sweep[i][1];
}
sweep[nsweep-1][0] = ballx; sweep[nsweep-1][1] = bally;
}
if( ballx <= 2*paddle_w && ballx > paddle_w && !nogo){
var sign = 1;
if( bally - p1y < 0 )sign = -1;
if( Math.abs(bally - p1y) <= paddle_h/2 ){
if( ballx >= 2*paddle_w - ball_size ){ //hit the front
//console.log("ballx = %d", ballx);
if(vmag < vmax)vmag += acc;
vx = vmag;
var diff= Math.abs(bally - p2y);
if( diff < paddle_h/8 ){ vy += 0; }
else if( diff < paddle_h/4 ){ vy += 0.25*vmag*sign; }
else if( diff < 3*paddle_h/8 ){ vy += 0.5*vmag*sign; }
else{ vy += 0.75*vmag*sign; }
} else {
//console.log("ball_x here = %d", ballx);
if(vmag < vmax)vmag += acc;
vx = vmag;
vy += vmag*sign;
//vy *= sign;
nogo = true;
}
}
}
else if( ballx <= 0 ){
//console.log("bally = %d px [%d, %d]", bally,p1y -paddle_h/2 ,p1y +paddle_h/2);
ballx = size/2;
bally = size/2; clean_sweep(nsweep); count = 0;
vx = vmag_init;
vy = vmag_init*(-1.0 + 2.0*Math.random());
vmag = vmag_init;
//t=1000;
score2++;
}
if(ballx > 2*paddle_w){nogo = false; }
if(ballx >= size - 2*paddle_w && ballx < size - paddle_w && !nogor){
var sign = 1;
if( bally - p2y < 0 )sign = -1;
if(Math.abs(bally - p2y) <= paddle_h/2){
if(ballx >= size - 2*paddle_w + ball_size ){
if(vmag < vmax)vmag += acc;
vx = -vmag;
var diff= Math.abs(bally - p2y);
if( diff < paddle_h/8 ){ vy += 0; }
else if( diff < paddle_h/4 ){ vy += 0.25*vmag*sign; }
else if( diff < 3*paddle_h/8 ){ vy += 0.5*vmag*sign; }
else{ vy += 0.75*vmag*sign; }
} else {
if(vmag < vmax)vmag += acc;
vx = -vmag;
vy += vmag*sign;
nogor = true;
}
}
}
else if( ballx >= size){
//console.log("bally = %d px [%d, %d]", bally,p2y -paddle_h/2 ,p2y +paddle_h/2);
ballx = size/2;
bally = size/2; clean_sweep(nsweep); count = 0;
vx = -vmag_init;
vy = vmag_init*(-1.0 + 2.0*Math.random());
vmag = vmag_init;
//t=1000;
score1++;
}
if(ballx < size - 2*paddle_w){nogor = false; }
if(bally <= ball_size ){vy = -vy;}
if(bally >= size - ball_size){vy = -vy;}
if(score1 > 9 || score2 > 9){ score1 = 0; score2 = 0; }
//if(ballx <= ball_size ){vx = -vx;}
//if(ballx >= size - ball_size){vx = -vx;}
draw_pong();
if(count < nsweep ){ draw_sweep(count); }
else{ draw_sweep(nsweep); }
ballx += vx * dt;
bally += vy * dt;
var nlag = 3;
if(count > nsweep - nlag){
p2y = sweep[nsweep - nlag][1];
if(p2y - paddle_h/2 < 0){ p2y = paddle_h/2; }
if(p2y + paddle_h/2 > size){ p2y = size - paddle_h/2; }
} else {
p2y = bally;
}
count++;
}
setTimeout(function() {
requestAnimFrame(function() {
animate_pong( runAnimation, canvas, context);
});
}, t);
}
function pause(evt){
runAnimation.value = !runAnimation.value;
}
function mmove(evt){
var rect = canvas.getBoundingClientRect();
var np1y = evt.clientY - rect.top - shh
if(np1y < paddle_h/2){np1y = paddle_h/2;}
if(np1y > size - paddle_h/2){np1y = size - paddle_h/2;}
vp1 = (np1y - p1y)/dt;
p1y = np1y;
}
function init_pong(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(shw, shh);
context.font="italic 15px Helvetica";
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mousedown', pause, false);
draw_pong();
runAnimation.value = false;
animate_pong( runAnimation, canvas, context);
}
</script>
</head>
<body onLoad="init_pong();">
<p>
Pong is the first, and most boring, video game. Play tetris instead.
</p>
<div id="pongContainer" style="width: 700px">
<div id="pong" style="float: left;">
<canvas id="canvas" width="700" height="700"></canvas>
</div>
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-72106805173230267482014-04-15T05:25:00.003-07:002014-04-15T05:28:05.933-07:00Almond Bread<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Mandlebrot</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawpoint(ctx,x,y,fs){
ctx.beginPath();
ctx.arc(x,y,1,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function drawdot_t(ctx,x,y,r,fs, al){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.globalAlpha = al;
ctx.fillStyle=fs;
ctx.fill();
ctx.globalAlpha = 1;
}
</script>
<script type="text/javascript">
var canvas;
var context;
var imageData;
var size = 512;
var runAnimation = {value: false};
var shw = 35;
var shh = 5;
var mar = new Array(size);
for(var i = 0; i < size; i++ ){
mar[i] = new Array(size);
for(var j = 0; j< size; j++ ){
mar[i][j] = 0;
}
}
var ix, iy;
var gx, gy;
var scale = 1/size;
var xc_min = -2.0;
var xc_max = 1.0;
var yc_min = -1.5;
var yc_max = 1.5;
var xposl = -2.0;
var xposr = 1.0;
var yposl = -1.5;
var yposr = 1.5;
var max_iteration = 1000
var bail = 4;
var ln2 = Math.log(2)
var escape_time = true;
function colour_pixel(imageData, x,y, it){
var index = (x + y * imageData.width) * 4;
if(it == max_iteration){
imageData.data[index+0] = 0;
imageData.data[index+1] = 0;
imageData.data[index+2] = 0;
imageData.data[index+3] = 255;
}
else {
col = Math.round( 255 * Math.log(it)/ Math.log(max_iteration-1) );
//col = Math.round( 255 * (it)/ (max_iteration-1) );
imageData.data[index+0] = 255 - col;
imageData.data[index+1] = 255 - col;
imageData.data[index+2] = 255;
imageData.data[index+3] = 255;
}
}
function draw_almond(){
remove_event_listeners();
context.clearRect(0,0,size,size);
var xinc = (xc_max - xc_min) / size;
var yinc = (yc_max - yc_min) / size;
var pixx = 0;
for(var x = xc_min; pixx < size; x += xinc){
var pixy = 0;
//console.log("%f", x);
for(var y = yc_min; pixy < size; y += yinc){
var iteration = 0
var xt = x + 0.5*xinc;
var yt = y + 0.5*yinc;
while ( xt*xt + yt*yt < bail && iteration < max_iteration ){
var xtemp = xt*xt - yt*yt + x
var ytemp = 2*xt*yt + y
if(xt == xtemp && y == ytemp){
iteration = max_iteration;
break;
}
xt = xtemp;
yt = ytemp;
iteration++;
}
if ( !escape_time && iteration < max_iteration ) {
var zn = xt*xt + yt*yt;
var nu = Math.log( 0.5*Math.log(zn) / ln2 ) / ln2;
iteration = iteration + 1 - nu
}
colour_pixel( imageData, pixx, pixy, iteration);// Math.round( 255*(iteration/max_iteration) ) );
mar[pixx][pixy] = iteration; //Math.round(255*iteration/max_iteration);
pixy++;
}
pixx++;
}
context.putImageData(imageData, shw, shh);
canvas.addEventListener('mousedown', mdown, false);
}
function redraw_almond(){
for(var i = 0; i < size; i++ ){
for(var j = 0; j< size; j++ ){
colour_pixel( imageData, i, j, mar[i][j]);
}
}
context.putImageData(imageData, shw, shh);
}
function remove_event_listeners(){
canvas.removeEventListener('mousemove', mmove);
canvas.removeEventListener('mousedown', mdown);
canvas.removeEventListener('mouseup', mup);
}
function mdown(evt){
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mouseup', mup, false);
var rect = canvas.getBoundingClientRect();
ix = evt.clientX - rect.left - shw
iy = evt.clientY - rect.top - shh
//console.log("init pos %d %d", ix, iy);
}
function mmove(evt){
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
redraw_almond();
var rect = canvas.getBoundingClientRect();
gx = evt.clientX - rect.left - shw
gy = evt.clientY - rect.top - shh
var dw = (gx - ix);
var dl = dw; //(gy - iy);
if(ix + dw > size-1 || iy + dl > size-1 || ix + dw < 1 || iy + dl < 1){
//console.log("here %d %d", ix, iy);
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
remove_event_listeners();
canvas.addEventListener('mousedown', mdown, false);
draw_almond();
} else {
xposl = xc_min + (xc_max - xc_min)*ix*scale; yposl = yc_min + (yc_max - yc_min)*iy*scale;
xposr = xc_min + (xc_max - xc_min)*gx*scale, yposr = yc_min + (yc_max - yc_min)*gy*scale;
/*console.log("base %f %f %f %f", xc_min, xc_max, yc_min, yc_max);
console.log("pos %f %f %f %f", xposl, xposr, yposl, yposr);
console.log("pos %f %f %f %f", ix, gx, iy, gy);
console.log("pos %f %f %f %f",
Math.round(size*(xposl - xc_min)/(xc_max - xc_min) ), Math.round(size*(xposr - xc_min)/(xc_max - xc_min) ),
Math.round(size*(yposl - yc_min)/(yc_max - yc_min) ), Math.round(size*(yposr - yc_min)/(yc_max - yc_min) ) );*/
context.strokeStyle = "red";
context.strokeRect(ix,iy,dw,dl);
context.strokeStyle = "black";
}
}
function mup(evt){
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
xc_min = xc_min + (xc_max - xc_min)*Math.min(ix,gx)*scale;
xc_max = xc_min + (xc_max - xc_min)*Math.max(ix,gx)*scale;
yc_min = yc_min + (yc_max - yc_min)*Math.min(iy,gy)*scale;
yc_max = yc_min + (yc_max - yc_min)*Math.max(iy,gy)*scale;
draw_almond();
context.strokeRect(0,0,size,size);
}
function init_box(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(shw, shh);
context.font="italic 15px Helvetica";
imageData = context.createImageData(size, size);
context.strokeRect(0,0,size,size);
draw_almond();
canvas.addEventListener('mousedown', mdown, false);
}
$(function() {
$( "#SliderR" ).slider({
value: max_iteration,
min: 1,
max: 5000,
step: 1,
slide: function( event, ui ) {
setTimeout( function() {
runAnimation.value = false;
max_iteration = $('#SliderR').slider("value");
draw_almond();
},0);
$( "#amountR" ).val( ui.value );
}
});
$( "#amountR" ).val( $( "#SliderR" ).slider( "value" ) );
});
function reset_params(){
scale = 1/size;
xc_min = -2.0;
xc_max = 1.0;
yc_min = -1.5;
yc_max = 1.5;
xposl = -2.0;
xposr = 1.0;
yposl = -1.5;
yposr = 1.5;
context.strokeRect(0,0,size,size);
draw_almond();
}
function change_algo(){
escape_time = !escape_time;
if(escape_time){ bail = 4; }
else{ bail = Math.pow(2,16); }
context.strokeRect(0,0,size,size);
draw_almond();
}
</script>
</head>
<body onLoad="init_box();">
<p>
The Mandlebrot set is a (very important) fractal. A fractal is basically a shape containing smaller copies
of itself <i>ad infinitum</i>, usually generated by repeating some simple rule. For the Mandlebrot set the rule is:
for every complex number $c$ repeat the operation
\[z_{n+1} = z_n^2 + c\]
if the size of $z_n$ doesn't tend to infinity then $c$ is in the set, otherwise it isn't. Of course
if we ask a computer to do the iterations we can only ask it to do a finite number. We colour the point
differently depending on how many iterations it takes to discover if the number is in the set or not up to
some number $N$. If we reach $N$ without diverging then we colour the point black and say, to the best of
our knowledge, the point is in the set.
</p><p>
There is a lot of fancy maths in this area, but I think that people mainly like making cool pictures, me included. So
here is a Mandlebrot set for you to zoom in on. Try and find something nice by clicking on the picture and dragging the red box, look at the edges for interesting swirls. This will go very slowly for a large number of iterations $N$, so be careful you don't put it too high and crash your browser.
</p>
<div id="BoxContainer" style="width: 550px; margin-left: 0px">
<div id="Box" style="float: left;">
<canvas id="canvas" width="550" height="550"></canvas>
</div>
<div id="Nlab" style="width: 100px; margin-left: 35px; float: left;">
<label for="amountR">N: </label>
<input type="text" id="amountR" style="border: 0px; margin: 0px; color: red; font-weight: bold; width: 69px; ">
</div>
<div id="SliderR" style="width: 150px; margin-left: 0px; float: left;"></div>
<div class="input" style="margin-left: 30px; float: left;">
<INPUT TYPE="button" NAME="Reset" Value="Reset" onClick="reset_params()">
</div>
<div class="input" style="margin-left: 0px; float: left;">
<INPUT TYPE="button" NAME="Smoothing" Value="Smoothing" onClick="change_algo()">
</div>
</div>
</body>
</html>
Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-74418389472366983202013-12-18T13:21:00.000-08:002014-07-30T00:00:49.183-07:00Spring Time<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>SpringTime</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 0);//1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawpoint(ctx,x,y,fs){
ctx.beginPath();
ctx.arc(x,y,1,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function drawdot_t(ctx,x,y,r,fs, al){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.globalAlpha = al;
ctx.fillStyle=fs;
ctx.fill();
ctx.globalAlpha = 1;
}
</script>
<script type="text/javascript">
var canvas;
var context;
var size = 400;
var shw=35;
var shh=35;
//var L = size-100;
var N = 6;
var NN = N*N;
var runAnimation = {value: false};
var pos = new Array( N+1 ); for(var i=0;i<N+1;i++){ pos[i] = new Array(N+1); for(var j=0; j<N+1; j++){ pos[i][j] = new Array(2); } }
var vel = new Array( N+1 ); for(var i=0;i<N+1;i++){ vel[i] = new Array(N+1); for(var j=0; j<N+1; j++){ vel[i][j] = new Array(2); } }
var acc = new Array( N+1 ); for(var i=0;i<N+1;i++){ acc[i] = new Array(N+1); for(var j=0; j<N+1; j++){ acc[i][j] = new Array(2); } }
var tmp_acc = new Array( N+1 ); for(var i=0;i<N+1;i++){tmp_acc[i] = new Array(N+1); for(var j=0; j<N+1; j++){tmp_acc[i][j] = new Array(2); } }
var t = 0;
var alpha = 0.0; //cubic term in potential
var beta = 500 //x^4
var k = 1; //x^2
var dt = 0.1;
var dt2 = dt*dt;
//given initial start and end points
function draw_spring( xi, yi, xf, yf, Nw, h){
context.save();
drawdot(context,xi,yi,4,"red")
drawdot(context,xf,yf,4,"red")
var len = Math.sqrt( (xf-xi)*(xf-xi) + (yf-yi)*(yf-yi) );
var w2 = len/Nw;
var w = w2*0.5;
var rat = (yf-yi)/(xf-xi);
var ang = Math.atan( Math.abs(rat) );
if(rat < 0){
if(yf>yi){ ang = Math.PI - ang; }
else{ ang = 2*Math.PI - ang; }
}
else{
if(yf<yi){ ang = Math.PI + ang; }
}
context.translate(xi, yi);
context.beginPath();
context.rotate(ang);
var xs = 0;
var ys = 0;
context.moveTo(xs,ys);
for(var i=0; i<Nw/2; i++){
xs += w;
context.lineTo(xs,ys+h);
xs += w;
context.lineTo(xs,ys);
xs += w;
context.lineTo(xs,ys-h);
xs += w;
context.lineTo(xs,ys);
}
context.stroke();
//context.rotate(-ang);
//context.translate(-xi, -yi);
context.restore();
}
function draw_spring_grid( ){
context.clearRect(-shw,-shh,2*size,2*size);
context.strokeRect(0,0,size,size);
a = size/N;
for(var i=0; i<N; i++){
for(var j=0; j<N; j++){
draw_spring( pos[i][j][0]*size, pos[i][j][1]*size, pos[i][(j+1)][0]*size, pos[i][(j+1)][1]*size, 16, 10);
draw_spring( pos[i][j][0]*size, pos[i][j][1]*size, pos[i+1][j][0]*size, pos[i+1][j][1]*size, 16, 10);
}
draw_spring( pos[N][i][0]*size, pos[N][i][1]*size, pos[N][(i+1)][0]*size, pos[N][(i+1)][1]*size, 16, 10);
draw_spring( pos[i][N][0]*size, pos[i][N][1]*size, pos[(i+1)][N][0]*size, pos[i+1][N][1]*size, 16, 10);
}
}
function initialize(){
context.restore();
runAnimation.value = false;
var a = 1.0/N;
var wig = 0.2;
for(var i=0; i<N+1; i++){
for(var j=0; j<N+1; j++){
pos[i][j][0] = i*a; pos[i][j][1] = j*a;
vel[i][j][0] = 0; vel[i][j][1] = 0;
acc[i][j][0] = 0; acc[i][j][1] = 0;
tmp_acc[i][j][0] = 0; tmp_acc[i][j][1] = 0;
}}
for(var i=1; i<N; i++){
for(var j=1; j<N; j++){
pos[i][j][0] += a*wig*( -1 + 2*Math.random() );
pos[i][j][1] += a*wig*( -1 + 2*Math.random() );
}}
t = 0;
draw_spring_grid( );
}
function force(dx){
return k*dx+alpha*dx*dx+beta*dx*dx*dx;
}
function acceleration(ax) {
var j;
for(var i = 1; i<N; i++) {
for(var j = 1; j<N; j++) {
ax[i][j][0] = 0;
ax[i][j][1] = 0;
}}
for(var i = 1; i<N; i++) {
for(var j = 1; j<N; j++) {
var a = force( (pos[i][j+1][0]-pos[i][j][0]) );
ax[i][j][0] += a;
ax[i][j+1][0] -= a;
a = force( (pos[i+1][j][1]-pos[i][j][1]) );
ax[i][j][1] += a;
ax[i+1][j][1] -= a;
}}
}
function start_stop(){ runAnimation.value = !runAnimation.value }
function animate_grid(runAnimation, canvas, context) {
if(runAnimation.value) {
draw_spring_grid( );
acceleration(acc);
for(var i = 1; i<N; i++) {
for(var j = 1; j<N; j++) {
pos[i][j][0] += dt*vel[i][j][0]+dt2*acc[i][j][0]/2.0;
pos[i][j][1] += dt*vel[i][j][1]+dt2*acc[i][j][1]/2.0;
}}
acceleration(tmp_acc);
for(var i = 1; i<N; i++) {
for(var j = 1; j<N; j++) {
//if(acc[i][j][0] > 1e4){ runAnimation.value = false; }
vel[i][j][0] += dt*(acc[i][j][0]+tmp_acc[i][j][0])/2.0;
vel[i][j][1] += dt*(acc[i][j][1]+tmp_acc[i][j][1])/2.0;
}}
t += dt;
}
setTimeout(function() {
requestAnimFrame(function() {
animate_grid( runAnimation, canvas, context);
});
}, 1);
}
function remove_event_listeners(){
canvas.removeEventListener('mousemove', mmove);
canvas.removeEventListener('mousedown', mdown);
canvas.removeEventListener('mouseup', mup);
}
var ibest, jbest;
function mdown(evt){
runAnimation.value = false;
canvas.addEventListener('mousemove', mmove, false);
canvas.addEventListener('mouseup', mup, false);
var rect = canvas.getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
var rad = (size/N)*0.5;
var b = 0;
var imin = size;
var jmin = size;
for(var i=1; i<N; i++){
for(var j=1; j<N; j++){
it = Math.abs(tinitx - pos[i][j][0]*size);
jt = Math.abs(tinity - pos[i][j][1]*size);
if( it < imin ){
ibest = i;
imin = it;
}
if( jt < jmin ){
jbest = j;
jmin = jt;
}
}}
pos[ibest][jbest][0] = tinitx/size;
pos[ibest][jbest][1] = tinity/size;
draw_spring_grid( );
}
function mmove(evt){
var rect = canvas.getBoundingClientRect();
var tinitx = evt.clientX - rect.left - shw
var tinity = evt.clientY - rect.top - shh
pos[ibest][jbest][0] = tinitx/size;
pos[ibest][jbest][1] = tinity/size;
draw_spring_grid( );
}
function mup(evt){
remove_event_listeners();
canvas.addEventListener('mousedown', mdown, false);
//runAnimation.value = true;
}
function change_params(){
k = document.getElementById('kv').value;
alpha = document.getElementById('av').value;
beta = document.getElementById('bv').value;
runAnimation.value = true;
}
function init_spring(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
/* canvas.style.width='110%';
canvas.style.height='110%';
canvas.width = 1.5*canvas.offsetWidth;
size = canvas.width;
canvas.height = size;
shw = 0;//size*0.05;
shh = 0;//size*0.05;
console.log(canvas.width, canvas.height, size, shh);*/
context.translate(shw, shh);
context.strokeRect(0,0,size,size);
initialize();
canvas.addEventListener('mousedown', mdown, false);
animate_grid( runAnimation, canvas, context);
}
</script>
<style>
form {
margin:10px 0;
}
label {
color: #404040;
float: left;
font-size: 13px;
line-height: 18px;
padding-top: 6px;
text-align: right;
width: 130px;
}
label, input, button, select, textarea {
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 13px;
font-weight: normal;
line-height: normal;
}
input, textarea, button, select {
-moz-border-radius: 3px 3px 3px 3px;
border: 1px solid #CCCCCC;
color: #808080;
display: inline-block;
font-size: 13px;
height: 30px;
line-height: 18px;
padding: 0px;
width: 200px;
}
input, textarea, button, select {
-moz-border-radius: 3px 3px 3px 3px;
border: 1px solid #CCCCCC;
color: #808080;
display: inline-block;
font-size: 13px;
height: 30px;
line-height: 18px;
padding: 0px;
width: 200px;
}
select {
height: 27px;
line-height: 27px;
}
form .input {
margin-left: 150px;
margin-bottom: 0px;
}
form .button {
margin-left: 150px;
margin-bottom: 0px;
float: left;
}
form .line {
margin-bottom: 0px;
}
</style>
</head>
<body onLoad="init_spring();">
<p>
Picture a spring. You know that the harder you squash or stretch it the harder it tries to get back to its "natural length". So you know that the force must be related to the difference between the natural length and the length it's been forced it to.
\[F = f(dx)\]
where $dx$ is the difference between the natural length and the stretched or squashed length. The equation above summarizes this in mathematical form, the force is given by some function of $dx$. $17^{\text{th}}$ century weirdo Robert Hooke gave the first guess for what this function was in the form of a Latin anagram <i>ceiiinosssttuv</i> which is solved to give <i>Ut tensio, sic vis</i>, "As the extension, so the force" or "Force is proportional to the extension." This gives us
\[F = k dx \]
where $k$ is some constant that tells us how stiff the spring is. Of course as advanced $21^{\text{st}}$ century scientists we can put in a more complicated function,
\[F = k dx + \alpha dx^2 + \beta dx^3 \]
$\alpha$ and $\beta$ are just some numbers. Any force law, other than Hooke's one is called "non-linear".</p>
<p>Now you could take a bunch of springs and join them together, making something like a mattress, pull on it and let it oscillate. For springs obeying Hooke's law it will oscillate in a pretty boring way. For non-linear springs the motion will be crazier. Joining a bunch of non-linear springs together is called the Fermi-Pasta-Ulam problem. Fermi and Ulam are famous guys. Pasta was a American computer scientist with an unfortunate name. Also involved in the first paper was a lady called Mary Tsingou, but for some reason she doesn't get to be included with the first three guys in the name of the problem. The idea was that if you had a non-linear force the system would oscillate in such a crazy way that it would go through every possible arrangement. When they actually simulated it however they found it didn't, it oscillated in a surprisingly regular way. The conclusion in fancy physics jargon: non-linearity does not imply ergodicity.<p>
<p>From the force we can get a potential energy, using the non-linear force above gives us the following four basic shapes of the potential.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsefiDFcHijpLP1q_vbk7xMh1mbNpMIrcbxq6XgCIK5VOIe8gAGu5OcviqOfkp_sww-slIqj-ppXylKkLFr2Z8v6WVWamqrNhyphenhyphendszMAIw9fDN2nWGdVCbts7_7Tco9h_9us6GxZu1RQOg/s1600/potentials-eps.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsefiDFcHijpLP1q_vbk7xMh1mbNpMIrcbxq6XgCIK5VOIe8gAGu5OcviqOfkp_sww-slIqj-ppXylKkLFr2Z8v6WVWamqrNhyphenhyphendszMAIw9fDN2nWGdVCbts7_7Tco9h_9us6GxZu1RQOg/s640/potentials-eps.png" /></a></div>
</p>You can think of the system as a little ball rolling on the potential hill. The top left is Hooke's law, small oscillations about the mean value, imagine a little ball rolling back and forth inside the "well". If you go to the simulation below you can see what that looks like by setting $\alpha = \beta = 0$ and $k = 1$ (and clicking Submit) for example. Much more interesting is the top right potential. Imagine carefully placing a little ball on top of the hump in the middle. Unless you were extremely careful it would roll down to the left or right. This is in fact exactly the sort of thing that happens in the <a href=http://en.wikipedia.org/wiki/Higgs_mechanism>Higgs mechanism</a> which explains the mass of the electron. In our model, if we start almost at the top of the hump (press the "random" button and try $k=-1$, $\beta = 80$, $\alpha = 0$) we find that the springs want to compress together making clumps. These clumps are a little like our Higgs bosons. The symmetry, where all the points were more or less equal, is broken and we rolled down the hill.</p>
<p>The third one is also interesting, again imagine a little ball rolling on the hill on the bottom left. If it starts near the middle it will roll happily inside the little well, but if it gets above the hill it will roll down forever getting faster and faster. You can see this happen, and break the simulation, by choosing say $k = 1$ and $\beta = -250$. After a little while some of the springs should, by chance, accumulate enough energy to get over the hump and fall to their doom (infinity).
The bottom right potential is what it looks like if you turn $\beta = 0$ and turn on $\alpha$. You have one stable direction and one unstable one.</p>
<div id="PendContainer" style="width:470px;">
<div id="Pend" style="float: left;">
<canvas id="canvas" width="470" height="470" ></canvas>
</div>
<div class="input" style="float: left; margin-left: 35px">
<INPUT TYPE="button" NAME="rand_button" Value="random" onClick="initialize()" style="float: left;">
<INPUT TYPE="button" NAME="start_button" Value="on/off" onClick="start_stop()" style="float: left;">
</div>
<form>
<div class="line">
<label for="input">k:</label>
<div class="input">
<input type="number" id="kv" name="inputbox" value="1">
</div>
<label for="input">α:</label>
<div class="input">
<input type="number" id="av" name="inputbox" value="0">
</div>
<label for="input">β:</label>
<div class="input">
<input type="number" id="bv" name="inputbox" value="500">
</div>
</div>
<div class="input" style="float: left; margin-left: 150px">
<INPUT TYPE="button" NAME="change_button" Value="Submit" onClick="change_params()">
</div>
</form>
</div>
<br></br>
<p>Try clicking on the dots, you can move them around if you want a different starting position. You can set up some interesting looking oscillations by choosing a good starting point for all the points. If you really want to, you can break some springs. Easiest is to make a potential with positive parameters. The forces can become huge and the algorithm that evolves the positions forward in time will break as the numbers overflow the maximum allowed size. These masses will break off. By pulling really hard on a spring you might be able to get it to snap off also, depending on the parameters. If you do break some springs clicking "random" will regenerate them.</p>
</body>
</html>
Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-85744671681947197002013-10-08T13:12:00.001-07:002013-10-08T13:16:57.620-07:00A Revolutionary Model<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>revolution</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
</script>
<script type="text/javascript">
var size = 256;
var L = 64; //must divide size
var V = L*L;
var Ls = size/L;
var canvas;
var context;
var imageData;
var Nc = 2;
var cpar = 2;
var t = 0;
var runAnimation = {
value: true
};
function random_powerdistrib(){
return Math.pow( Math.random() , (1/(cpar) ) );
}
function random_sign(){
return -1 + Math.round(Math.random()) * 2
}
function random_Nc( nn ){
return Math.floor(Math.random() * nn);
}
var spin = new Array(L);
var loyalty = new Array(L);
for (var i = 0; i < L; i++) {
spin[i] = new Array(L);
loyalty[i] = new Array(L)
}
var Nrev;
var Ns;
function random_start(){
runAnimation.value = true;
Nrev = 0; Ns = 0.1;
for (var i = 0; i < L; i++) {
for (var j = 0; j < L; j++) {
spin[i][j] = 1;
loyalty[i][j] = random_powerdistrib();
//console.log(loyalty[i][j]);
}
}
do {
var x = random_Nc(L);
var y = random_Nc(L);
if( spin[x][y] == 1 ){ spin[ x ][ y ] = 0; Nrev++; }
} while( Nrev < Math.round( Ns*V ) );
draw_revolution();
$( "#Ns" ).val( Nrev/V );
}
var Ncolours = 8;
var colours = new Array(Ncolours);
for(var c=0; c<Ncolours; c++){ colours[c] = new Array(3); }
colours[0][0] = 255; colours[0][1] = 255; colours[0][2] = 255;
colours[1][0] = 255; colours[1][1] = 0; colours[1][2] = 0;
colours[2][0] = 0; colours[2][1] = 255; colours[2][2] = 0;
colours[3][0] = 0; colours[3][1] = 0; colours[3][2] = 255;
colours[4][0] = 0; colours[4][1] = 255; colours[4][2] = 255;
colours[5][0] = 255; colours[5][1] = 0; colours[5][2] = 255;
colours[6][0] = 255; colours[6][1] = 255; colours[6][2] = 0;
colours[7][0] = 0; colours[7][1] = 0; colours[7][2] = 0;
function colour_pixel(imageData, x,y, type){
for(var i=0; i<Ls; i++){
for(var j=0; j<Ls; j++){
var index = ( (x+i) + (y+j) * imageData.width) * 4;
imageData.data[index+0] = colours[ (type%Ncolours) ][0];
imageData.data[index+1] = colours[ (type%Ncolours) ][1];
imageData.data[index+2] = colours[ (type%Ncolours) ][2];
imageData.data[index+3] = 255;
}}
}
function draw_revolution(){
for (var i = 0; i < L; i++) {
for (var j = 0; j < L; j++) {
colour_pixel(imageData, Ls*i, Ls*j, 1 + spin[i][j]);
}}
context.putImageData(imageData, 0, 0);
context.strokeRect(0,0,size,size);
}
var a = 0;
var b = 0.2;
function javascript_abort()
{
throw new Error('This is not an error. This is just to abort javascript');
}
function local_energy(i,j){
var nb = 0;
if(spin[i][j] != spin[ (i+1)%L ][j]){nb--;}
if(spin[i][j] != spin[ (i-1+L)%L ][j]){nb--;}
if(spin[i][j] != spin[i][ (j+1)%L ]){nb--;}
if(spin[i][j] != spin[i][ (j-1+L)%L ]){nb--;}
/*if(0 == spin[ (i+1)%L ][(j+1)%L]){nb--;}
if(0 == spin[ (i+1)%L ][(j-1+size)%L]){nb--;}
if(0 == spin[ (i-1+L)%L ][(j+1)%L]){nb--;}
if(0 == spin[ (i-1+L)%L ][(j-1+L)%L]){nb--;}*/
return nb;
}
var J = 0;
function Step(){
for(var k=0; k<V; k++){
var i = random_Nc(L);
var j = random_Nc(L);
if( spin[i][j] == 1){
Ns = Nrev/V;
if( loyalty[i][j] + J*local_energy(i,j) < a*Math.pow(Ns,b) ){
Nrev+=1;
spin[i][j] = 0;
$( "#Ns" ).val( Nrev/V );
}
}
}
}
function animate_revolution(runAnimation, canvas, context) {
if(runAnimation.value) {
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
t++;
Step();
draw_revolution();
//if (t > 500){runAnimation.value = false; }
}
setTimeout(function() {
requestAnimFrame(function() {
animate_revolution( runAnimation, canvas, context);
});
});
}
function step_time(){
runAnimation.value = true;
animate_revolution( runAnimation, canvas, context);
runAnimation.value = false;
}
function init_revolution(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(0,0);
context.font="italic 15px Helvetica";
context.strokeRect(0,0,size,size);
imageData = context.createImageData(size, size);
random_start();
if(runAnimation.value) {
animate_revolution( runAnimation, canvas, context);
}
}
$(function() {
$( "#SliderTol" ).slider({
value:a,
min: 0.0,
max: 5.0,
step: 0.01,
slide: function( event, ui ) {
setTimeout(function() {
runAnimation.value = false;
a = $('#SliderTol').slider("value");
runAnimation.value = true;
animate_revolution( canvas, context);
},0);
$( "#amount" ).val( ui.value );
}
});
$( "#amount" ).val( $( "#SliderTol" ).slider( "value" ) );
});
$(function() {
$( "#SliderOcc" ).slider({
value:J,
min: 0,
max: 1,
step: 0.01,
slide: function( event, ui ) {
setTimeout(function() {
runAnimation.value = false;
J = $('#SliderOcc').slider("value");
random_start();
runAnimation.value = true;
animate_revolution( canvas, context);
},0);
$( "#amountocc" ).val( ui.value );
}
});
$( "#amountocc" ).val( $( "#SliderOcc" ).slider( "value" ) );
});
$(function() {
$( "#SliderNc" ).slider({
value:cpar,
min: 2,
max: 5000,
step: 2,
slide: function( event, ui ) {
setTimeout(function() {
runAnimation.value = false;
cpar = $('#SliderNc').slider("value");
random_start();
runAnimation.value = true;
animate_revolution( canvas, context);
},0);
$( "#amountnc" ).val( ui.value );
}
});
$( "#amountnc" ).val( $( "#SliderNc" ).slider( "value" ) );
});
$(function() {
$( "#Ns" ).val( Ns );
});
</script>
</head>
<body onLoad="init_revolution();">
<p>
As another application of an Ising type system in 'social physics' I am going to look at the paper,
<a href="http://arxiv.org/pdf/1207.5232v1.pdf">Peer to Peer and Mass Communication Effect on Revolution Dynamics</a>,
if you want more details you can read it, I have nothing to do with the authors and my mistakes are my own.
The essential idea is again to simplify people down to binary agents with two possible choices, join the revolution or stay with the status quo. The agents have a predetermined conservatism and they can be influenced by their immediate neighbours. In addition the revolutionary agents have a youtube channel, a 50 megawatt broadcasting tower or a guy handing out leaflets. They have some way to make their influence felt by all the other agents simultaneously.
</p>
<p>
As an Ising system conservatism is something like a local coupling constant, the neighbour interaction is the usual ising interaction and the mass communication is like a global field, but created by the spins themselves. These analogies are far from exact however and as usual the best way to find out what the model does is to simulate it. We start with an initial state where most people are in the status quo and there are a few randomly distributed revolutionaries. Like the Schelling model but unlike the Ising model we don't allow people to change their minds and go back to the status quo. We could use the standard Metropolis accept reject but it wouldn't modify the conclusions much, as it is you can think of this as the Metropolis algorithm running at zero temperature.
</p>
</BR>
<div id="revolutionContainer" style="width: 600px; height 400px; float: left;">
<div id="revolution" style="float: left;">
<canvas id="canvas" width="300" height="300"></canvas>
</div>
<div id="tollab" style="margin-left: 30px; width: 85px; float: left;">
<label for="amount">a: </label></div><input type="text" id="amount" style="border: 0px; margin: 0px; color: red; font-weight: bold; width: 69px; ">
<div id="SliderTol" style="width: 200px; margin: 15px; float: left;"></div>
<div id="occlab" style="margin-left: 30px; width: 95px; float: left;">
<label for="amountocc">J: </label></div><input type="text" id="amountocc" style="border: 0px; margin: 0px; color: red; font-weight: bold; width: 69px; float: left;">
<div id="SliderOcc" style="width: 200px; margin: 15px; float: left;"></div>
<div id="mclab" style="margin-left: 30px; width: 145px; float: left;">
<label for="amountnc">c: </label></div><input type="text" id="amountnc" style="border: 0px; margin: 0px; color: red; font-weight: bold; width: 69px; float: left;">
<div id="SliderNc" style="width: 200px; margin: 15px; float: left;"></div>
<div id="Buttons" style="float: left; margin: 15px;">
<div id="llab" style="margin-left: 20px; margin-top: 0px; width: 85px; float: left;">
<label for="Ns">% rev: </label></div><input type="text" id="Ns" style="border: 0px; margin: 0px; color: red; font-weight: bold; width: 69px; float: left;"> </div>
<INPUT TYPE="button" NAME="rand_button" Value="random" onClick="random_start()" style=" margin-left: 30px; float: left;">
<!--<INPUT TYPE="button" NAME="step_button" Value="step" onClick="step_time()" style=" margin-left: 30px; float: left;">-->
</div>
<p>
Let $R = N_{rev}/N$ be the ratio of revolutionaries to the total population, initially $R = 0.1$. The parameter $a$ controls the power the mass communication has to influence people: given R let $H(R) = a R^b$ this is the 'media field'. I just follow the paper and set $b = 0.2$ so $a$ controls the strength of the mass media. $J$ controls the influence of the local environment, given an agent $i$ let $H(i) = J \sum_j S_j$ where the sum is over neighbours of $i$, in this case up down left and right. The final parameter $c$ controls the conservatism. Let $h_i$ be the conservatism of the agent $i$. Low $h_i$ means the agent doesn't much like the status quo while an agent with large $h_i$ is very attached to it. The $h_i$'s are randomly distributed at the start of the simulation (whenever you click the random button or move the $c$ slider) according to $P(h_i < h) = h^c$ for $h \in [0,1]$. For low c this gives a wide distribution of people with varied opinions about the current establishment. For large $c$, everyone is about equally conservative. Finally an agent joins the revolution if at any time,
\[ h_i + H(i) < H\]
</p>
<p>
There are several regimes. Let's take $c = 2$ first. When nearest neighbours have little influence, $J \approx 0$ and the effects of mass media are also relatively small $a < 1$, we see an inhomogeneous distribution, much like a high temperature Ising model. There is no clustering of revolutionaries with revolutionaries and conservatives with conservatives. This is probably a dangerous situation in a real society, maybe this is a civil war phase. As the power of the media increases there is total revolution. For moderate $a$, say $0.3$ and moderate $J$, say $0.25$, we start to see clustering. Now that the influence of neighbours becomes as important as the influence of the media we start to see small clusters of conservatives swallowed up by the revolution, but larger clusters surviving. Perhaps we end up with two independent nations in this phase. Unsurprisingly if you increase the conservatism it requires stronger media influence and stronger neighbour coupling to get total revolutions. There also appears to be no phase where there are large numbers of revolutionaries and large clusters of conservatives coexisting. So no civil wars and no new nations, maybe not surprising considering a high $c$ nation is a nation where everyone is almost equally conservative.
</p>
<p>
People keep finding new applications for this old model which seems apt to describe situations where there is clustering, as here and in the Schelling model, or where there is a change of phase as here in the total revolution case and in the original Ising model at $T_c$. Where there is a binary choice; spin up or down, move or stay, revolt or don't, an Ising like model seems to often reproduce much of the interesting behaviour.
</p>
</body>
</html>
Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com1tag:blogger.com,1999:blog-337859244861341472.post-8859503988976194742013-08-29T01:04:00.002-07:002016-05-10T02:14:27.946-07:00The Schelling Model<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Schelling</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawpoint(ctx,x,y,fs){
ctx.beginPath();
ctx.arc(x,y,1,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function drawVTic(ctx,p){
ctx.beginPath();
ctx.moveTo(p,0);
ctx.lineTo(p,5);
ctx.stroke();
}
function drawHTic(ctx,p){
ctx.beginPath();
ctx.moveTo(0,p);
ctx.lineTo(5,p);
ctx.stroke();
}
</script>
<script type="text/javascript">
var size = 256;
var L = 64; //must divide size
var V = L*L;
var Ls = size/L;
var canvas;
var context;
var imageData;
var Nc = 2;
var E = 0;
var tolerance = 0.3;
var occupancy = 0.8;
var t = 0;
var runAnimation = {
value: true
};
var spin = new Array(L);
for (var i = 0; i < L; i++) {
spin[i] = new Array(L);
}
function random_sign(){
return -1 + Math.round(Math.random()) * 2
}
function random_Nc( nn ){
return Math.floor(Math.random() * nn);
}
var Nvacant = 0;
var vacant = new Array(V);
for (var i = 0; i < V; i++) { vacant[i] = new Array(2); }
function random_start(){
runAnimation.value = true;
Nvacant = 0;
t = 0;
for (var i = 0; i < L; i++) {
for (var j = 0; j < L; j++) {
if(Math.random() < occupancy){
spin[i][j] = 1 + random_Nc(Nc);
}
else{
spin[i][j] = 0;
vacant[ Nvacant][0] = i; vacant[ Nvacant][1] = j;
Nvacant += 1;
}
}
}
}
var Ncolours = 8;
var colours = new Array(Ncolours);
for(var c=0; c<Ncolours; c++){ colours[c] = new Array(3); }
colours[0][0] = 255; colours[0][1] = 255; colours[0][2] = 255;
colours[1][0] = 255; colours[1][1] = 0; colours[1][2] = 0;
colours[2][0] = 0; colours[2][1] = 255; colours[2][2] = 0;
colours[3][0] = 0; colours[3][1] = 0; colours[3][2] = 255;
colours[4][0] = 0; colours[4][1] = 255; colours[4][2] = 255;
colours[5][0] = 255; colours[5][1] = 0; colours[5][2] = 255;
colours[6][0] = 255; colours[6][1] = 255; colours[6][2] = 0;
colours[7][0] = 0; colours[7][1] = 0; colours[7][2] = 0;
function colour_pixel(imageData, x,y, type){
for(var i=0; i<Ls; i++){
for(var j=0; j<Ls; j++){
var index = ( (x+i) + (y+j) * imageData.width) * 4;
imageData.data[index+0] = colours[ (type%Ncolours) ][0];
imageData.data[index+1] = colours[ (type%Ncolours) ][1];
imageData.data[index+2] = colours[ (type%Ncolours) ][2];
imageData.data[index+3] = 255;
}}
}
function draw_schelling(){
for (var i = 0; i < L; i++) {
for (var j = 0; j < L; j++) {
colour_pixel(imageData, Ls*i, Ls*j, spin[i][j]);
}}
context.putImageData(imageData, 0, 0);
context.strokeRect(0,0,size,size);
}
var av_div = 0;
function calc_diversity(){
av_div = 0;
var num = 0;
for (var i = 0; i < L; i++) {
for (var j = 0; j < L; j++) {
if(spin[i][j] != 0){
var ln = local_energy(i,j);
var nn = local_neighbours(i,j);
if(nn != 0){ av_div += (ln)/nn; }
num++;
}
}}
av_div /= num;
av_div = 1*( av_div );
$( "#av_div" ).val( Math.round(av_div * 1000) / 1000 );
}
function javascript_abort()
{
throw new Error('This is not an error. This is just to abort javascript');
}
function local_energy(i,j){
var nb = 0;
if(spin[i][j] == spin[ (i+1)%L ][j]){nb++;}
if(spin[i][j] == spin[ (i-1+L)%L ][j]){nb++;}
if(spin[i][j] == spin[i][ (j+1)%L ]){nb++;}
if(spin[i][j] == spin[i][ (j-1+L)%L ]){nb++;}
if(spin[i][j] == spin[ (i+1)%L ][(j+1)%L]){nb++;}
if(spin[i][j] == spin[ (i+1)%L ][(j-1+L)%L]){nb++;}
if(spin[i][j] == spin[ (i-1+L)%L ][(j+1)%L]){nb++;}
if(spin[i][j] == spin[ (i-1+L)%L ][(j-1+size)%L]){nb++;}
return nb;
}
function local_neighbours(i,j){
var nb = 8;
if(0 == spin[ (i+1)%L ][j]){nb--;}
if(0 == spin[ (i-1+L)%L ][j]){nb--;}
if(0 == spin[i][ (j+1)%L ]){nb--;}
if(0 == spin[i][ (j-1+L)%L ]){nb--;}
if(0 == spin[ (i+1)%L ][(j+1)%L]){nb--;}
if(0 == spin[ (i+1)%L ][(j-1+size)%L]){nb--;}
if(0 == spin[ (i-1+L)%L ][(j+1)%L]){nb--;}
if(0 == spin[ (i-1+L)%L ][(j-1+L)%L]){nb--;}
return nb;
}
function Step(){
//for (var i = 0; i < size; i++) {
//for (var j = 0; j < size; j++) {
for(var k=0; k<V; k++){
var i = random_Nc(L);
var j = random_Nc(L);
if( spin[i][j] != 0){
var ln = local_energy(i,j);
var nn = local_neighbours(i,j);
if( ln < tolerance*nn ){
var usen = Math.floor( Math.random( ) * Nvacant );
spin[ vacant[usen][0] ][ vacant[usen][1] ] = spin[i][j];
spin[i][j] = 0;
vacant[usen][0] = i; vacant[usen][1] = j;
}
}
}
//}
//}
}
function animate_schelling(runAnimation, canvas, context) {
if(runAnimation.value) {
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
t++;
Step();
draw_schelling(); calc_diversity();
//if (t > 500){runAnimation.value = false; }
}
setTimeout(function() {
requestAnimFrame(function() {
animate_schelling( runAnimation, canvas, context);
});
});
}
function init_schelling(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(0,0);
context.font="italic 15px Helvetica";
context.strokeRect(0,0,size,size);
imageData = context.createImageData(size, size);
random_start();
draw_schelling();
if(runAnimation.value) {
animate_schelling( runAnimation, canvas, context);
}
}
$(function() {
$( "#SliderTol" ).slider({
value:tolerance,
min: 0.01,
max: 0.99,
step: 0.01,
slide: function( event, ui ) {
setTimeout(function() {
runAnimation.value = false;
tolerance = $('#SliderTol').slider("value");
runAnimation.value = true;
animate_schelling( canvas, context);
},0);
$( "#amount" ).val( ui.value );
}
});
$( "#amount" ).val( $( "#SliderTol" ).slider( "value" ) );
});
$(function() {
$( "#SliderOcc" ).slider({
value:occupancy,
min: 0,
max: 0.99,
step: 0.01,
slide: function( event, ui ) {
setTimeout(function() {
runAnimation.value = false;
occupancy = $('#SliderOcc').slider("value");
random_start();
runAnimation.value = true;
animate_schelling( canvas, context);
},0);
$( "#amountocc" ).val( ui.value );
}
});
$( "#amountocc" ).val( $( "#SliderOcc" ).slider( "value" ) );
});
$(function() {
$( "#SliderNc" ).slider({
value:Nc,
min: 2,
max: 6,
step: 1,
slide: function( event, ui ) {
setTimeout(function() {
runAnimation.value = false;
Nc = $('#SliderNc').slider("value");
random_start();
runAnimation.value = true;
animate_schelling( canvas, context);
},0);
$( "#amountnc" ).val( ui.value );
}
});
$( "#amountnc" ).val( $( "#SliderNc" ).slider( "value" ) );
});
$(function() {
$( "#av_div" ).val( av_div );
});
</script>
</head>
<body onLoad="init_schelling();">
<p>
Lest you think I've forgotten about the <a href="http://usediscretion.blogspot.dk/2013/05/the-ising-model.html">Ising model</a>, here is another application (sort of). Below are some maps of cities in America where each dot is a person and the colour represents their race. Taken from <a href="http://www.coopercenter.org/demographics/Racial-Dot-Map">here</a>.
As you can see the distribution is less than homogeneous. I especially like the little red enclave in Detroit as well at the obvious "domain wall" along 8-Mile Road. New York and Chicago have more types of people. New York has many smaller clusters, possibly helped to form by geography.
</p>
<a href="http://imgur.com/SZEoEj7"><img src="http://i.imgur.com/SZEoEj7.jpg" title="Hosted by imgur.com" width="540" height=auto/></a>
<h2>New York</h2>
<a href="http://imgur.com/ZcClWZ0"><img src="http://i.imgur.com/ZcClWZ0.jpg" title="Hosted by imgur.com" width="540" height=auto/></a>
<h2>Chicago</h2>
<a href="http://imgur.com/OoE2ex6"><img src="http://i.imgur.com/OoE2ex6.jpg" title="Hosted by imgur.com" width="540" height=auto/></a>
<h2>Detroit</h2>
<p>
An economist named Thomas Schelling heard about these divisions and wanted to know if they were caused by people having strong preferences to be near their own kind, so he created a model to get to the essence of the problem. Like any good model we strip away the inessentials. People move for various reasons; for new jobs, better schools, to avoid meteor strikes, in Schelling's model people move based only on who their neighbours are. Our city is a large grid. At each point on the grid we have an agent of type A, an agent of type B or an empty space. When we examine the grid points we count the total number of neighbours and the number of neighbours of the same type as the central point. Note we are looking at the <a href="http://en.wikipedia.org/wiki/Moore_neighborhood">Moore neighbourhood</a> of A.
</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOz8t1bbzyGDYvn5mSnBmuLJQ2AZm0RFsJZpnoiau3lY2PZd6NWLGV6lFAO3lRwf16fkt6glqAIIVfMejabNR1tp7G5CLjaD6kJpuvCg62MIJjrFFV7_zILt5wCPDM5t3HwWe0OFfHSQ8/s1600/moore.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOz8t1bbzyGDYvn5mSnBmuLJQ2AZm0RFsJZpnoiau3lY2PZd6NWLGV6lFAO3lRwf16fkt6glqAIIVfMejabNR1tp7G5CLjaD6kJpuvCg62MIJjrFFV7_zILt5wCPDM5t3HwWe0OFfHSQ8/s320/moore.png" /></a></div>
<p>
In the plot above A has 7 neighbours 3 of which are the same type as him and 4 of which are different. We now pick a number called the intolerance which acts very much like the temperature in the Ising model. If the equation
\[ \frac{ \text{Number different neighbours} }{\text{Number of neighbours}} > \text{intolerance} \]
is true the agent moves to a vacant space (chosen at random), if not the agent stays put. For example with an intolerance of $30\%$ the agent will be okay with being in the minority as long as at least $30\%$ of its neighbours are the same type as it. Click the box below to see this in action, starting from a random distribution of agents and evolving.
</p>
<div id="schellingContainer" style="width: 600px; height 400px; float: left;">
<div id="schelling" style="float: left;">
<canvas id="canvas" width="300" height="300"></canvas>
</div>
<div id="tollab" style="margin-left: 30px; width: 80px; float: left;">
<label for="amount">intolerance: </label></div><input type="text" id="amount" style="border: 0px; margin: 0px; color: red; font-weight: bold; width: 69px; float: left;">
<div id="SliderTol" style="width: 200px; margin: 15px; float: left;"></div>
<div id="occlab" style="margin-left: 30px; width: 85px; float: left;">
<label for="amountocc">occupancy: </label></div><input type="text" id="amountocc" style="border: 0px; margin: 0px; color: red; font-weight: bold; width: 69px; float: left;">
<div id="SliderOcc" style="width: 200px; margin: 15px; float: left;"></div>
<div id="mclab" style="margin-left: 30px; width: 80px; float: left;">
<label for="amountnc">Types: </label></div><input type="text" id="amountnc" style="border: 0px; margin: 0px; color: red; font-weight: bold; width: 69px; float: left;">
<div id="SliderNc" style="width: 200px; margin: 15px; float: left;"></div>
<div id="llab" style="margin-left: 20px; margin-top: 20px; width: 65px; float: left;">
<label for="av_div">% same: </label></div><input type="text" id="av_div" style="border: 0px; margin: 0px; margin-top: 20px; color: red; font-weight: bold; width: 69px; float: left;"> </div>
<!--
<div id="Buttons" style="float: left; margin: 0px;">
<INPUT TYPE="button" NAME="rand_button" Value="random" onClick="random_start()" style=" margin-left: 10px; float: left;">
</div>-->
<p>
The process we sought to model, racial segregation, has materialised. The original somewhat surprising finding was that for quite tolerant agents the final "diversity" measured by checking how many neighbours of the same type each agent has is relatively low (or the % same = 1 - diversity is relatively high). Much lower than what each individual agent will tolerate. Slightly biased individuals give rise to a very biased society. As usual there are some parameters to play with. Change the intolerance to see a phase transition to a noisy phase where everyone hates being near agents of different type so much that they move all the time. Decrease the occupancy to make the grid more sparsely populated, you can see that the segregated domains are separated by a "wall" of vacant sites. Finally play with the number of agent types to see that even an ethnically diverse city segregates, though in this case the place looks a bit more diverse since there are more, smaller clusters, kind of like the New York map. Interestingly, if the segregation phenomenon occurs then the agents are made extremely tolerant this does nothing to increase diversity, proving mathematically that society can never improve :)
</p>
<p>
Going back to look at the <a href="http://usediscretion.blogspot.dk/2013/05/the-ising-model.html">Ising model</a> the differences are (a) conservation of agents: no one dies during this simulation - there are always the same number of A type and B types. The Ising model doesn't conserve number of up spins for example though it will fluctuate pretty close to its equilibrium value. (b) However this means there is no "conquest" of A agents by B agents. For example if you put the Ising model to a random configuration and rapidly lower the temperature (increase $\beta$) you will see a similar domain structure form. However, wait long enough and one spin will ultimately dominate. I can't decide if this makes a more or less realistic model. Also if you play with the Ising model in this way you sometimes get two solid blocks of up and down separated by a domain wall, Detroit style, which I haven't seen occur in the Schelling model.
</p>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-58256989978137216782013-07-27T06:03:00.000-07:002013-07-27T06:29:42.722-07:00Playing Tetris is my homework!<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Tetris</title>
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
</script>
<script type="text/javascript">
var canvas;
var context;
var canvas2;
var context2;
var width;
var height;
var block_size = 30;
var wblocks;
var hblocks;
var runAnimation = {value: true};
var shw = 0;
var shh = 0;
var block_array;
var block_colour_array;
var nblocks;
var row;
var crow;
var xpos;
var xold;
var ypos;
var yold;
var droom;
var next_falling_type;
var falling_type;
var idx;
var draw = 1;
var dodrop = 1;
var tmplag = 25;
var lag_init = 400 + tmplag;
var lag = lag_init;
var lag_incr = 25;
var oldlag = lag;
var dead = false;
var level = 0;
var lines = 0;
var score = 0;
var npx, npy;
var periodic = false;
var col = new Array(7);
/*
x x
x x
*/
col[0] = "red";
/*
x x x x
*/
col[1] = "orange";
/*
x
x x x
*/
col[2] = "blue";
/*
x
x x x
*/
col[3] = "yellow";
/*
x
x x x
*/
col[4] = "fuchsia";
/*
x x
x x
*/
col[5] = "aqua";
/*
x x
x x
*/
col[6] = "green";
var block = new Array(4);
for(var k=0; k<4; k++){ block[k] = new Array(2); }
var rblock = new Array(4);
for(var k=0; k<4; k++){ rblock[k] = new Array(2); }
var nextblock = new Array(4);
for(var k=0; k<4; k++){ nextblock[k] = new Array(2); }
function square(ctx, x, y, fs){
ctx.fillStyle=fs;
ctx.fillRect(x*block_size,y*block_size,block_size,block_size);
ctx.strokeRect(x*block_size,y*block_size,block_size,block_size);
}
function oh(x, y){
block[0][0] = x; block[0][1] = y;
block[1][0] = x; block[1][1] = y+1;
block[2][0] = x+1; block[2][1] = y;
block[3][0] = x+1; block[3][1] = y+1;
}
function eye(x, y){
block[2][0] = x-1; block[2][1] = y;
block[0][0] = x; block[0][1] = y;
block[1][0] = x+1; block[1][1] = y;
block[3][0] = x+2, block[3][1] = y;
}
function tee(x, y){
block[2][0] = x-1; block[2][1] = y;
block[0][0] = x; block[0][1] = y;
block[1][0] = x+1; block[1][1] = y;
block[3][0] = x; block[3][1] = y-1;
}
function ell1(x, y){
block[2][0] = x-1; block[2][1] = y-1;
block[1][0] = x-1; block[1][1] = y;
block[0][0] = x; block[0][1] = y;
block[3][0] = x+1; block[3][1] = y;
}
function ell2(x, y){
block[2][0] = x-1; block[2][1] = y;
block[0][0] = x; block[0][1] = y;
block[1][0] = x+1; block[1][1] = y;
block[3][0] = x+1; block[3][1] = y-1;
}
function zed(x, y){
block[2][0] = x-1; block[2][1] = y-1;
block[1][0] = x; block[1][1] = y-1;
block[0][0] = x; block[0][1] = y;
block[3][0] = x+1; block[3][1] = y;
}
function ess(x, y){
block[2][0] = x+1; block[2][1] = y-1;
block[1][0] = x; block[1][1] = y-1;
block[0][0] = x; block[0][1] = y;
block[3][0] = x-1; block[3][1] = y;
}
function block_picker(x, y, type){
switch(type){
case 0:
oh(x, y)
break;
case 1:
eye(x, y);
break;
case 2:
tee(x, y)
break;
case 3:
ell1(x, y);
break;
case 4:
ell2(x, y);
break;
case 5:
zed(x, y);
break;
case 6:
ess(x, y);
break;
}
}
function choose_block(x, y){
falling_type = next_falling_type;
next_falling_type = Math.floor((Math.random()*7));
/* Showing next block */
block_picker(npx, npy, next_falling_type);
scoretable();
draw_block(context2, next_falling_type)
/**********************/
block_picker(x, y, falling_type);
}
function draw_block(ctx, type){
if(typeof(type)==='undefined'){type = falling_type;}
for(var i=0; i<4; i++){
square( ctx, block[i][0], block[i][1], col[type] );
}
}
function idx_to_coord(i,j){ return i*(hblocks+1)+j; }
function draw_block_array(){
for(var i=0; i<wblocks; i++){
for(var j=0; j<hblocks; j++){
idx = idx_to_coord(i,j);
if( block_array[idx] ){ square(context, i,j, block_colour_array[idx] ); }
}}
}
function checklines(){
runAnimation.value = false;
var multiplier = 1;
for(var j=0; j<hblocks; j++){
var csum = 0;
for(var i=0; i<wblocks; i++){
csum += block_array[idx_to_coord(i,j)];
}
if(csum == wblocks){
multiplier++;
lines++; if(lines%10 == 0 && oldlag > tmplag){oldlag -= lag_incr; lag = oldlag; level++; }
for(var i=0; i<wblocks; i++){ idx = idx_to_coord(i,j-1); row[i] = block_array[idx]; crow[i] = block_colour_array[idx];}
for(var k=j; k>1; k--){
for(var i=0; i<wblocks; i++){
idx = idx_to_coord(i,k);
block_array[idx] = row[i];
block_colour_array[idx] = crow[i];
idx = idx_to_coord(i,k-2);
row[i] = block_array[idx];
crow[i] = block_colour_array[idx];
}
}
for(var i=0; i<wblocks; i++){ idx = idx_to_coord(i,1); block_array[idx] = row[i]; block_colour_array[idx] = crow[i];}
context.clearRect(0,0,width,height);
context.strokeRect(0,0,width,height);
draw_block_array();
}
}
score += (level+1)*multiplier*multiplier;
runAnimation.value = true;
}
var room_lr = new Array(4);
function keyDown(evt){
if(evt.keyCode == 40 || evt.keyCode == 37 || evt.keyCode == 39 || evt.keyCode == 68 || evt.keyCode == 80 || evt.keyCode == 83){
if(!dead){
var wallhit = 0; var lr;
var rothit = 0; var rotlr;
var oldx, oldy;
if (evt.keyCode == 40) { lag = tmplag; }
else if (evt.keyCode == 80) { runAnimation.value = !runAnimation.value; }
else{
if(runAnimation.value & draw) {
draw = 0;
for(var i=0;i<4;i++){ rblock[i][0] = block[i][0]; rblock[i][1] = block[i][1]; }
var room = block_array[ idx_to_coord(rblock[0][0],rblock[0][1]) ];
switch (evt.keyCode) {
case 37:
if(!periodic){
for(var i=0;i<4;i++){
if(rblock[i][0]-1 < 0){wallhit = 1; break;}
room_lr[i] = block_array[ idx_to_coord(rblock[i][0]-1,rblock[i][1]) ];
} rothit = 1; lr = -1;
} else{
for(var i=0;i<4;i++){
//if(rblock[i][0]-1 < 0){wallhit = 1; break;}
room_lr[i] = block_array[ idx_to_coord( (rblock[i][0]-1+wblocks)%wblocks,rblock[i][1]) ];
} rothit = 1; lr = -1;
}
break;
case 39:
if(!periodic){
for(var i=0;i<4;i++){
if(rblock[i][0]+1 >= wblocks){wallhit = 1; break;}
room_lr[i] = block_array[ idx_to_coord(rblock[i][0]+1,rblock[i][1]) ];
} rothit = 1; lr = 1;
} else {
for(var i=0;i<4;i++){
//if(rblock[i][0]-1 < 0){wallhit = 1; break;}
room_lr[i] = block_array[ idx_to_coord( (rblock[i][0]+1)%wblocks,rblock[i][1]) ];
} rothit = 1; lr = 1;
}
break;
case 68: /*d*/
for(var i=1;i<4;i++){
if(room > 0){break;}
oldx = rblock[i][0] - rblock[0][0];
oldy = rblock[i][1] - rblock[0][1];
if(rblock[0][0]-oldy < 0){rothit = 1; break;}
if(rblock[0][0]-oldy >= wblocks){rothit = 1; break;}
if(rblock[0][1]+oldx >= hblocks){rothit = 1; break;}
room += block_array[ idx_to_coord(rblock[0][0]-oldy,rblock[0][1]+oldx) ];
//room_lr[i] = block_array[ idx_to_coord(block[i][0]-oldy,block[i][1]+oldx) ];
}
if(!room && !rothit){
for(var i=0;i<4;i++){
oldx = rblock[i][0] - rblock[0][0];
oldy = rblock[i][1] - rblock[0][1];
block[i][0] = rblock[0][0]-oldy;
block[i][1] = rblock[0][1]+oldx;
}
}
wallhit = 1; rotlr = -1; rothit = 1;
break;
case 83: /*s*/
/*for(var i=1;i<4;i++){
oldx = block[i][0] - block[0][0];
oldy = block[i][1] - block[0][1];
if(block[0][0]+oldy < 0){rothit = 1; break;}
if(block[0][0]+oldy >= wblocks){rothit = 1; break;}
if(block[0][1]-oldx >= hblocks){rothit = 1; break;}
room_lr[i] = block_array[ idx_to_coord(block[0][0]+oldy,block[0][1]-oldx) ];
} wallhit = 1; rotlr = 1;*/
for(var i=1;i<4;i++){
if(room > 0){break;}
oldx = rblock[i][0] - rblock[0][0];
oldy = rblock[i][1] - rblock[0][1];
if(rblock[0][0]+oldy < 0){rothit = 1; break;}
if(rblock[0][0]+oldy >= wblocks){rothit = 1; break;}
if(rblock[0][1]-oldx >= hblocks){rothit = 1; break;}
room += block_array[ idx_to_coord(rblock[0][0]+oldy,rblock[0][1]-oldx) ];
//room_lr[i] = block_array[ idx_to_coord(block[i][0]-oldy,block[i][1]+oldx) ];
}
if(!room && !rothit){
for(var i=0;i<4;i++){
oldx = rblock[i][0] - rblock[0][0];
oldy = rblock[i][1] - rblock[0][1];
block[i][0] = rblock[0][0]+oldy;
block[i][1] = rblock[0][1]-oldx;
}
}
wallhit = 1; rotlr = -1; rothit = 1;
break;
}//switch
context.clearRect(0,0,width,height);
context.strokeRect(0,0,width,height);
if(!wallhit){
var room = 0; for(var i=0;i<4;i++){ room += room_lr[i] }
if(!room){
//for(var i=0;i<4;i++){ block[i][0] = rblock[i][0] + lr; }
if(periodic){
if(lr < 0){ for(var i=0;i<4;i++){ block[i][0] = (rblock[i][0] -1 + wblocks)%wblocks; } }
if(lr > 0){ for(var i=0;i<4;i++){ block[i][0] = (rblock[i][0] +1)%wblocks; } }
} else {
for(var i=0;i<4;i++){ block[i][0] = rblock[i][0] + lr; }
}
}
}
/*if(!rothit){
var room = 0; for(var i=0;i<4;i++){ room += room_lr[i] }
if(!room){
for(var i=1;i<4;i++){
oldx = block[i][0] - block[0][0];
oldy = block[i][1] - block[0][1];
block[i][0] = block[0][0]+rotlr*oldy;
block[i][1] = block[0][1]-rotlr*oldx;
}
}
}*/
draw_block(context);
draw_block_array();
draw = 1;
}//draw
}//slam else
}//dead
}
evt.preventDefault();
return false;
}
function keyUp(evt){
if (evt.keyCode == 40) {
lag = oldlag;
}
evt.preventDefault();
return false;
}
function drop(){
//if(draw){
dodrop = 0;
//setTimeout(function() {
context.clearRect(0,0,width,height);
context.strokeRect(0,0,width,height);
droom = 0;
for(var i=0;i<4;i++){ droom += (block_array[ idx_to_coord(block[i][0],block[i][1]+1) ]); }
if(!droom){
draw_block(context);
} else {
for(var i=0;i<4;i++){
idx = idx_to_coord(block[i][0],block[i][1]);
block_array[ idx ] = 1;
block_colour_array[ idx ] = col[falling_type];
}
checklines();
ypos = 0; xpos = (wblocks/2) - 1;
choose_block(xpos, ypos);
draw_block(context);
}
draw_block_array();
if(block_array[ idx_to_coord(xpos,1) ]){
draw_block(context);
runAnimation.value = false; dead = true; canvas.addEventListener('mousedown', mdown, false);
context.fillStyle = "Black"
context.fillText("Game Over" ,((wblocks/2) - 3)*block_size,((hblocks/2) - 1)*block_size );
}
ypos=(ypos+1)%hblocks;
//droom = 0;
for(var i=0;i<4;i++){
block[i][1]++;
//if(block[i][1]+1 == hblocks-1){droom++;}
}
/*if(droom > 0){
for(var i=0;i<4;i++){
idx = idx_to_coord(block[i][0],block[i][1]);
block_array[ idx ] = 1;
block_colour_array[ idx ] = col[falling_type];
} checklines();
xpos = (wblocks/2) - 1; ypos = 0;
choose_block(xpos, ypos);
}*/
//}, 0);
//}
}
function step(runAnimation, canvas, context) {
if(runAnimation.value) {
if(!dead) drop();
dodrop = 1;
}
setTimeout(function() {
requestAnimFrame(function() {
step( runAnimation, canvas, context);
});
}, lag);
}
function scoretable(){
context2.fillStyle="gray";
context2.globalAlpha = 0.5;
context2.clearRect(0,0,canvas2.width,canvas2.height);
context2.fillRect(0,0,canvas2.width,canvas2.height);
context2.globalAlpha = 1.0;
context2.fillStyle="white";
context2.fillRect( (npx-1)*block_size,(npy-6)*block_size,4*block_size, 2*block_size);
context2.fillStyle="white";
context2.fillRect( (npx-1)*block_size,(npy-2)*block_size,4*block_size, 4*block_size);
context2.fillStyle="black";
context2.strokeRect( 0,0,canvas2.width,canvas2.height);
context2.strokeRect( (npx-1)*block_size,(npy-6)*block_size,4*block_size, 2*block_size);
context2.strokeRect( (npx-1)*block_size,(npy-2)*block_size,4*block_size, 4*block_size);
if(periodic){ context2.fillText("Loop" ,(npx-0.25)*block_size,(npy-4.7)*block_size ); }
else{context2.fillText("Fixed" ,(npx-0.5)*block_size,(npy-4.7)*block_size );}
context2.fillText("Score" ,(npx-1)*block_size,(npy+4)*block_size );
context2.fillText(score.toString() ,(npx-1)*block_size,(npy+5)*block_size );
context2.fillText("Lines" ,(npx-1)*block_size,(npy+7)*block_size );
context2.fillText(lines.toString() ,(npx-1)*block_size,(npy+8)*block_size );
context2.fillText("Level" ,(npx-1)*block_size,(npy+10)*block_size );
context2.fillText(level.toString() ,(npx-1)*block_size,(npy+11)*block_size );
}
var first = 1;
function mdown(evt){
canvas.removeEventListener('mousedown', mdown);
runAnimation.value = true;
draw = 1;
dodrop = 1;
tmplag = 25;
lag_init = 400 + tmplag;
lag = lag_init;
lag_incr = 25;
oldlag = lag;
dead = false;
level = 0;
lines = 0;
score = 0;
for(var i=0; i<nblocks; i++){ block_array[i] = 0; }
for(var i=0; i<wblocks; i++){ block_array[ idx_to_coord(i,hblocks) ] = 1; }
context.clearRect(0,0,width,height);
context.strokeRect(0,0,width,height);
ypos = 0; xpos = (wblocks/2) - 1;
droom = 0;
next_falling_type = Math.floor((Math.random()*7));
choose_block(xpos, ypos);
if(first){ step(runAnimation, canvas, context); }
first = 0;
}
function mdown2(evt){
var rect = canvas2.getBoundingClientRect();
var tx = evt.clientX - rect.left - shw;
var ty = evt.clientY - rect.top - shh;
if( tx < (npx+3)*block_size && tx > (npx-1)*block_size && ty < (npy-4)*block_size && ty > (npy-6)*block_size){
periodic = !periodic;
}
scoretable();
}
function init_tetris(){
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
context.translate(shw, shh);
context.font="bold 30px Veranda";
canvas2 = document.getElementById("canvas2");
context2 = canvas2.getContext("2d");
context2.translate(0,0);
context2.font="30px Veranda";
npx = (canvas2.width/(2*block_size)) - 1; npy = canvas2.height/(3*block_size);
scoretable();
canvas.addEventListener('keydown', keyDown, false);
canvas.addEventListener('keyup', keyUp, false);
width = canvas.width; wblocks = width/block_size;
height = canvas.height; hblocks = height/block_size;
nblocks = wblocks*(hblocks+1);
block_array = new Array(nblocks);
block_colour_array = new Array(nblocks);
row = new Array(wblocks);
crow = new Array(wblocks);
context.strokeRect(0,0,width,height);
/*for(var i=0; i<nblocks; i++){ block_array[i] = 0; }
for(var i=0; i<wblocks; i++){ block_array[ idx_to_coord(i,hblocks) ] = 1; }
context.strokeRect(0,0,width,height);
ypos = 0; xpos = (wblocks/2) - 1;
droom = 0;
next_falling_type = Math.floor((Math.random()*7));
choose_block(xpos, ypos);
step(runAnimation, canvas, context);*/
canvas.addEventListener('mousedown', mdown, false);
canvas2.addEventListener('mousedown', mdown2, false);
}
</script>
</head>
<body onLoad="init_tetris();">
<p>
One summer when I was younger, twelve or so, I was sent to a summer school for the insufferably gifted. I really didn't want to go so I refused to pick a class, which was a terrible idea. In the end I was sent to learn computer programming, something I never would have chosen, since I liked video games. Being denied a summer of watching daytime TV and playing Street Fighter was an outrage and in protest I slept through most of the classes.
</p>
<p>
There was a final project that we had to do, based on what we learned during the course. People did very simple things like programming a computer to deal blackjack or do a substitution cypher. Things like that. But one kid, and I wonder what happened to him, made a Tetris program. This blew my mind. So, almost 15 years late, I am handing in my homework. I promise I didn't copy off anyone.
</p>
<p>
Click the left hand screen to begin playing. The left and right arrow keys move the blocks, down arrow slams them. The 's' and 'd' keys rotate the blocks. The 'p' key pauses and unpauses it. If you die click the left screen again to restart. Tetris is such a classic it can hardly be improved, however if you want to try something funny click on the box that says
"Fixed" and try playing <i>Tetorus</i>.
</p>
<div id="tetrisContainer" style="width: 600px; height: 700px; margin-left: 0px; margin-top: 30px">
<div id="tetris" style="margin: 0; float: left;">
<canvas id="canvas" tabindex="1" width="300" height="600"></canvas>
</div>
<div id="tetriscore" style="margin: 0; float: left;">
<canvas id="canvas2" width="210" height="600"></canvas>
</div>
</div>
</body>
</html>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0tag:blogger.com,1999:blog-337859244861341472.post-66088270101144121782013-07-20T01:38:00.002-07:002013-07-20T05:49:57.387-07:00The Doodle of Arthur
<script type='text/x-mathjax-config'>
MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']],
displayMath: [['\\[','\\]']]}});
</script>
<script src='http://cdn.mathjax.org/mathjax/2.2-latest/MathJax.js?config=TeX-AMS_HTML' type='text/javascript'></script>
<script type='text/javascript'>
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
</script>
<script type="text/javascript">
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
</script>
<script type="text/javascript">
function drawpoint(ctx,x,y,fs){
ctx.beginPath();
ctx.arc(x,y,1,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function drawdot(ctx,x,y,r,fs){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.fillStyle=fs;
ctx.fill();
}
function drawdot_t(ctx,x,y,r,fs, al){
ctx.beginPath();
ctx.arc(x,y,r,0.0,2.0*Math.PI,0);
ctx.globalAlpha = al;
ctx.fillStyle=fs;
ctx.fill();
ctx.globalAlpha = 1;
}
</script>
<script type="text/javascript">
var size = 300;
var sqsize = Math.sqrt(size);
var shw = 0;
var shh = 0;
var twopi = 2.0*Math.PI;
var pitwo = Math.PI/2.0;
var qoh_y = 0;
var qoh_theta = 0;
var qoh_curve = new Array(size);
for(var i=0; i<size; i++){ qoh_curve[i] = 0; }
function QuadratrixofHippias(runAnimation, canvas, context){
if(runAnimation.value) {
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
context.beginPath();
context.moveTo(0,qoh_y);
context.lineTo(size,qoh_y);
context.stroke();
qoh_curve[qoh_y] = 1;
qoh_y = (qoh_y + 1)%(size);
if(qoh_y == 0){ for(var i=0; i<size; i++){ qoh_curve[i] = 0; } }
context.beginPath();
context.arc(0,size,size,0,3*pitwo,1);
context.stroke();
qoh_theta = (qoh_theta + (pitwo/size) )%pitwo;
context.translate(0,size);
context.beginPath();
context.moveTo(0,0);
context.lineTo( size*Math.cos( pitwo - qoh_theta), -size*Math.sin( pitwo - qoh_theta) );
context.stroke();
context.beginPath();
context.moveTo(0,-size);
context.strokeStyle = "red"
var x, y;
for(var i=0; i<size; i++){
if(qoh_curve[i] == 1){
y = -size+i; x = -y/Math.tan( pitwo - (i*pitwo/size) );
context.lineTo(x,y); context.moveTo(x,y);
} else { break; }
}
context.stroke();
context.strokeStyle = "black"
context.translate(0,-size);
//if(qoh_y + 1 == size){ runAnimation.value = false; }
}
setTimeout(function() {
requestAnimFrame(function() {
QuadratrixofHippias( runAnimation, canvas, context);
});
}, 0);
}
var con_a = size/6;
var con_k = size/4;
var con_init = -0.005 + Math.PI/3;
var con_theta = con_init;
var con_curve = new Array(size);
var con_y= 0;
for(var i=0; i<size; i++){ con_curve[i] = 0; }
function ConchoidofNicomedes(runAnimation, canvas, context){
if(runAnimation.value) {
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
context.beginPath();
context.moveTo(0,size/2);
context.lineTo(size,size/2);
context.stroke();
context.beginPath();
context.moveTo(con_a,0);
context.lineTo(con_a,size);
context.stroke();
con_curve[con_y] = 1;
con_y = (con_y + 1)%size;
if(con_y == 0){ for(var i=0; i<size; i++){ con_curve[i] = 0; } }
con_theta = (con_theta - (2*con_init/size) );
if(con_theta < -con_init){ con_theta = con_init; }
context.translate(0,size/2);
context.beginPath();
context.moveTo(0,0);
var r = con_k + (con_a / Math.cos(con_theta) );
context.lineTo( r*Math.cos( con_theta ), -r*Math.sin( con_theta ) );
context.stroke();
context.beginPath();
context.strokeStyle = "red"
var x, y, th, rr;
th = con_init;
rr = con_k + (con_a / Math.cos(th) );
context.moveTo( rr*Math.cos( th ), -rr*Math.sin( th ) );
for(var i=0; i<size; i++){
if(con_curve[i] == 1){
th = (th - (2*con_init/size) );
rr = con_k + (con_a / Math.cos(th) );
x = rr*Math.cos( th ); y = -rr*Math.sin( th );
context.lineTo(x,y); context.moveTo(x,y);
} else { break; }
}
context.stroke();
context.strokeStyle = "black"
context.translate(0,-size/2);
//if(con_y + 1 == size){ runAnimation.value = false; }
}
setTimeout(function() {
requestAnimFrame(function() {
ConchoidofNicomedes( runAnimation, canvas, context);
});
}, 0);
}
var soa_y = 0;
var soa_theta = 0;
var loop = 4;
var soa_rad = size/(2*Math.PI*loop);
var soa_curve = new Array(size);
for(var i=0; i<size; i++){ soa_curve[i] = 0; }
function SpiralofArchimedes(runAnimation, canvas, context){
if(runAnimation.value) {
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
context.translate(size/2,size/2);
soa_curve[soa_y] = 1;
soa_y = (soa_y + 1)%(size);
soa_theta = (soa_theta + loop*Math.PI/size) % (loop*Math.PI);
if(soa_y == 0){ for(var i=0; i<size; i++){ soa_curve[i] = 0; } }
context.beginPath();
context.moveTo(0,0);
context.lineTo(soa_rad*soa_theta*Math.cos(soa_theta),-soa_rad*soa_theta*Math.sin(soa_theta) );
context.stroke();
context.beginPath();
context.strokeStyle = "red"
var x, y, th;
th = 0;
context.moveTo( 0,0 );
for(var i=0; i<size; i++){
if(soa_curve[i] == 1){
th = th + loop*Math.PI/size;
x = soa_rad*th*Math.cos(th); y = -soa_rad*th*Math.sin(th);
context.lineTo(x,y); context.moveTo(x,y);
} else { break; }
}
context.stroke();
context.strokeStyle = "black"
context.translate(-size/2,-size/2);
//if(soa_y + 1 == size){ runAnimation.value = false; }
}
setTimeout(function() {
requestAnimFrame(function() {
SpiralofArchimedes( runAnimation, canvas, context);
});
}, 0);
}
var cod_y = -size/2;
var cod_curve = new Array(2*size);
var cod_r = size/4;
for(var i=0; i<2*size; i++){ cod_curve[i] = 0; }
function CissoidofDiocles(runAnimation, canvas, context){
if(runAnimation.value) {
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
/*context.beginPath();
context.moveTo(0,cod_y);
context.lineTo(size,cod_y);
context.stroke();*/
context.translate(0,size/2);
context.beginPath();
context.moveTo(0,0);
context.lineTo(size,cod_y - (size/2) );
context.stroke();
context.beginPath();
context.moveTo(0,cod_y - (size/2));
var t = ( cod_y - (size/2) )/size;
var x = size*t*t/(t*t + 1);
context.lineTo(x,x*t);
context.stroke();
cod_curve[cod_y] = 1;
cod_y = (cod_y + 2)%(3*size/2);
if(cod_y == 0){ for(var i=0; i<2*size; i++){ cod_curve[i] = 0; } }
context.beginPath();
context.strokeStyle = "red"
t = ( -size/2 - (size/2) )/size;
x = size*t*t/(t*t + 1);
var y = x*t;
context.moveTo( x,y );
for(var i=(-size/2); i<(3*size/2); i+=2){
if(cod_curve[i] == 1){
t = ( i - (size/2) )/size;
x = size*t*t/(t*t + 1);
y = x*t;
context.lineTo(x,y); context.moveTo(x,y);
} else { break; }
}
context.stroke();
context.strokeStyle = "black"
context.translate(0,-size/2);
//if(cod_y + 2 == (3*size/2) ){ runAnimation.value = false; }
}
setTimeout(function() {
requestAnimFrame(function() {
CissoidofDiocles( runAnimation, canvas, context);
});
}, 0);
}
var cos_init = 2*Math.PI/3;
var cos_y = 0;
var cos_theta = 0;
var cos_rad = size/3;
var cos_curvex = new Array(size);
var cos_curvey = new Array(size);
for(var i=0; i<size; i++){ cos_curvex[i] = 0; cos_curvey[i] = 0; }
function ConchoidofdeSluze(runAnimation, canvas, context){
if(runAnimation.value) {
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
context.translate(size/2,size/2);
context.beginPath();
context.arc(0,0,cos_rad,0,2*Math.PI,0);
context.stroke();
context.beginPath();
context.moveTo(0,0)
context.lineTo(cos_rad,0);
context.stroke();
var angle = (cos_init) - (2*cos_init)*cos_y/size;
var x = cos_rad*Math.cos(angle);
var y = -cos_rad*Math.cos(angle)*Math.tan( angle/2 );
cos_curvex[cos_y] = x;
cos_curvey[cos_y] = y;
cos_y = (cos_y + 1)%(size);
context.beginPath();
context.strokeStyle = "red"
context.moveTo( cos_curvex[0], cos_curvey[0] );
for(var i=0; i< cos_y+1 ; i++){
context.lineTo(cos_curvex[i], cos_curvey[i]); context.moveTo(cos_curvex[i], cos_curvey[i]);
}
context.stroke();
context.strokeStyle = "black"
context.beginPath();
context.moveTo(x,y)
context.lineTo(x,0);
context.stroke();
context.beginPath();
context.moveTo(x,0);
context.lineTo(0,0);
context.stroke();
context.moveTo(x,0);
var toc;
if(y<0){ toc = -Math.sqrt(cos_rad*cos_rad - x*x); }
else{ toc = Math.sqrt(cos_rad*cos_rad - x*x); }
if( Math.abs(angle) > pitwo ){ toc = -toc; }
context.lineTo(x,toc);
context.moveTo(x,toc);
context.lineTo(0,0);
context.moveTo(x,toc);
context.lineTo(cos_rad,0);
context.stroke();
context.beginPath();
context.moveTo(0,0);
var lxy = Math.sqrt(x*x + y*y);
var ad = lxy + ( (toc-y)*y/lxy);
context.lineTo(ad*x/lxy,ad*y/lxy);
context.stroke();
if( Math.abs(angle) < pitwo ){
context.beginPath();
context.moveTo(cos_rad,0);
lxy = Math.sqrt( (cos_rad - x)*(cos_rad - x) + y*y);
ad = lxy + ( (toc-y)*y/lxy);
context.lineTo(cos_rad - ( ad*(cos_rad-x)/lxy ),ad*y/lxy);
context.stroke();
} else {
context.beginPath();
context.moveTo(cos_rad,0);
context.lineTo(x,y);
context.stroke();
context.beginPath();
context.moveTo(0,0);
context.lineTo(x,y);
context.stroke();
}
if( angle < 0 && angle < Math.PI ){
context.beginPath();
context.moveTo(0,0);
var th = Math.acos(x/cos_rad);
context.lineTo(x*Math.cos(th), x*Math.sin(th) );
context.stroke();
}
if( angle > 0 && angle < Math.PI ){
context.beginPath();
context.moveTo(0,0);
var th = Math.acos(x/cos_rad);
context.lineTo(x*Math.cos(th), -x*Math.sin(th) );
context.stroke();
}
context.translate(-size/2,-size/2);
//if(cos_y + 1 == size ){ runAnimation.value = false; }
}
setTimeout(function() {
requestAnimFrame(function() {
ConchoidofdeSluze( runAnimation, canvas, context);
});
}, 0);
}
var tom_y = 0;
var tom_theta1 = 0;
var tom_theta2 = 0;
var tom_rad = size/4;
var tom_curvex = new Array(size);
var tom_curvey = new Array(size);
for(var i=0; i<size; i++){ tom_curvex[i] = 0; tom_curvey[i] = 0; }
function TrisectrixofMaclaurin(runAnimation, canvas, context){
if(runAnimation.value) {
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
context.beginPath();
context.moveTo(0,size/2);
context.lineTo(size,size/2);
context.stroke();
context.translate(size/8 - 1,size/2);
context.beginPath();
var x = size*Math.cos(tom_theta1);
var y = size*Math.sin(tom_theta1);
context.moveTo(-x,-y);
context.lineTo(x,y);
context.stroke();
tom_theta2 = 3*tom_theta1;
context.beginPath();
x = size*Math.cos(tom_theta2);
y = size*Math.sin(tom_theta2);
context.moveTo(-x+tom_rad,-y);
context.lineTo(x+tom_rad,y);
context.stroke();
if(tom_y == 0){ for(var i=0; i<size; i++){ tom_curvex[i] = 0; tom_curvey[i] = 0; } tom_theta1 = 0; }
tom_theta1 = (tom_theta1 - twopi/size) % (twopi);
var r = (tom_rad/2)*( 4*Math.cos(tom_theta1) - (1/Math.cos(tom_theta1) ) );
tom_curvex[tom_y] = r*Math.cos(tom_theta1);
tom_curvey[tom_y] = r*Math.sin(tom_theta1);
tom_y = (tom_y + 1)%(size);
context.beginPath();
context.strokeStyle = "red"
context.moveTo( tom_curvex[0], tom_curvey[0] );
for(var i=0; i< tom_y+1 ; i++){
//drawpoint(context,tom_curvex[i], tom_curvey[i], "red")
if(tom_curvey[i] != 0) context.lineTo(tom_curvex[i], tom_curvey[i]);
context.moveTo(tom_curvex[i], tom_curvey[i]);
}
context.stroke();
context.strokeStyle = "black"
context.translate(-size/8 + 1,-size/2);
//if(tom_y + 1 == size){ runAnimation.value = false; }
}
setTimeout(function() {
requestAnimFrame(function() {
TrisectrixofMaclaurin( runAnimation, canvas, context);
});
}, 0);
}
var woa_y = 0;
var woa_theta = 0;
var woa_rad = size/6;
var woa_curvex = new Array(size);
var woa_curvey = new Array(size);
for(var i=0; i<size; i++){ woa_curvex[i] = 0; woa_curvey[i] = 0; }
function WitchofAgnesi(runAnimation, canvas, context){
if(runAnimation.value) {
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
context.translate(size/2,size/2);
context.beginPath();
context.arc(0,0,woa_rad,0,twopi,0);
context.stroke();
context.beginPath();
context.moveTo(-size/2,woa_rad);
context.lineTo(size/2,woa_rad);
context.stroke();
context.beginPath();
context.moveTo(-size/2,-woa_rad);
context.lineTo(size/2,-woa_rad);
context.stroke();
context.translate(0,woa_rad);
if(woa_y == 0){ for(var i=0; i<size; i++){ woa_curvex[i] = 0; woa_curvey[i] = 0; } woa_theta = 0; }
woa_theta = (woa_theta + Math.PI/size) % (Math.PI);
var x = 2*woa_rad*Math.tan(pitwo - woa_theta);
var y = -2*woa_rad;
context.beginPath();
context.moveTo(0,0);
context.lineTo(x,y);
context.stroke();
var xx = 2*woa_rad*Math.cos(pitwo - woa_theta)*Math.cos(woa_theta);
var yy = -2*woa_rad*Math.cos(pitwo - woa_theta)*Math.sin(woa_theta);
context.beginPath();
context.moveTo(xx,yy);
context.lineTo(x,yy);
context.stroke();
context.beginPath();
context.moveTo(x,yy);
context.lineTo(x,y);
context.stroke();
woa_curvex[woa_y] = x;
woa_curvey[woa_y] = yy;
woa_y = (woa_y + 1)%size
context.beginPath();
context.strokeStyle = "red"
context.moveTo( woa_curvex[0], woa_curvey[0] );
for(var i=0; i< woa_y ; i++){
context.lineTo(woa_curvex[i], woa_curvey[i]);
context.moveTo(woa_curvex[i], woa_curvey[i]);
}
context.stroke();
context.strokeStyle = "black"
context.translate(0,-woa_rad);
context.translate(-size/2,-size/2);
//if(woa_y + 1 == size){ runAnimation.value = false; }
}
setTimeout(function() {
requestAnimFrame(function() {
WitchofAgnesi( runAnimation, canvas, context);
});
}, 0);
}
var cot_init = size/2;
var cot_y = 0;
var cot_theta = Math.PI;
var cot_rad = size/16;
var cot_curvex = new Array(size);
var cot_curvey = new Array(size);
for(var i=0; i<size; i++){ cot_curvex[i] = 0; cot_curvey[i] = 0; }
function CubicofTschirnhausen(runAnimation, canvas, context){
if(runAnimation.value) {
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
context.translate(0,size/2);
context.beginPath();
for(var i=-16; i<16; i+=0.01){
context.lineTo(cot_rad*i*i, cot_rad*2*i);
context.moveTo(cot_rad*i*i, cot_rad*2*i);
}
context.stroke();
var r, x, y;
/*
context.translate(cot_rad,0);
context.strokeStyle = "red"
context.beginPath();
for(var th=-2*Math.PI; th<2*Math.PI; th +=0.01){
r = cot_rad/(Math.pow( Math.cos(th/3),3 ) );
x = -r*Math.cos(th);
y = r*Math.sin(th);
context.lineTo(x,y); context.moveTo(x,y);
}
context.stroke();
context.strokeStyle = "black"
context.translate(-cot_rad,0);
*/
context.beginPath();
context.moveTo(cot_rad,0);
var t = 4*(-cot_init + cot_y)/size;
x = cot_rad*t*t;
y = -cot_rad*2*t;
context.lineTo(x,y);
context.stroke();
cot_curvex[cot_y] = 3*cot_rad*t*t;
cot_curvey[cot_y] = cot_rad*t*(t*t - 3);
var m = y/(x-cot_rad);
var xx = size;
var yy = y - (1/m)*(xx - x);
context.beginPath();
context.moveTo(x,y);
context.lineTo(xx, yy);
context.stroke();
xx = -size;
yy = y - (1/m)*(xx - x);
context.beginPath();
context.moveTo(x,y);
context.lineTo(xx, yy);
context.stroke();
cot_y = (cot_y + 1)%size
cot_theta = (cot_theta + (twopi/size) )%(twopi);
context.strokeStyle = "red"
//context.translate(cot_rad,0);
context.beginPath();
context.moveTo( cot_curvex[0], cot_curvey[0] );
for(var i=0; i< cot_y ; i++){
context.lineTo(cot_curvex[i], cot_curvey[i]);
context.moveTo(cot_curvex[i], cot_curvey[i]);
}
context.stroke();
context.strokeStyle = "black"
//context.translate(-cot_rad,0);
context.translate(0,-size/2);
//if(cot_y + 1 == size){ runAnimation.value = false; }
}
setTimeout(function() {
requestAnimFrame(function() {
CubicofTschirnhausen( runAnimation, canvas, context);
});
}, 0);
}
var lob_y = 0;
var lob_theta = 0;
var lob_rad = size/16;
var lob_curvex = new Array(size);
var lob_curvey = new Array(size);
var lob_size = size/5;
var sq2 = Math.sqrt(2);
for(var i=0; i<size; i++){ lob_curvex[i] = 0; lob_curvey[i] = 0; }
function LemniscateofBernoulli(runAnimation, canvas, context){
if(runAnimation.value) {
context.clearRect(0,0,size,size);
context.strokeRect(0,0,size,size);
//var t = twopi*lob_y/size;
//var xx = sq2*lob_size*Math.cos(t)/(1 + Math.sin(t)*Math.sin(t));
//var yy = sq2*lob_size*Math.cos(t)*Math.sin(t)/(1 + Math.sin(t)*Math.sin(t));
//lob_curvex[lob_y] = xx;
//lob_curvey[lob_y] = yy;
context.translate(size/2,size/2);
var r1 = lob_size/sq2;
context.beginPath();
context.arc(0,0,r1,0,twopi);
context.stroke();
context.beginPath();
context.moveTo(0,0);
var x = r1*Math.cos(lob_theta); var y = -r1*Math.sin(lob_theta)
context.lineTo(x,y);
context.stroke();
var b = lob_size;
context.beginPath();
context.arc(b,0,b,0,twopi);
context.stroke();
if(lob_theta < Math.PI){
var r = Math.sqrt( (x-b)*(x-b) + y*y );
var gam = Math.asin( r1*Math.sin(lob_theta)/r );
var c = lob_size/sq2;
var beta = Math.acos( (r*r + b*b - c*c)/(2*r*b) );
var xx = b + b*Math.cos(Math.PI - gam - beta); var yy = -b*Math.sin(Math.PI - gam - beta);
} else {
var r = Math.sqrt( (x-b)*(x-b) + y*y );
var gam = Math.asin( r1*Math.sin(twopi - lob_theta)/r );
var c = lob_size/sq2;
var beta = Math.acos( (r*r + b*b - c*c)/(2*r*b) );
var xx = b + b*Math.cos(Math.PI + gam + beta); var yy = -b*Math.sin(Math.PI + gam + beta);
}
/*context.beginPath();
context.arc(x,y,c,0,twopi);
context.stroke();*/
context.beginPath();
context.moveTo(b,0);
context.lineTo( xx, yy );
context.lineTo( x, y );
context.lineTo( 2*x - xx, 2*y - yy )
context.stroke();
lob_curvex[lob_y] = 2*x - xx;
lob_curvey[lob_y] = 2*y - yy;
lob_y = (lob_y + 1)%size
lob_theta = (lob_theta + (2*twopi/size) )%(twopi);
context.strokeStyle = "red"
context.beginPath();
context.moveTo( lob_curvex[0], lob_curvey[0] );
for(var i=0; i< lob_y ; i++){
context.lineTo(lob_curvex[i], lob_curvey[i]);
context.moveTo(lob_curvex[i], lob_curvey[i]);
}
context.stroke();
context.strokeStyle = "black"
context.translate(-size/2,-size/2);
//if(lob_y + 1 == size){ runAnimation.value = false; }
}
setTimeout(function() {
requestAnimFrame(function() {
LemniscateofBernoulli( runAnimation, canvas, context);
});
}, 0);
}
function clicker(runAnimation, canvas, context, elemid, animation){
runAnimation = {value: true};
canvas = document.getElementById(elemid);
context = canvas.getContext("2d"); //context.translate(shw, shh);
size = canvas.width;
context.strokeRect(0,0,size,size);
canvas.addEventListener('click', function() {
runAnimation.value = !runAnimation.value;
});
if(runAnimation.value) {
animation(runAnimation, canvas, context);
}
}
function init(){
var runAnimation1, canvas1, context1;
clicker(runAnimation1, canvas1, context1, "canvas1", QuadratrixofHippias);
var runAnimation2, canvas2, context2;
clicker(runAnimation2, canvas2, context2, "canvas2", ConchoidofNicomedes);
var runAnimation3, canvas3, context3;
clicker(runAnimation3, canvas3, context3, "canvas3", SpiralofArchimedes);
var runAnimation4, canvas4, context4;
clicker(runAnimation4, canvas4, context4, "canvas4", CissoidofDiocles);
var runAnimation5, canvas5, context5;
clicker(runAnimation5, canvas5, context5, "canvas5", ConchoidofdeSluze);
var runAnimation6, canvas6, context6;
clicker(runAnimation6, canvas6, context6, "canvas6", TrisectrixofMaclaurin);
var runAnimation7, canvas7, context7;
clicker(runAnimation7, canvas7, context7, "canvas7", WitchofAgnesi);
var runAnimation8, canvas8, context8;
clicker(runAnimation8, canvas8, context8, "canvas8", CubicofTschirnhausen);
var runAnimation9, canvas9, context9;
clicker(runAnimation9, canvas9, context9, "canvas9", LemniscateofBernoulli);
}
</script>
</head>
<body onLoad="init();">
<p>
I think there's a lot in a name, probably because I happen to have an unusual one. Maths seems to yield topics and titles that for some reason always sound interesting to me. A random sample of some recent papers, about which I have no idea: "Non-Abelian Lie algebroids over jet spaces", "The Voevodsky motive of a rank one semiabelian variety", "On Avoiding Sufficiently Long Abelian Squares" using three different versions of Abel's name. Are there jet planes in a jet space? What was Voevodsky's motive; probably not fame. Do short Abelian squares make better company?
</p>
<p>
Some things I do understand which also have great names are the "classic" curves. I think the Quadratrix of Hippias sounds great and I want one to ride around on. Compared to its name it is a sightly disappointing shape. You can use it for trisecting angles and squaring cubes, but since it can't be constructed with ruler and compass it doesn't count as a solution, mathematicians are very picky. Hippias was, according to Plato, vain and boastful. Which goes to show, if you are vain and boastful, invent something useful so people will still be talking about you two and a half thousand years later but write your own biography or people will still mention how vain and boastful you are.
</p>
<p>
The Conchoid of Nicomedes takes its name from another Greek, who seems to have left only this to the world with no record of how vain and boastful he was. The word conchoid is supposed to recall a conch shell, the idea being that if you stack a lot of these they look something like the patterns on a mussel. Archimedes and his spiral are very famous compared to the other two but despite writing a whole book about them they were first studied by Conon (the barbarian). Often priority is not enough to get your name attached to something, even if then Spiral of Conon sounds better.
</p>
<p>
The second row are all examples of a family of Conchoids called Conchoids of de Sluze, named after a <a href="http://www.famousbelgians.net/">famous Belgian</a>. The word Cissoid means <i>ivy-like</i> which it isn't. Strophoid means <i>belt with a twist</i> which is a strange thing to have a single word for. Trisectrix is the feminine curve that divides an angle in three, much like the Quadratrix of Hippias but a little more complicated.
</p>
<p>
The Witch of Agnesi is called a Lorentzian by physicists. Why it's called a Witch is apparently a (hilarious) pun in Latin and probably stuck because Agnesi was a woman and 18$^{th}$ century mathematicians weren't too sensitive to the gender bias in their field. Tschirnhausen, as well as having a very difficult name to spell, invented porcelain in Europe, which is quite a bit more impressive than this funny curve but unfortunately he didn't market himself well enough and someone else's name became attached to the discovery. Bernoulli (all of them) is very famous, the word lemniscate isn't but should be, it means <i>decorated with ribbons</i>.
</p>
</BR>
<div id="Curves1" style="float:left; width:910px; height: 350px">
<div id="h1" style="margin-right: 0px; margin-top:0px; margin-bottom: 0px; margin-left: 35px; width:300px; height: 20px"><head>Quadratrix of Hippias</head></div>
<canvas id="canvas1" width="300px" height="300px" style="float: left; width: 300px;"></canvas>
<div id="h2" style="position:relative;
width: 300px;
height: 20px;
top: -320px;
left: 300px; margin-left: 35px;"><head>Conchoid of Nicomedes</head></div>
<div id="c2" style="position:relative;
width: 300px;
height: 300px;
top: -300px;
left: 300px;">
<canvas id="canvas2" width="300px" height="300px" style="float: left; width: 300px;"></canvas>
</div>
<div id="h3" style="position:relative;
width: 300px;
height: 20px;
top: -620px;
left: 600px; margin-left: 0px;"><head>Spiral of Archimedes</head></div>
<div id="c3" style="position:relative;
width: 300px;
height: 300px;
top: -600px;
left: 600px;">
<canvas id="canvas3" width="300px" height="300px" style="float: left; width: 300px;"></canvas>
</div>
</div>
<div id="Curves2" style="float:left; width:910px; height: 350px">
<div id="h4" style="margin-right: 0px; margin-top:0px; margin-bottom: 0px; margin-left: 35px; width:300px; height: 20px"><head>Cissoid of Dioceles</head></div>
<canvas id="canvas4" width="300px" height="300px" style="float: left; width: 300px;"></canvas>
<div id="h5" style="position:relative;
width: 300px;
height: 20px;
top: -320px;
left: 300px; margin-left: 35px;"><head>Strophoid of Newton</head></div>
<div id="c5" style="position:relative;
width: 300px;
height: 300px;
top: -300px;
left: 300px;">
<canvas id="canvas5" width="300px" height="300px" style="float: left; width: 300px;"></canvas>
</div>
<div id="h6" style="position:relative;
width: 300px;
height: 20px;
top: -620px;
left: 600px; margin-left: 35px;"><head>Trisectrix of Maclaurin</head></div>
<div id="c6" style="position:relative;
width: 300px;
height: 300px;
top: -600px;
left: 600px;">
<canvas id="canvas6" width="300px" height="300px" style="float: left; width: 300px;"></canvas>
</div>
</div>
<div id="Curves3" style="float:left; width:910px; height: 350px">
<div id="h7" style="margin-right: 0px; margin-top:0px; margin-bottom: 0px; margin-left: 35px; width:300px; height: 20px"><head>Witch of Agnesi</head></div>
<canvas id="canvas7" width="300px" height="300px" style="float: left; width: 300px;"></canvas>
<div id="h8" style="position:relative;
width: 300px;
height: 20px;
top: -320px;
left: 300px; margin-left: 0px;"><head>Cubic of Tschirnhausen</head></div>
<div id="c8" style="position:relative;
width: 300px;
height: 300px;
top: -300px;
left: 300px;">
<canvas id="canvas8" width="300px" height="300px" style="float: left; width: 300px;"></canvas>
</div>
<div id="h9" style="position:relative;
width: 300px;
height: 20px;
top: -620px;
left: 600px; margin-left: 35px;"><head>Lemniscate of Bernoulli</head></div>
<div id="c9" style="position:relative;
width: 300px;
height: 300px;
top: -600px;
left: 600px;">
<canvas id="canvas9" width="300px" height="300px" style="float: left; width: 300px;"></canvas>
</div>
</div>
<p>
A note on the construction of these for those who are interested (if you are really interested you can right click and view the source and see that I should have defined some more classes and functions to make my life easier when drawing these):
<ul>
<li>Quadratrix of Hippias: Move a line segment down and a radius around a quadrant at a uniform rate so they reach the bottom at the same time. The intersection of radius and line defines the curve.</li>
<li>Conchoid of Nicomedes: Draw a line from a point O to a point on a line X and add an extra distance k with the same slope as X varies down the line.</li>
<li>Spiral of Archimedes: Starting from zero rotate around the origin and draw a line whose length is proportional to the angle. The end of the line traces out the spiral.</li>
<li>Cissoid of Dioceles: Given a point O and a line L draw a line parallel to L through O. Let point on P vary on L
and the projection of P onto the line through O be Q. R is the intersection of the line through Q perpendicular to OP
and the points R trace the curve.</li>
<li>Strophoid of Newton: The position of the orthocentre of a triangle with base given by a radius and the third vertex
varying around the circle.</li>
<li>Trisectrix of Maclaurin: The intersection points of two lines; one spinning three times as fast as the other.</li>
<li>Witch of Agnesi: Draw a line from the base of the circle to the upper line and construct a right triangle with
hypotenuse given by the line segment outside the circle, the third vertex traces the curve.</li>
<li>Cubic of Tschirnhausen: The negative pedal curve of the parabola (look it up).</li>
<li>Lemniscate of Bernoulli: This one is neat. I am using something called Watt's linkage. We stick three rigid rods together: a small one which rotates uniformly around a circle $a$; a longer one fixed at the centre of a different circle $b$ and a final even longer one $c$. We attach one end of $c$ to the free point of $b$ and the midpoint of $c$ to the free end of $a$. As $a$ rotates the free end of $c$ traces the curve!</li>
</ul>
</p>
</body>Anonymoushttp://www.blogger.com/profile/14363557083424911304noreply@blogger.com0