Waterfall with createImageData (2)

By using getImageData and putImageData with an appropriate offset value, you do not have to explicitly shift the data in imgData.

index.html

<!doctype html>
<html>
<head>
<script src='/socket.io/socket.io.js'></script>
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<script>
var nxdata  = 32;
var nydata  = 32;
var myarray = Array(nxdata);
var mytable = Array(nxdata * nydata);
var socket  = io();
var canvas;
var ctx;
var imgData;

window.addEventListener("load", init);

function init() {
  canvas = document.getElementById('myCanvas');
  ctx    = canvas.getContext('2d');
    imgData = ctx.createImageData(512, 512);
    for (i = 0; i < 512; i++) {
      for (j = 0; j < 512; j++) {
        imgData.data[0 + j * 4 + i * imgData.width * 4] = j % 256;
        imgData.data[1 + j * 4 + i * imgData.width * 4] = (255 - (i % 256));
        imgData.data[2 + j * 4 + i * imgData.width * 4] =
            ((i / 2 + j / 2) % 256);
        imgData.data[3 + j * 4 + i * imgData.width * 4] = 255;
      }
    }
    ctx.putImageData(imgData, 0, 0);
}

function emitParticles(myarray) {
  ctx.putImageData(imgData, 0, 1);
  imgData = ctx.getImageData(0, 0, 512, 512);
  for (j = 0; j < 512; j++) {
    imgData.data[0 + j * 4] = (myarray[(j>>4)%8] - 48) * 32 % 256;
    imgData.data[1 + j * 4] = j % 256;
    imgData.data[2 + j * 4] = 0;
    imgData.data[3 + j * 4] = 255;
  }
}

socket.on('time', function(data) {
  myarray = data.buffer;
  emitParticles(myarray);
});
</script>
</head>

<body>
    <canvas id="myCanvas" width="512" height="512" style="background:white;"></canvas>
    <p id='messages'></p>
</body>
</html>

Waterfall with createImageData

A more natural way to draw waterfall pictures is to use the methods, createImageData, getImageData, and putImageData.

index.html

<!doctype html>
<html>
<head>
<script src='/socket.io/socket.io.js'></script>
<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script>
<script>
var nxdata  = 32;
var nydata  = 32;
var myarray = Array(nxdata);
var mytable = Array(nxdata * nydata);
var socket  = io();
var canvas;
var ctx;
var imgData;

window.addEventListener("load", init);

function init() {
  console.log('init..');
  canvas = document.getElementById('myCanvas');
  ctx    = canvas.getContext('2d');

  if (canvas.getContext && canvas.getContext('2d').createImageData) {
    imgData = ctx.createImageData(512, 512);
    for (i = 0; i < 512; i++) {
      for (j = 0; j < 512; j++) {
        imgData.data[0 + j * 4 + i * imgData.width * 4] = j % 256;
        imgData.data[1 + j * 4 + i * imgData.width * 4] = (255 - (i % 256));
        imgData.data[2 + j * 4 + i * imgData.width * 4] =
            ((i / 2 + j / 2) % 256);
        imgData.data[3 + j * 4 + i * imgData.width * 4] = 255;
      }
    }
    ctx.putImageData(imgData, 0, 0);
  }
}

var count  = 0;
var marker = 0;
function emitParticles(myarray) {
  count++;
  if (count % 128 == 0) {
    marker = 255;
    count  = 0;
  } else {
    marker = 0;
  }
  for (j = 0; j < 512; j++) {
    imgData.data[0 + j * 4 + (512 - 1) * imgData.width * 4] = marker;
    imgData.data[1 + j * 4 + (512 - 1) * imgData.width * 4] = 0;
    imgData.data[2 + j * 4 + (512 - 1) * imgData.width * 4] =
        (32 * myarray[(j >> 3) % 10]) % 256;
    imgData.data[3 + j * 4 + (512 - 1) * imgData.width * 4] = 255;
  }

  for (i = 0; i < 512 - 1; i++) {
    for (j = 0; j < 512; j++) {
      for (k = 0; k < 4; k++) {
        imgData.data[k + j * 4 + i * imgData.width * 4] =
            imgData.data[k + j * 4 + (i + 1) * imgData.width * 4];
      }
    }
  }

  ctx.putImageData(imgData, 0, 0);
}

socket.on('time', function(data) {
  myarray = data.buffer;
  emitParticles(myarray);
});
</script>
</head>

<body>
    <canvas id="myCanvas" width="512" height="512" style="background:white;">
    </canvas>
    <p id='messages'></p>
</body>
</html>

Animation with WebGL and Three.js (5)

