Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html>
- <head>
- <title>Frame multiplication</title>
- </head>
- <body>
- <h1>Frame multiplication</h1>
- Frames are boolean-valued matrices. They can be implemented densely or sparsely. This implementation is dense.
- <p>
- <table>
- <tr>
- <td valign="top">
- <canvas id="matrix0" width="300" height="300" style="border:1px solid #c3c3c3;" onclick="click(0)">
- Your browser does not support the HTML5 canvas tag.</canvas><br>
- </td>
- <td valign="center">×</td>
- <td valign="top">
- <canvas id="matrix1" width="300" height="300" style="border:1px solid #c3c3c3;" onclick="click(1)">
- Your browser does not support the HTML5 canvas tag.</canvas><br>
- </td>
- <td valign="center">=</td>
- <td valign="top">
- <canvas id="matrix2" width="300" height="300" style="border:1px solid #c3c3c3;"></canvas>
- </td>
- </tr>
- <tr>
- <td valign="top">
- <button onclick="make('empty', 0)">empty</button>
- <button onclick="make('diagonal', 0)">diagonal</button>
- <button onclick="make('full', 0)">full</button>
- <button onclick="make('random', 0)">random</button>
- <button onclick="make('opposite', 0)">opposite</button>
- <button onclick="make('predicate', 0)">predicate</button>
- <button onclick="make('transpose', 0)">transpose</button>
- <form action="">
- <br>
- Number of random pixels:<br>
- <input type="number" id="random0" value="10"><br><br>
- Custom predicate:<br>
- <input type="text" id="predicate0" value="(i+j)%3 == 1">
- </form>
- </td>
- <td></td>
- <td valign="top">
- <button onclick="make('empty', 1)">empty</button>
- <button onclick="make('diagonal', 1)">diagonal</button>
- <button onclick="make('full', 1)">full</button>
- <button onclick="make('random', 1)">random</button>
- <button onclick="make('opposite', 1)">opposite</button>
- <button onclick="make('predicate', 1)">predicate</button>
- <button onclick="make('transpose', 1)">transpose</button>
- <form action="">
- <br>
- Number of random pixels:<br>
- <input type="number" id="random1" value="10"><br><br>
- Custom predicate:<br>
- <input type="text" id="predicate1" value="(i+j)%3 == 1">
- </form>
- </td>
- <td></td>
- <td valign="top">
- <button onclick="make('transpose', 2)">transpose</button>
- <form action="">
- <br>
- Kind of addition:
- <input type="radio" name="addition" value="OR" checked="checked" onclick="changeAddition('OR')"> OR
- <input type="radio" name="addition" value="XOR" onclick="changeAddition('XOR')"> XOR
- </form>
- </td>
- </tr>
- </table>
- <script>
- var n = 10;
- var resn = 300;
- function Frame() {
- this.data = []; // n*n array
- for (i = 0; i < n; i++) {
- this.data[i] = [];
- for (j = 0; j < n; j++) {
- this.data[i][j] = false;
- }
- }
- this.dot = function(frame) {
- new_frame = new Frame();
- for (i = 0; i < n; i++) {
- for (j = 0; j < n; j++) {
- new_frame.data[i][j] = false;
- for (k = 0; k < n; k++) {
- if (this.data[i][k] && frame.data[k][j]) {
- new_frame.data[i][j] = true;
- }
- }
- }
- }
- return new_frame;
- }
- this.altdot = function(frame) {
- new_frame = new Frame();
- for (i = 0; i < n; i++) {
- for (j = 0; j < n; j++) {
- new_frame.data[i][j] = false;
- for (k = 0; k < n; k++) {
- if (this.data[i][k] && frame.data[k][j]) {
- new_frame.data[i][j] = !new_frame.data[i][j];
- }
- }
- }
- }
- return new_frame;
- }
- this.draw = function(ctx) {
- ctx.clearRect(0, 0, resn, resn);
- ctx.fillStyle = "#000000";
- ctx.strokeStyle = "#eeeeee";
- ctx.lineWidth = 1;
- for (i = 1; i < n; i++) {
- ctx.moveTo(resn*i/n, 0);
- ctx.lineTo(resn*i/n, resn);
- ctx.stroke();
- ctx.moveTo(0, resn*i/n);
- ctx.lineTo(resn, resn*i/n);
- ctx.stroke();
- }
- for (i = 0; i < n; i++) {
- for (j = 0; j < n; j++) {
- if (this.data[i][j]) {
- ctx.fillRect(resn*j/n, resn*i/n, resn/n, resn/n);
- }
- }
- }
- }
- this.makeEmpty = function() {
- for (i = 0; i < n; i++) {
- for (j = 0; j < n; j++) {
- this.data[i][j] = false;
- }
- }
- }
- this.makeDiagonal = function() {
- for (i = 0; i < n; i++) {
- for (j = 0; j < n; j++) {
- this.data[i][j] = i == j;
- }
- }
- }
- this.makeFull = function() {
- for (i = 0; i < n; i++) {
- for (j = 0; j < n; j++) {
- this.data[i][j] = true;
- }
- }
- }
- this.makeRandom = function(many) {
- this.makeEmpty();
- for (k = 0; k < many && k < n*n; k++) { // TODO
- do {
- i = Math.floor((Math.random() * n));
- j = Math.floor((Math.random() * n));
- } while (this.data[i][j]);
- this.data[i][j] = true;
- }
- }
- this.makeOpposite = function() {
- for (i = 0; i < n; i++) {
- for (j = 0; j < n; j++) {
- this.data[i][j] = !this.data[i][j];
- }
- }
- }
- this.makePredicate = function(pred) {
- for (i = 0; i < n; i++) {
- for (j = 0; j < n; j++) {
- this.data[i][j] = eval(pred);
- }
- }
- }
- this.makeTranspose = function(pred) {
- new_data = [];
- for (i = 0; i < n; i++) {
- new_data[i] = [];
- for (j = 0; j < n; j++) {
- new_data[i][j] = this.data[j][i];
- }
- }
- this.data = new_data;
- }
- }
- var c = [document.getElementById("matrix0"),
- document.getElementById("matrix1"),
- document.getElementById("matrix2")];
- var ctx = [c[0].getContext("2d"),
- c[1].getContext("2d"),
- c[2].getContext("2d")];
- frames = [new Frame, new Frame, new Frame];
- make('empty', 0);
- make('diagonal', 1);
- recalculate();
- c[0].addEventListener('click', function(event) { click(0, event); }, false);
- c[1].addEventListener('click', function(event) { click(1, event); }, false);
- function make(what, i) {
- if (what === 'empty') frames[i].makeEmpty();
- if (what === 'diagonal') frames[i].makeDiagonal();
- if (what === 'full') frames[i].makeFull();
- if (what === 'random') {
- var many = document.getElementById("random"+i).value;
- frames[i].makeRandom(many);
- }
- if (what === 'opposite') frames[i].makeOpposite();
- if (what === 'predicate') {
- var pred = document.getElementById("predicate"+i).value;
- frames[i].makePredicate(pred);
- }
- if (what === 'transpose') {
- if (i == 0 || i == 1) {
- frames[i].makeTranspose();
- } else { // i == 2
- frames[0].makeTranspose();
- frames[1].makeTranspose();
- [frames[0], frames[1]] = [frames[1], frames[0]];
- }
- }
- recalculate();
- }
- function click(i, event) {
- if (event.isTrusted) {
- var rect = c[i].getBoundingClientRect();
- var x = event.clientX - rect.left;
- var y = event.clientY - rect.top;
- var j = Math.max(0, Math.min(n-1, Math.floor(y * n / resn)));
- var k = Math.max(0, Math.min(n-1, Math.floor(x * n / resn)));
- frames[i].data[j][k] = !frames[i].data[j][k];
- frames[i].draw(ctx[0]);
- recalculate();
- }
- }
- var addition = 'OR';
- function changeAddition(newAddition) {
- addition = newAddition;
- recalculate();
- }
- function recalculate() {
- if (addition === 'OR') {
- frames[2] = frames[0].dot(frames[1]);
- } else { // addition === 'XOR'
- frames[2] = frames[0].altdot(frames[1]);
- }
- frames[0].draw(ctx[0]);
- frames[1].draw(ctx[1]);
- frames[2].draw(ctx[2]);
- }
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement