SVG + ECMAScript(JavaScript) で遊んでみた
とりあえず,何とか収束するようになったので,アップしてみる.
多体問題で,バネ(ばね)運動をベースに差分化してみたら,なぜか発散してしまった.
で,摩擦係数みたいのを追加したら,収束したw
はっきりいって,式的にあっているか知らん.TouchGraph見たいなものを作りたかったから,
JavaScriptでもできそうだなと思って,やってみた.
はじめはただ単にJavaScriptでやろうとしたんだけど,HTMLじゃ線引けないジャン.
ってことで,急遽SVGでチャレンジ.
にしても,ECMAScriptというかJavaScriptというか,どんなプロパティとかメソッドとか
あるのかわかりにくくてやんなるね.見よう見まねで何とかかけたけどさ.
そろそろ,体系的に勉強する必要ありそう...
あ,ちなみに,このSVGは
http://www.adobe.com/svg/viewer/install/main.html
から,プラグインを落として,ソースをhogehoge.svgとかいう名前で
保存してやって,開けばうまくいくはず.
ちなみに,Opera8 じゃ動かないもよう.OperaのサポートしているSVGじゃ動かないし,
プラグイン追加してみたけど,うんともすんとも言わん.ようわからん.
さらにFireFoxも,SVGを表示した後何かしようとすると毎回落ちる.これもようわからん.
さらにさらに,なぜかノートパソコンにAdobeのプラグインをインストールすると,
毎回インストールに失敗しましたと出る.さっぱりわからん.
<?xml version="1.0" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20001102//EN" "http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd"> <svg> <script type="text/ecmascript"> <![CDATA[ c01 = document.getElementById('c01'); c02 = document.getElementById('c02'); c03 = document.getElementById('c03'); c04 = document.getElementById('c04'); c05 = document.getElementById('c05'); dt = 10; obs = [c01, c02, c03, c04, c05]; bns = [ [c01, c02, 2000, 200, 500], [c01, c03, 2000, 200, 500], [c02, c03, 2000, 200, 500], [c01, c04, 2000, 200, 500], [c02, c04, 2000, 200, 500], [c03, c04, 2000, 200, 500], [c01, c05, 2000, 200, 500], // [c02, c05, 2000, 200, 500], [c03, c05, 2000, 200, 500], [c04, c05, 2000, 200, 500], ]; m01 = document.getElementById('m01'); msg = document.getElementById('msg'); obj = null; offset_x = 0; offset_y = 0; function down(e) { obj = e.target; offset_x = obj.getAttribute("cx") - evt.getClientX(); offset_y = obj.getAttribute("cy") - evt.getClientY(); } function up() { obj = null; reset(); } function move(e) { if (!obj) return; obj.setAttribute("cx", evt.getClientX() + offset_x); obj.setAttribute("cy", evt.getClientY() + offset_y); for (i in bns) { line = document.getElementById(get_line_id(i)); line.setAttribute("x1", bns[i][0].getAttribute("cx")); line.setAttribute("y1", bns[i][0].getAttribute("cy")); line.setAttribute("x2", bns[i][1].getAttribute("cx")); line.setAttribute("y2", bns[i][1].getAttribute("cy")); } return false; } function set_time_func() { setTimeout('time_event_func()', dt); } function time_event_func() { if (obj) return; do_motion(); set_time_func(); } function do_motion() { for (i in bns) { bane(bns[i]); } mx = my = mr = 0; for (i in obs) { x = obs[i].getAttribute("cx"); y = obs[i].getAttribute("cy"); r = obs[i].getAttribute("r"); mx -= - r * x; my -= - r * y; mr -= - r; } m01.setAttribute("cx", mx / mr); m01.setAttribute("cy", my / mr); for (i in bns) { line = document.getElementById(get_line_id(i)); line.setAttribute("x1", bns[i][0].getAttribute("cx")); line.setAttribute("y1", bns[i][0].getAttribute("cy")); line.setAttribute("x2", bns[i][1].getAttribute("cx")); line.setAttribute("y2", bns[i][1].getAttribute("cy")); } } function get_line_id(i) { return "line_id_" + i; } function init() { svg = document.getElementsByTagName("svg"); for (i in bns) { line = document.createElement("line"); line.setAttribute("id", get_line_id(i)); line.setAttribute("x1", 0); line.setAttribute("y1", 0); line.setAttribute("x2", 0); line.setAttribute("y2", 0); svg.item(0).appendChild(line); } reset(); } function reset() { for (i in obs) init_p(obs[i]); set_time_func(); } function init_p(e) { e.setAttribute("px", e.getAttribute("cx")); e.setAttribute("py", e.getAttribute("cy")); } function bane(param) { a = param[0]; b = param[1]; k = param[2]; l = param[3]; frc = param[4]; xa0 = a.getAttribute("px"); ya0 = a.getAttribute("py"); xa1 = a.getAttribute("cx"); ya1 = a.getAttribute("cy"); ra = a.getAttribute("r"); xb0 = b.getAttribute("px"); yb0 = b.getAttribute("py"); xb1 = b.getAttribute("cx"); yb1 = b.getAttribute("cy"); rb = b.getAttribute("r"); dx0 = xa0 - xb0; dy0 = ya0 - yb0; dx1 = xa1 - xb1; dy1 = ya1 - yb1; dl0 = Math.sqrt(dx0 * dx0 + dy0 * dy0); dl1 = Math.sqrt(dx1 * dx1 + dy1 * dy1); r = ra + rb; f0 = k * (dl0 - l) * dt * dt / 1000000; f1 = frc * (dl1 - dl0) * dt / 1000; xa2 = 2 * xa1 - xa0 - (rb / r) * ((dx0 / dl0) * f0 + f1 * dx1 / dl0) / ra; ya2 = 2 * ya1 - ya0 - (rb / r) * ((dy0 / dl0) * f0 + f1 * dy1 / dl0) / ra; xb2 = 2 * xb1 - xb0 + (ra / r) * ((dx0 / dl0) * f0 + f1 * dx1 / dl0) / rb; yb2 = 2 * yb1 - yb0 + (ra / r) * ((dy0 / dl0) * f0 + f1 * dy1 / dl0) / rb; a.setAttribute("cx", xa2); a.setAttribute("cy", ya2); b.setAttribute("cx", xb2); b.setAttribute("cy", yb2); a.setAttribute("px", xa1); a.setAttribute("py", ya1); b.setAttribute("px", xb1); b.setAttribute("py", yb1); } init(); ]]> </script> <text id="msg" x="10" y="30" font-size="18">msg</text> <circle id="c01" style="fill:white;stroke:black;" cx="200" cy="400" r="10" onmousedown="down(evt)" onmouseup="up()" onmousemove="move(evt)"/> <circle id="c02" style="fill:white;stroke:black;" cx="400" cy="400" r="15" onmousedown="down(evt)" onmouseup="up()" onmousemove="move(evt)"/> <circle id="c03" style="fill:white;stroke:black;" cx="400" cy="100" r="20" onmousedown="down(evt)" onmouseup="up()" onmousemove="move(evt)"/> <circle id="c04" style="fill:white;stroke:black;" cx="100" cy="400" r="17" onmousedown="down(evt)" onmouseup="up()" onmousemove="move(evt)"/> <circle id="c05" style="fill:white;stroke:black;" cx="240" cy="100" r="13" onmousedown="down(evt)" onmouseup="up()" onmousemove="move(evt)"/> <circle id="m01" style="fill:black;stroke:black;" cx="200" cy="100" r="1"/> </svg>