omega01pi

Please click the image for real-time animation.

Yet another simple case is when I1=I2≠I3. Again from Landau and Lifshitz:

eq36-6

Here is a nice figure from the MIT OpenCourseWare Course.

https://ocw.mit.edu/courses/aeronautics-and-astronautics/16-07-dynamics-fall-2009/lecture-notes/MIT16_07F09_Lec29.pdf

peraire

The simulation parameters are:

Ibody.set(1,0,0, 0,1,0, 0,0,2);
L.set(00, 01, 2.0*Math.PI);

The value of ω in equation (36.6), therefore, becomes pi, while A (=√ Ω1^2 + Ω2^2) becomes 1.0. See the curves of, wx, wy, wz in the graph.

Animation with WebGL and Three.js (4)

omega123

Let’s see with some of the special cases. Again from Landau and Lifshitz:

eq36-5

Obviously, the simplest case occurs when I1=I2=I3, in which case Omega becomes a constant vector, as is shown in the figure. The parameters employed are:

Ibody.set(1,0,0, 0,1,0, 0,0,1);
L.set(1, 2, 3);

If we let

L.set(1, 1, 1);

we will get:

omega111

Note that the scale of the y-axis is largely different in two figures.

Animation with WebGL and Three.js (3)

stable

Please click the image for real-time animation.

The parameters are:

Ibody.set(1,0,0, 0,1,0, 0,0,2);
L.set(2.0*Math.PI*0.0,2.0*Math.PI*0.0,2.0*Math.PI*5.0);
var dt = 1.0/1000.0;

So the body should rotate 2.5 times per second, and this is what is happening in the simulation. The graph shows the components of the unit quaternion, which rotates only 1.25 times per second.

euler

In the real-time animation, the body rotates rather slowly, but it is because the frame rate is only 30fps.

Animation with WebGL and Three.js (2)

monolith3

Please click either an unstable case or a stable case.

The source code may include some errors, bat basically it seems to be OK. I am not sure if I really have to write functions matrix4_from_matrix3() and matrix3_from_matrix4().

Please check the following documents, if you are in doubt.

https://threejs.org/docs/api/math/Vector3.html
https://threejs.org/docs/api/math/Quaternion.html
https://threejs.org/docs/api/math/Matrix3.html
https://threejs.org/docs/api/math/Matrix4.html

