高確率で思い込みによる説明.間違っていることが多い./「無知だったり、勘違いしていたり、底意を押しつけたり、いいかげんだったり、噂や疑惑を信じていたりして、狂気じみてさえいるかもしれません」( http://bit.ly/gs23zg )
2015年3月28日土曜日
2013年10月23日水曜日
WebGLのTextureをCanvasに文字(Web Fonts)を書いて動的に作ってみる(jQuery/ThreeJS使用, Firefox 24.0/Safari 6.0.5で動作)
tumblrにも書いたが,こっちにも書いておく.
以前にも試みたがリンク先の情報がなくなったりFirefoxでの動作に問題があったりしたので再挑戦.
以前にも試みたがリンク先の情報がなくなったりFirefoxでの動作に問題があったりしたので再挑戦.
<html> <head> <meta http-equiv="content-type" content="text/html;charset=UTF-8" /> <link href='http://fonts.googleapis.com/css?family=Ewert' rel='stylesheet' type='text/css'> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js" type="text/javascript"></script> <script src="http://mrdoob.github.com/three.js/build/three.min.js" type="text/javascript"></script> <script type="text/javascript"> var camera, scene, renderer, mesh, cube; function resize() { camera.aspect= window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } function animate() { requestAnimationFrame(animate); var time= Date.now() * 0.001; if(mesh) { mesh.rotation.x= -time; mesh.rotation.y= time; var imagedata= createImageData('Hello, World!! ' + (time % 1000).toFixed(2), { r: 0, g: 0, b: 255, }, 35); var texture= createTexture(imagedata); mesh.material.map= texture; } var time= Date.now() * 0.0005; if(cube) { cube.rotation.x= time; cube.rotation.y= time; } renderer.render(scene, camera); } function init() { camera= new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 2000); camera.position.z= 10; scene= new THREE.Scene(); scene.add(camera); renderer= new THREE.WebGLRenderer({ antialias: true }); $('#endpoint').append($(renderer.domElement)); cube= new THREE.Mesh(new THREE.CubeGeometry(1, 1, 1), new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true, })); scene.add(cube); cube.scale.x= 2; cube.scale.y= 2; cube.scale.z= 2; cube.position.z= -5; var geometry= new THREE.PlaneGeometry(1, 1); var material= new THREE.MeshBasicMaterial({ transparent: true, }); mesh= new THREE.Mesh(geometry, material); scene.add(mesh); mesh.scale.x= 5; mesh.scale.y= 5; } function createTexture(imagedata) { var w= imagedata.width; var h= imagedata.height; var size= w * h; var data= new Uint8Array(4 * size); for(var i= 0; i < size; i++) { data[i * 4 + 0]= imagedata.data[i * 4 + 0]; data[i * 4 + 1]= imagedata.data[i * 4 + 1]; data[i * 4 + 2]= imagedata.data[i * 4 + 2]; data[i * 4 + 3]= imagedata.data[i * 4 + 3]; } var texture= new THREE.DataTexture(data, w, h, THREE.RGBAFormat); texture.needsUpdate= true; return texture; } function createImageData(message, color, fontsize) { var c4tex= $('#hiddenCanvas').get(0); var w= $(c4tex).width(); var h= $(c4tex).height(); var ctx= c4tex.getContext('2d'); ctx.clearRect(0, 0, w, h); ctx.fillStyle= 'rgba(' + color.r + ',' + color.g + ',' + color.b + ',.1)'; ctx.fillRect(0, 0, w, h); ctx.fillStyle= 'rgba(' + color.r + ',' + color.g + ',' + color.b + ',1.0)'; ctx.font= fontsize + 'px \'Ewert\''; ctx.fillText(message, (w - ctx.measureText(message).width) * .5, (h + fontsize) * .5); return ctx.getImageData(0, 0, w, h); } $(document).ready(function() { $(window).resize(function() { resize(); }); init(); animate(); resize(); }); </script> </head> <body style="margin: 0; padding: 0;"> <div id="endpoint"></div> <canvas id="hiddenCanvas" width="512" height="512" style="display: none;"></canvas> </body> </html>
- CanvasからtoDataURLメソッドを用いて,Data URI Schemeの形で得た値を返して,THREE.ImageUtils.loadTextureメソッドで生成しようとするとCORS(Cross-Origin Resource Sharing)的問題で引っかかる.
- また,Canvasの2DコンテクストからgetImageDataメソッドを用いて作ったImageData.dataを直接THREE.DataTexture.image.dataに突っ込んでも動作しなかった(私の間違いか,やはりCORS的なナニカか,わからないけど).
ラベル:
canvas,
javascript,
webfonts,
WebGL
2013年6月9日日曜日
Blockly+linda.jsなこと(linda-arduino-sensorの値をとるコードを作成してみた)
(ブロックの表記は'温度計の値を読む'とかにして,内部でjsコードが正しくできあがるって方向に進めると良さげなんだろう.たぶん)
Result:
How:
Result:
- lindaについての@shokaiさんの記事
- linda-arduino-sensor
- 'linda.io.on'関連を書いてないんだけど動いちゃった.
How:
1. blockly(-read-only)
2. jquery.min.jssvn checkout http://blockly.googlecode.com/svn/trunk/ blockly-read-only
3. index.html (based on blockly-read-only/demos/generator/index.html)
'rpi.local'はlinda-baseが動いているマシン
<html> <head> <meta charset="utf-8"> <title>blocky - linda</title> <script type="text/javascript" src="blockly-read-only/blockly_compressed.js"></script> <script type="text/javascript" src="blockly-read-only/en_compressed.js"></script> <script type="text/javascript" src="blockly-read-only/javascript_compressed.js"></script> <script type="text/javascript" src="./language_linda.js"></script> <script type="text/javascript" src="./language_utility.js"></script> <script src="./jquery.min.js"></script> <script src="http://rpi.local:5000/rocketio/linda.js"></script> <script> var linda= new Linda(); </script> <style> body { background-color: white; font-family: sans-serif; } h1 { font-weight: normal; font-size: 140%; } </style> </head> <body> <p> <button onclick="showCode()"> Show JavaScript </button> <button onclick="runCode()"> Run JavaScript </button> </p> <div id="blocklyDiv" style="height: 480px; width: 600px;"></div> <xml id="toolbox" style="display: none"> <category name="Control"> <block type="controls_if"></block> <block type="controls_repeat_ext"> <value name="TIMES"> <block type="math_number"> <title name="NUM">10</title> </block> </value> </block> <block type="controls_whileUntil"></block> </category> <category name="Logic"> <block type="logic_compare"></block> <block type="logic_operation"></block> <block type="logic_negate"></block> <block type="logic_boolean"></block> </category> <category name="Math"> <block type="math_number"></block> <block type="math_arithmetic"></block> <block type="math_single"></block> </category> <category name="Text"> <block type="text"></block> <block type="text_length"></block> <block type="text_print"></block> </category> <category name="Variables" custom="VARIABLE"></category> <category name="List"> <block type="lists_create_empty"></block> <block type="lists_create_with"></block> <block type="lists_repeat"> <value name="NUM"> <block type="math_number"> <title name="NUM">5</title> </block> </value> </block> <block type="lists_length"></block> <block type="lists_isEmpty"></block> <block type="lists_indexOf"> <value name="VALUE"> <block type="variables_get"> <title name="VAR">list</title> </block> </value> </block> <block type="lists_getIndex"> <value name="VALUE"> <block type="variables_get"> <title name="VAR">list</title> </block> </value> </block> <block type="lists_setIndex"> <value name="LIST"> <block type="variables_get"> <title name="VAR">list</title> </block> </value> </block> <block type="lists_getSublist"> <value name="LIST"> <block type="variables_get"> <title name="VAR">list</title> </block> </value> </block> </category> <category name="Linda"> <block type="linda_createTupleSpace"> <value name="TupleSpace"> <block type="text"> <title name="TEXT">myhome</title> </block> </value> </block> <block type="linda_watch"> <title name="LIST">tuple</title> </block> </category> <category name="Utility"> <block type="utility_log"></block> </category> </xml> <script> Blockly.inject(document.getElementById('blocklyDiv'), { path: 'blockly-read-only/', toolbox: document.getElementById('toolbox') }); function showCode() { // Generate JavaScript code and display it. Blockly.JavaScript.INFINITE_LOOP_TRAP= null; var code= Blockly.Generator.workspaceToCode('JavaScript'); alert(code); } function runCode() { // Generate JavaScript code and run it. window.LoopTrap= 1000; Blockly.JavaScript.INFINITE_LOOP_TRAP= 'if (--window.LoopTrap == 0) throw "Infinite loop.";\n'; var code= Blockly.Generator.workspaceToCode('JavaScript'); Blockly.JavaScript.INFINITE_LOOP_TRAP= null; try { eval(code); } catch (e) { alert(e); } } </script> </body> </html>
4. language_linda.js
5. language_utility.jsif(!Blockly.Language) { Blockly.Language= {}; } Blockly.Language.linda_createTupleSpace= { category: 'Linda', helpUrl: '', init: function() { this.setColour(110); this.setOutput(true); this.appendValueInput('TupleSpace').appendTitle('Create TupleSpace:') this.setPreviousStatement(false); this.setNextStatement(false); this.setTooltip('Create a TupleSpace.'); } }; Blockly.Language.linda_watch= { category: 'Linda', helpUrl: '', init: function() { this.setColour(110); this.appendValueInput('TupleSpace').appendTitle('TupleSpace:'); this.appendValueInput('Tuple').appendTitle('Watch Tuple:'); this.appendDummyInput().appendTitle('Found Tuple:').appendTitle(new Blockly.FieldVariable(null), 'LIST'); this.appendStatementInput('DO').appendTitle('Do'); this.setPreviousStatement(true); this.setNextStatement(true); this.setTooltip('Watch the tuple in the tuplespace.'); } }; Blockly.JavaScript= Blockly.Generator.get('JavaScript'); Blockly.JavaScript.linda_createTupleSpace= function() { var _ts= Blockly.JavaScript.valueToCode(this, 'TupleSpace', Blockly.JavaScript.ORDER_NONE) || 'test'; var code= "new linda.TupleSpace(" + _ts + ")" return [code, Blockly.JavaScript.ORDER_NONE]; }; Blockly.JavaScript.linda_watch= function() { var _ts= Blockly.JavaScript.valueToCode(this, 'TupleSpace', Blockly.JavaScript.ORDER_NONE) || 'ts'; var _t= Blockly.JavaScript.valueToCode(this, 'Tuple', Blockly.JavaScript.ORDER_NONE) || '["sensor"]'; var _l= Blockly.JavaScript.variableDB_.getName(this.getTitleValue('LIST'), Blockly.Variables.NAME_TYPE) || 'list'; var branch= Blockly.JavaScript.statementToCode(this, 'DO'); var code= _ts + ".watch(" + _t + ", function(" + _l + "){\n"; code+= branch; code+= "\n});\n"; return [code, Blockly.JavaScript.ORDER_NONE]; };
if(!Blockly.Language) { Blockly.Language= {}; } Blockly.Language.utility_log= { category: 'Linda', helpUrl: '', init: function() { this.setColour(111); this.appendValueInput('Message').appendTitle('console.log:'); this.setPreviousStatement(true); this.setNextStatement(true); this.setTooltip('console.log()'); } }; Blockly.JavaScript= Blockly.Generator.get('JavaScript'); Blockly.JavaScript.utility_log= function() { var _msg= Blockly.JavaScript.valueToCode(this, 'Message', Blockly.JavaScript.ORDER_NONE) || ''; var code= "console.log(" + _msg + ")" return code; };
2013年6月1日土曜日
Raspberry Pi: Mincraft-Piも試し終わり,どうしようと思った所で@shokaiさんのLindaで遊び始めた.
タイトルの通り,Lindaをraspberry piに入れて遊んでます.linda-arduino-sensorも動かしてるのでこいつを,flotでグラフ化してみた.
![]()
(温度センサもCdSも安定してない…)
(rpi.localはlinda-baseの動いてるraspberry piのこと.Lindaはクロスドメインをデフォルトでは許可してるのでこのコード自体はローカルファイルのfoobar.htmlでも動く)
<html> <head> <!-- http://jquery.com --> <script src="./jquery.min.js"></script> <!-- http://www.flotcharts.org --> <script src="./jquery.flot.min.js" type="text/javascript"></script> <script src="./jquery.flot.time.js" type="text/javascript"></script> <!-- https://github.com/shokai/linda-base --> <script src="http://rpi.local:5000/rocketio/linda.js"></script> <script> var space_name= "myhome"; var tuple= ["sensor"]; var linda= new Linda(); var ts= new linda.TupleSpace(space_name); var data= []; var data2= []; $(function() { //linda linda.io.on("connect", function() { ts.watch(tuple, function(_tuple) { log(_tuple) }); }); linda.io.on("disconnect", function() { }); var log= function(msg) { if(msg[1] == 'light') data.push([(new Date()).getTime(), msg[2]]); else if(msg[1] == 'temperature') data2.push([(new Date()).getTime(), msg[2]]); } //flot var container= $("#placeholder"); var maximum= container.outerWidth() / 2 || 300; function getData(_data) { while(_data.length > maximum) { _data= _data.slice(1); } return _data; } series= [{ data: getData(data), label: "light", lines: { fill: false, } }, { data: getData(data2), label: "temp.", yaxis: 2, lines: { fill: false, } }]; var plot= $.plot(container, series, { grid: { borderWidth: 1, minBorderMargin: 20, labelMargin: 10, backgroundColor: { colors: ["#fff", "#e4f4f4"] }, margin: { top: 8, bottom: 20, left: 20 }, markings: function(axes) { var markings= []; var xaxis= axes.xaxis; for(var x= Math.floor(xaxis.min); x < xaxis.max; x+= xaxis.tickSize * 2) { markings.push({ xaxis: { from: x, to: x + xaxis.tickSize }, color: "rgba(232, 232, 255, 0.2)" }); } return markings; } }, xaxis: { mode: "time", timezone: "browser", timeformat: "%H:%M:%S", ticks: 8, }, yaxes: [{ tickFormatter: function(val, axis){return val.toFixed(1)}, }, { tickFormatter: function(val, axis){return val.toFixed(1)}, }], legend: { show: true, position: "sw", } }); setInterval(function updateSeries() { series[0].data= getData(data); series[1].data= getData(data2); plot.setData(series); plot.setupGrid(); plot.draw(); }, 1000); }); </script> </head> <body> <div id="container"> <div id="placeholder" style="width:800px;height:300px;"></div> </div> </body> </html>
ちなみにsystem_timerはruby1.9.3でうまく入らなかったのでtwを使う上ではrubyは1.8系である必要があった(私だけかもしれないけど).
ラベル:
flot,
javascript,
linda,
raspberry-pi
2012年6月15日金曜日
画像からMeshをつくってみる
動機
OLM Digital R&D » モーフィング応用による2次元アニメーション http://www.olm.co.jp/rd/n-way-morphing/
画からMeshを作ってみようかなと思いつくままにやってみた.
入力画像(背景は透明)
微分フィルタにて境界とおぼしき点を探索
参考: ハフ変換を使わない画像のエッジ角度 - 無作為研究所 http://www.faicha.com/vision/02edgea/, 他
適当な点から最近傍をつないでいく(境界の赤色の点上の緑色の線)
参考(NSArrayの高階関数を用いるソート): Safx: Objective-C上でブロックオブジェクトによる高階関数を用いてソートする方法について http://safx-dev.blogspot.jp/2010/11/objective-c.html
とにかく三角形となるように埋めて行く(青色の線が三角形の群れ)
参考: Javaゲーム制作記 任意多角形の三角形分割 http://javaappletgame.blog34.fc2.com/blog-entry-148.html, 他
縮退三角形を間に常に挟む事でとにかく書き出す
var v= [ { x:0.207031, y:0.937500, z:0.0 }, … { x:0.205078, y:0.933594, z:0.0 }, ]; var i= [ 2170, 2169, 2168, 2169, 2168, 2168, 2168, 2168, 2168, 2168, 2168, 2168, 2168, 2168, 2167, 2168, 2167, 2166, … 1, 2, 3210, 2, 3210, 3210, 3210, 3210, 1, 3210, 1, 1, 1, 1, 3210, 1, 3210, 0, ]; function (__structure v,__structure i) main () { var result = new Object(); result.v= v; result.i= i; return result; }
参考: 縮退三角形(Degenerate triangle)による最適化 - 強火で進め http://d.hatena.ne.jp/nakamura001/20100111/1263219309
書き出したコードをJavascriptパッチに入れてMesh Creater/Mesh Rendererに任せてみる
yone80さんのGLSL Shader(vertNoise)をかぶせてみる
2012年6月2日土曜日
'google-blockly'+'serialport-server'
- I used 'Serialport-server' ( http://shokai.github.com/serialport-server/ ).
- I got the google-blockly code from google code by svn.
- I added the 'language_device.js' in demos/maze folder. The 'language_device.js' code is in my blog.
- I added one line which request the 'language_device.js' to the 'frame.html' in demos/maze folder.
- I added some lines to the 'maze.js' in demos/maze folder. The lines code is in my blog.
Scratch has the function about 'create a program using blocks'. Scratch has the function about 'serial port communication'. The following page describes the serial port communication between Scratch and Ardino in Japanese and English.
Scratch+Arduino | Yengawa Systems http://www.yengawa.com/scratch_arduino
動機
コード language_device.jsif (!Blockly.Language) { Blockly.Language = {}; } Blockly.JavaScript = Blockly.Generator.get('JavaScript'); Blockly.Language.device_sendValue = { category: 'Device', helpUrl: '', init: function() { this.setColour(210); this.addTitle('Send Value'); var dropdown = new Blockly.FieldDropdown(function() { return Blockly.Language.device_sendValue.Symbol; }); this.addTitle(dropdown); this.setTitleText(Blockly.Language.device_sendValue.Symbol[0], 1); this.addTitle('To Server (Addr \u201C'); this.addTitle(new Blockly.FieldTextInput('http://localhost:8783')); this.addTitle('\u201D \)'); this.setPreviousStatement(true); this.setNextStatement(true); this.setTooltip('Send Value to the serialport-server'); } }; Blockly.Language.device_sendValue.Symbol = ['o', 'x']; Blockly.JavaScript.device_sendValue = function() { var _addr= Blockly.JavaScript.quote_(this.getTitleText(3)); var _symbol = Blockly.Language.device_sendValue.Symbol.indexOf(this.getTitleText(1)); if (false) { var cmd= "var xhr = new XMLHttpRequest();"; cmd+= "xhr.open('post', "+_addr+", false);"; cmd+= "xhr.onreadystatechange = function(){"; cmd+= "if (xhr.readyState === 4 && xhr.status === 200){"; cmd+= "}"; cmd+= "};"; cmd+= "xhr.send('"+_symbol+"');\n"; return cmd; } else { return (_symbol===0?"Maze.ledon();":"Maze.ledoff();")+"\n"; } };
- 'Blockly.JavaScript.device_sendValue'においてMazeのアニメに合わせて動作させるために内部用のコマンドを返すようにしてあるが, 単に対応するJavascriptを返すだけならif文のthen側,cmdの値を使えばよい.(serialport-serverに'o'か'x'を送るというJavascript)
- これをframe.htmlで定義している他のjsファイルと共に読み込ませるだけでエディタの項目に出てくる
- 編集結果のjavascript codeを取得するには
var code = Blockly.Generator.workspaceToCode('JavaScript');で取得できる.(引数文字列'JavaScript'とBlockly.'JavaScript'が対応付いて'Language'の関数(Blocklyの編集用オブジェクト)に対応する'JavaScript'の同名関数の返り値(文字列)の集まりが得られる)
結果
maze.jsの差分(赤色部分)… Maze.animate = function() { … } else if (action == 'finish') { Maze.scheduleFinish(); } else if (action == 'send_o') { var xhr = new XMLHttpRequest(); xhr.open('post', 'http://localhost:8783', true); xhr.onreadystatechange = function(){ if (xhr.readyState === 4 && xhr.status === 200){ } }; xhr.send('o'); } else if (action == 'send_x') { var xhr = new XMLHttpRequest(); xhr.open('post', 'http://localhost:8783', true); xhr.onreadystatechange = function(){ if (xhr.readyState === 4 && xhr.status === 200){ } }; xhr.send('x'); } Maze.pidList.push(window.setTimeout(Maze.animate, Maze.STEP_SPEED * 5)); }; … Maze.ledoff = function() { Maze.checkTimeout(); Maze.path.push(['send_x', null]); } Maze.ledon = function() { Maze.checkTimeout(); Maze.path.push(['send_o', null]); }
2012年5月21日月曜日
serialport-serverとtimbreを連携させてみた
参考というか動機
結果
やっている事:serialport-serverの例のようにCdsを接続し,Cdsの値をtimbreのfami.freqに与えている.
予想される動作:明るくなると音の高さが上がる.暗くなると音の高さが下がる.
で,結果:
コード
<html> <head> <meta charset="utf-8"/> <title>timbre - oscillators</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script> <script type="text/javascript" src="../timbre.js"></script> </head> <body> <selction id="body"> <h2>Timbre</h2> <div> <button id="play0">play</button> <button id="pause0">pause</button> </div> <hr/> <div id="main"> <h2>Serial Port</h2> <div> <input type="text" value="http://localhost:8783" id="addr" size="40" /> </div> <h3>LED</h3> <div class="led"> <input type="button" class="btn on" value="ON" /> <input type="button" class="btn off" value="OFF" /> </div> <h3>CdS</h3> <div class="cds"> <input type="range" value="500" min="0" max="1024" class="slider" /> <input type="text" id="cdsvalue" value="500" disabled="disabled" size="5" /> </div> </div> </section> </body> <script type="text/javascript"> $(function() { $('.led .on').click(function(){ $.post($('#addr').val(), 'o', function(){ //alert('led on'); }); }); $('.led .off').click(function(){ $.post($('#addr').val(), 'x', function(){ //alert('led off'); }); }); setInterval(function(){ $.getJSON($('#addr').val(), {}, function(data){ $('.cds input').val( data[0].data ); }); }, 100); function getCdsValue() { var value= parseInt($("#cdsvalue")[0].value); if (isNaN(value)) { value= 880; } return value; } dac0= T("dac", fami= T("fami", getCdsValue())); var timerId; dac0.addEventListener("on", function() { timerId = setInterval(function() { fami.freq = getCdsValue(); }, 50); }); dac0.addEventListener("on" , function() {timbre.on();}); dac0.addEventListener("off", function() { if (dac0.isOff) timbre.off(); }); $("#play0").on("click", function() { dac0.on(); }); $("#pause0").on("click", function() { dac0.off(); }); }); </script> </html>
2012年4月1日日曜日
'JSでRSA'をMac OSX jscコマンドで試してみた
追記(2012/04/01):以下のようにすれば"console.log(msg);"で出力することはできる.var console= { "log":function(msg) { print(msg); } };
動機
'JSでRSA - 橋本詳解'を読んで試してみようと思ったが,HTMLの部分や読み込みをscriptタグで書くのめんどくさいなぁと思ったので調べ始めた.
jsc
こちらの記事( 'JavaScript shell scripting / Stoyan's phpied.com phpied.com' )にあるようにjscというのがMac OSXにはあるらしい.sudo ln -s /System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc /usr/local/bin/jsc
とかしといてみた.
コード
動機ページのコードをベースに改変.
・出力は'console.log'ではなく'print'(1).
・外部ファイルの読み込みは'load'(2).
・navigatorはjscではアクセスできないのでloadする前に必要な分だけ定義(3).
・passがそのままというのも失礼な気がしたので変えさせていただきました(4).
var navigator= { "appName":"Mozilla", "appVersion":"5" }; // (3)
load("./cryptico.js"); // (2)
var pass = 'p_g_';// (4)
var rsa_key = cryptico.generateRSAKey(pass, 1024);
var pub_key = cryptico.publicKeyString(rsa_key);
var enc = cryptico.encrypt('hello', pub_key);
print(enc.cipher); // (1)
var dec = cryptico.decrypt(enc.cipher, rsa_key);
print(dec.plaintext); // (1)
登録:
投稿 (Atom)









