戻る
このページは現在、ソフトを作るためのメモです。

これまでのまとめ


見る

(2021.9)
tangrams' web storageはGoogle App Engineの移行に追従できず停止。 実はデータ共有よりも、1枚の画像にまとめられる方が有用かも知れない。 とりあえず、WebAPIから読んでいたものは、追加できるプリセットのようにしておく。 WebAPIはいつか別に用意するとしても、今や並べ替えもブラウザ側でできるので、 画像としては扱わずに、純粋なデータベースとしてシンプルに作ろう…。

コンセプト (2020.5)


1画面内の複数のcanvasでpaperjsを使う (2020.5)


paperscriptを使えば良い話だけど、デバッグが辛い、letのような言語の進化が取り込めない、 global経由でないとpaperscript内の関数を呼び出せないのはいつか困りそう、ということでjavascriptで書こうとする。 そのscopeに確実に所属するようにlayerやgroupを作って、必ずそこにアイテムを所属させるのが分かりやすそう。 +-*/でベクトル演算できなくなるのは残念だけど、それはまだ諦めがつくかな、という感じ。

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<script src="paper-full.min.js"></script>
	<script>
	class MyCanvas{
		constructor( element, param ){
			this._scope = new paper.PaperScope(); // scope作成
			this._scope.setup(element); // canvasに結びつける
			this._layer = new paper.Layer(); // layerを作成
			this._scope.layer = this._layer; // layerをこのクラスのscopeに所属させる
			this._scope.view.onMouseDown = this._onMouseDown.bind(this);
			this._mycolor = new paper.Color(param.r, param.g, param.b);
		}
		_onMouseDown(event){
			let path = new paper.Path.Circle(event.point, 10); // この時点ではどこかのアクティブなscopeに所属
			path.fillColor = this._mycolor;
			this._layer.addChild(path); // このクラスのscopeのlayerに追加
			this._scope.view.draw(); // このクラスのscopeを再描画
		}
	}
	window.onload = function(){
		myCanvas1 = new MyCanvas(document.getElementById('myCanvas1'), {r:1,g:0,b:0});
		myCanvas2 = new MyCanvas(document.getElementById('myCanvas2'), {r:1,g:1,b:0});
	}
	</script>
</head>
<body>
	<canvas id="myCanvas1" style="border: solid 1px black; width:200px; height:200px"></canvas>
	<canvas id="myCanvas2" style="border: solid 1px black; width:200px; height:200px"></canvas>
</body>
</html>

タングラムの問題自動生成の難しさについて


一般画像認識ができたとして、どうなのかという端話。

自動生成 (2021.9)


pzdcさんの silhouette_generator で、虚構推理のシルエットパズルの問題を自動生成。 要求環境はPython3.9だけど、今のところ一箇所くらい変えれば3.7でも動いてくれるので、 Google Colaboratoryで動かせる。

自動生成したシルエット。

対して、人手で作ったシルエットはこんな感じ。

両者の間にある違いは、考えすぎると良くないけど、 これに関しては自動生成の方は形が複雑になりがち。 形が単純なシルエットの方がパズルとしては難しいことが多いので、そんな形も作れれば良いなと思う。 自動生成の方法は、今のところ結晶成長型になっているそうなので、この出力を種にして アニーリングというか、台を少し傾けて寄せる、みたいな操作をぼんやりと考えたりする。 4年前のメモを見ると、自動生成を今の配置からの変遷だと思っているので、 自分の考え方のクセなのかもしれない。

あるいはもっと簡単に、単純な形ができるのが稀なだけなら、 とにかく沢山作って、複雑度で減衰する確率分布に近づくように取捨選択。 どちらかを選ばなければいけない場合は、認識結果の確信度の高い(より何かに見える)方を選ぶとか。

並べ替え (2021.9)


並べ替えの特徴量も細々と考えていたけど、時間がたつともう何をやっていたのか思い出せないので、 気分を変えて、深層特徴をあまり深く考えず試した。

シルエットは、hotatenohontateさんの Sprout を、上と同じくpzdcさんのツールで自動生成したもの168個。 左は今までの、複雑度と局所面積率の8次元特徴を使った場合で、 右がImageNetで学習済みのResNet18(CNNの一種)のFC層手前の512次元特徴を使った場合。 どちらもSOMで形成した100ノードのひも状ゲージへ投影して順番決め。

 

このCNNの特徴量は、カラー画像に映っているものが、 あらかじめ決めてある1000種類のうち何であるかを分類できる情報を持っていて、 シルエットでも役に立つのかなと前々から興味があった。 結果的に見た目では今までのよりもきれいに並んでいるように見える (何に見えるか、というレベルまで少し踏みこんでいる?)。 ただ、今までのは複雑度を陽に特徴としているせいか、形の単純さ≒難しさでよく並ぶので、 パズルとして考えたら有用かなと思う。 CNN特徴に転移で複雑度を学習させることも意味があるかも。 でもそれをするためには複雑度の小さいシルエットも大量に用意しないといけないので、 これも胆は自動生成なのか…。

ちなみのこちらもGoogle Colaboratoryで動くのでお手軽。
silhouette_sorter_210924.zip

パズルを解いて遊ぶアプリの妄想 (2021.9)


もうかなり長いこと、シルエットパズルを解くこと自体への興味は失っていたけど、 自動生成に手が届くとちょっと変わってくるかもしれない。

例えば、解くために選べるシルエットは、最初は人手のシルエットだけだけど、 起ち上げるたびに自動生成のシルエットが1つ増える。 なので、1つも解けないで次に起ち上げると、問題が1つ増えているという 地獄のようなアプリになる(歓喜)。 逆に一気に沢山解いてしまう人にとっては、しまいには1つずつしか解けなくなるので、 ほどよいブレーキになると思う。

あとはピースを動かすこと自体に、何かしらの気持ちよさがあればいいと思う。 例えば砂の上を引きずるような視覚効果や音とか、 ペンキの付いた板を動かしたような跡がつくとか (跡は薄れてしばらくするとキレイになる)、 引きずった跡に芽が出て花が咲いて散るとか、軌跡が蝶になって飛び去るとか。 考えるうちは楽しい。

シルエットの並べ方


一列、格子、ハニカム、螺旋…螺旋?
ということでひまわりの種などの配置のモデル化として有名な、フォーゲルの公式(Vogel's formula)を調べてみました。

まず、アルキメデス螺旋(Archimedian spiral)の一般形。

これの特殊な場合として、dr/dθ ∝ 1/r, r(θ=0)=0 の時、フェルマー螺旋(Fermat's spiral)になります。
そしてフォーゲルの公式は、


なので、r ≥ 0のフェルマー螺旋上で、137.5°ごとに点を打っていくことになります。結果は以下。


ちなみに、137.5°は黄金角を程よく丸めた角度。
黄金角は正確には360°を に内分した小さいほうの角度で、137.50776…°。
この比は黄金比と呼ばれていて、調べていくと面白いです。

フィボナッチ数


黄金比





黄金角

話を戻して、n=0,1,2,…の順番で点を結んでいくと137.5°跳ぶので、全然隣合わない。


そこで、一定幅dの螺旋を描いて、それに沿って点を結んでいきます。
0番目の点の位置については、nを少しずらす(n+a, 0≤a<1)といくらか自然に。
それか省くか。

show path

N=
d=
a=
戻る