<html>
	<head>
		<title>My first Three.js app</title>
		<style>
			body { margin: 0; }
			canvas { width: 100%; height: 100% }
		</style>
	</head>
	<body>
		<script src="https://ajax.googleapis.com/ajax/libs/threejs/r76/three.min.js"></script>
		<script>
			function matrix4_from_matrix3 (m4, m3) {
				var se = m3.elements;
				var te = m4.elements;
				te[0] = se[0]; te[4] = se[3]; te[ 8] = se[6]; te[12] = 0;
				te[1] = se[1]; te[5] = se[4]; te[ 9] = se[7]; te[13] = 0;
				te[2] = se[2]; te[6] = se[5]; te[10] = se[8]; te[14] = 0;
				te[3] = 0;     te[7] =     0; te[11] =     0; te[15] = 0;
			}
			function matrix3_from_matrix4 (m3, m4) {
				var se = m4.elements;
				var te = m3.elements;
				te[0] = se[0]; te[3] = se[4]; te[6] = se[ 8];
				te[1] = se[1]; te[4] = se[5]; te[7] = se[ 9];
				te[2] = se[2]; te[5] = se[6]; te[8] = se[10];
			}

			var scene = new THREE.Scene();
			var camera = new THREE.PerspectiveCamera(7, window.innerWidth/window.innerHeight, 0.1, 1000 );

			var renderer = new THREE.WebGLRenderer();
			renderer.setSize( window.innerWidth, window.innerHeight );

			document.body.appendChild( renderer.domElement );

			var geometry = new THREE.BoxGeometry( 4, 9, 1 );

			var material2= new THREE.MeshLambertMaterial( { color: 0xf01010 } );
			var cube= new THREE.Mesh( geometry, material2 );
			cube.position.x = 0.0;
			scene.add( cube );


			var geometry0= new THREE.BoxGeometry( 1000, 1000, 1);
			var material0 = new THREE.MeshBasicMaterial( { color: 0x101040 } );
			var cube0 = new THREE.Mesh( geometry0, material0 );
			cube0.position.z = -10;
			scene.add( cube0 );

			camera.position.x = 100;
			camera.position.y = 100;
			camera.position.z = 250;
			camera.lookAt(cube.position);
			scene.add( camera );

			var light = new THREE.DirectionalLight(0xffffff);
			light.position.set(250, 250, 250);
			scene.add( light );
			var light0 = new THREE.AmbientLight( 0x404040 );
			scene.add( light0  );

			var Ibody     = new THREE.Matrix3();
			var IbodyInv  = new THREE.Matrix3();
			var IbodyInv4 = new THREE.Matrix4();
			Ibody.set(82,0,0, 0,17,0, 0,0,97);
			IbodyInv.getInverse(Ibody);
			matrix4_from_matrix3 (IbodyInv4, IbodyInv);

			var q    = new THREE.Quaternion();
			var qq   = new THREE.Quaternion();
			var qdot = new THREE.Quaternion();
			var axis = new THREE.Vector3(0,1,0).normalize();
			var angle = Math.PI * 0.0;
			q.setFromAxisAngle(axis,angle);
			var x, y, z, w;

			var L  = new THREE.Vector3();
			var L4 = new THREE.Vector4();
			L.set(13.0*2.0*Math.PI*82.0,2.0*Math.PI*0.1,2.0*Math.PI*0.1);
			L4.set(L.x, L.y, L.z, 0);

			var omega = new THREE.Vector3();
			var R     = new THREE.Matrix3();
			var RInv  = new THREE.Matrix3();
			var IInv  = new THREE.Matrix3();

			var R4    = new THREE.Matrix4();
			var RInv4 = new THREE.Matrix4();
			var IInv4 = new THREE.Matrix4();

			var dt = 0.001;

			var render = function () {
				requestAnimationFrame( render );
				x = q.x; y = q.y; z = q.z; w = q.w;
				R.set(1.0-2.0*y*y-2.0*z*z, 2.0*x*y+2.0*w*z, 2.0*x*z-2.0*w*y,
				      2.0*x*y-2.0*w*z, 1.0-2.0*x*x-2.0*z*z, 2.0*y*z+2.0*w*x,
				      2.0*x*z+2.0*w*y, 2.0*y*z-2.0*w*x, 1.0-2.0*x*x-2.0*y*y);
				RInv.getInverse(R);
				matrix4_from_matrix3 (R4   , R   );
				matrix4_from_matrix3 (RInv4, RInv);
//				IInv = R * IbodyInv * RInv;
				IInv4.multiplyMatrices(R4, IbodyInv4);
				IInv4.multiply        (RInv4);
				matrix3_from_matrix4 (IInv, IInv4);
//				omega = IInv * L;
				omega.copy(L);
				omega.applyMatrix3(IInv);
				qq.set(omega.x/2.0, omega.y/2.0, omega.z/2.0, 0.0);
//				qdot = qq * q;
				qdot.multiplyQuaternions(qq, q);
//				q += qdot * dt;
				q.set(q.x+qdot.x*dt, q.y+qdot.y*dt, q.z+qdot.z*dt, q.w+qdot.w*dt);
				q.normalize();
				cube.rotation.setFromQuaternion(q);
				renderer.render(scene, camera);
			}

			render();
		</script>
	</body>
</html>

IC-7410 Audio Interface and ALSA (2)

pcm2

For the playback, IC-7410 seems to accept the audio data at least with three different sample rates, namely 32kHz, 44.1kHz and 48kHz.

pcm3

It does not work with these sample rates.

You can hear the sound with the Monitor function of IC-7410, if you set the “DATA OFF MOD (menu item no. 40)” to “USB”, and push the “TRANSMIT SWITCH” on, preferably using a dummy load.

% cp ./alsa-lib-1.0.28/test/pcm.c pcm2.c
% gcc pcm2.c -o pcm -lasound
(you need "asoundlib.h", which you can find in "alsa-lib-1.0.28/include".)

A URI or a URL?

uri-res-rep

The World Wide Web (WWW, or simply Web) is an information space in which the items of interest, referred to as resources, are identified by global identifiers called Uniform Resource Identifiers (URI).

Architecture of the World Wide Web, Volume One
W3C Recommendation 15 December 2004

capture_001_03092014_213655

Therefore, you say “cool URIs”, but not “cool URLs”, if you are strict in using technical terms.

Blog to Ebook Conversion (6)

Now you have a file that contains just one article, and you wish to extract three things out of each file, which are:

  • Title
  • Date
  • Text

Assume again that you find by inspection of the files that they are contained in the lines like this:

<h2><a href="...">Need to repare my rig</a></h2>
<div class="entry_text">When I switched on my rig this morning...</div>
<li>[2014/03/01 05:43]

A short awk program will do the job for you to convert the files into html format which can then be fed to Ebook authoring tools.