MathBox
以前から気になっていた "MathBox" を使ってみました。Making WebGL Danceで使われていると言われればどんなことが出来るか分かるかと思います。公式サイト には "PowerPoint Must Die" と過激な事が書いてある通り、スライドを作ることもできます。
いくつかの記事に分けて使い方を書いていこうと思います。
自分にとっての魅力
- ベクトル、曲線や曲面など大抵は描画出来る
- スライド間の遷移やグラフのアニメーションが可能
- JavaScript である(ので、その他 JavaScript で出来ることはなんでも出来る)
- TeX 記法で式がかける(KaTeX)
- 3D モデルの描画が出来る(Three.js)
といったところが魅力的でした。
使い方
使い方は GitHub の README や 公式サイト を見ればなんとなく分かるのですが、自分で思い描いているものを書こうとすると骨が折れました。どちらかというとコードが書けた後にドキュメントを読み返すと「あぁ、こういうことが言いたかったのね」となる感じでした。
まずは直線と Sin カーブを描画するサンプル examples/test/xyzw.html
を基にして見ていきましょう。コードは以下の通りです。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MathBox - XYZW Test</title>
<script src="../../build/mathbox-bundle.js"></script>
<link rel="stylesheet" href="../../build/mathbox.css">
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
</head>
<body>
<script>
mathbox = mathBox({
plugins: ['core', 'controls', 'cursor'],
controls: {
klass: THREE.OrbitControls
},
});
three = mathbox.three;
three.camera.position.set(2.3, 1, 2);
three.renderer.setClearColor(new THREE.Color(0xFFFFFF), 1.0);
view = mathbox.cartesian({
range: [[-6, 6], [-1, 1], [-1, 1]],
scale: [6, 1, 1],
});
view.interval({
width: 128,
expr: function (emit, x, i, time) {
var d = Math.sin((x + time) * 2);
emit(x, 0);
emit(x, d * .5);
},
items: 2,
channels: 2,
});
view.line({
color: 0x3090FF,
width: 10,
});
</script>
</body>
</html>
こちらをブラウザで開くと時間的に変化する水色の直線とサインカーブが描かれ、Three.js の OrbitControls と同じ操作で視点移動が可能です。こちらを少しずつ変更していってみます。
See the Pen xyzw by Yuichi Sato (@satoyuichi) on CodePen.
メソッドチェーン
view.interval(...)
の部分は以下のように書くことも可能です。サンプルでもこのように書かれていることが多いです。
view.interval({
width: 128,
expr: function (emit, x, i, time) {
var d = Math.sin((x + time) * 2);
emit(x, 0);
emit(x, d * .5);
},
items: 2,
channels: 2,
}).line({
color: 0x3090FF,
width: 10,
});
描画色を変える
直線と Sin カーブで色を変えてみます。先ほどまでは同じ view.interval(...)
内で書いていたのですが、それぞれ分けて描画します。
直線のプロパティの width
は配列の幅を表しているのですが、直線なので始点と終点だけあれば良いため 2
に変更しました。また items
は先ほどの直線と Sin カーブの二種だったのが、直線一種のみになったので 1
としています。 Sin カーブの items
も同じく 1
となります。
// 直線
view.interval({
width: 2,
expr: function (emit, x, i, time) {
emit(x, 0);
},
items: 1,
channels: 2,
}).line({
color: 0x3090FF,
width: 10,
});
// Sin カーブ
view.interval({
width: 128,
expr: function (emit, x, i, time) {
var d = Math.sin((x + time) * 2);
emit(x, d * .5);
},
items: 1,
channels: 2,
}).line({
color: 0xFF3090,
width: 10,
});
グリッド
このままでは位置が分かりにくいので、グリッドを追加します。下記のコードを追加します。
view.grid({
stroke: 'dashed',
});
stroke
に 'dashed'
を指定しているので、ダッシュ線でグリッドが表示されます。座標軸が伸びて見えますが正常です。ドキュメントを見ながら、下記の箇所を変更しながら観察してみてください。
view = mathbox.cartesian({
range: [[-6, 6], [-1, 1], [-1, 1]],
scale: [6, 1, 1],
});
コード全体
ここまでのコード全体は下記の通りです。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>MathBox - XYZW Test</title>
<script src="../../build/mathbox-bundle.js"></script>
<link rel="stylesheet" href="../../build/mathbox.css">
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
</head>
<body>
<script>
mathbox = mathBox({
plugins: ['core', 'controls', 'cursor'],
controls: {
klass: THREE.OrbitControls
},
});
three = mathbox.three;
three.camera.position.set(2.3, 1, 2);
three.renderer.setClearColor(new THREE.Color(0xFFFFFF), 1.0);
view = mathbox.cartesian({
range: [[-6, 6], [-1, 1], [-1, 1]],
scale: [6, 1, 1],
});
view.interval({
width: 2,
expr: function (emit, x, i, time) {
emit(x, 0);
},
items: 1,
channels: 2,
}).line({
color: 0x3090FF,
width: 10,
});
view.interval({
width: 128,
expr: function (emit, x, i, time) {
var d = Math.sin((x + time) * 2);
emit(x, d * .5);
},
items: 1,
channels: 2,
}).line({
color: 0xFF3090,
width: 10,
});
view.grid({
stroke: 'dashed',
});
</script>
</body>
</html>
See the Pen xyzw color changed by Yuichi Sato (@satoyuichi) on CodePen.