デバッグと今後の予定

六帖webアプリ
kickzone/TrainNavi2 · GitHub
用事を済ませてからデバッグ。一応、動作するようになった。今回のデバッグで、よーく覚えておかなければいけないことは、
・EaselJSでテキストオブジェクトを扱う際は、オブジェクト自体の大きさに気を付けること。点と点を結んだ直線と比べると、同じ座標にオブジェクトを置いても、getMeasuredWidth()/2, getMeasuredHeight()/2の分だけ、右下にずれる。これは、四角形などのShapeにも言えること。
・さらに、右下、ということに気が付いてなかった。そう、パソコンのXY軸は、ふつーの数学で使うXY座標軸とは違う。Y軸が180度反転している。ここでハマった。左90度回転のベクトルを作ろうと思ったら、通常の座標系でいう、右90度回転と同じ計算をしなければいけない。ベクトルの計算例で作成したコードを載せておきます。

//ベクトルの長さを計算
function norm(p){
return Math.sqrt(Math.pow(p.x, 2) + Math.pow(p.y, 2));
}
//p1p2, p3p2の角の二等分線を単位ベクトルで得る
function calcBisectUnitVector(p1, p2, p3)
{
//単位ベクトル同士を足すと出来上がり
var p1p2 = {x: p2.x - p1.x, y: p2.y - p1.y};
var nrmp1p2 = norm(p1p2);
var p3p2 = {x: p2.x - p3.x, y: p2.y - p3.y};
var nrmp3p2 = norm(p3p2);
var bisect = {x: p1p2.x/nrmp1p2 + p3p2.x/nrmp3p2, y: p1p2.y/nrmp1p2 + p3p2.y/nrmp3p2};
if(bisect.x == 0 && bisect.y == 0){
//1直線上に3点があった場合、打ち消しあって0になってしまう
//このときはp1p2の法線をリターン
return calcNormalUnitVector(p1, p2);
}
var nrmBisect = norm(bisect);
bisect.x /= nrmBisect;
bisect.y /= nrmBisect;
//p1p2の左側に二等分線が来るようにしたい
//p1p2と外積をとって、正なら反転させる
var cp = p1p2.x * bisect.y - p1p2.y * bisect.x;
if(cp > 0){
bisect.x = -bisect.x;
bisect.y = -bisect.y;
}
return bisect;
}
//p1p2の法線単位ベクトルを得る
//左90度回転
function calcNormalUnitVector(p1, p2)
{
//(x, y)の左90度回転ベクトルは(-y, x)
//しかしながら、PCの座標系はyが反転しているので、(y, -x)にしないといけない
var normalVec = {x: p2.y - p1.y, y: p1.x - p2.x};
var nrmNormal = norm(normalVec);
normalVec.x /= nrmNormal;
normalVec.y /= nrmNormal;
return normalVec;
}

前回のTrainNaviと比べると、JSONをやめて、サーバーとの通信の冗長性をひたすらなくしたことで、ローカルでさえ10秒ほどかかっていたローディングが、無料サーバー経由でもほんの1秒ほどで済むようになった。自分でもびっくり。一方、描画はのろい。行先表示もまだ未実装だというのに、15fpsでもCPU使用率が20%台をキープしている。非常に簡単なオブジェクトしか描画してないんだから、もっと軽くできるはずだ。例えば列車はテキストじゃなくてShapeにした方がいいかも。キャッシュ機能も使うべきかもしれない。

今後の予定:(優先順)

  • 行先表示
  • 拡大縮小、スクロール
  • DB拡充
  • 駅名表示(どこに表示するかが問題)
  • パッケージファイルの読み込み
  • 動作速度の改善

追加したい機能(優先順)

  • スクロールに合わせた画面表示をする。画面にないオブジェクトを削除して動作を軽くする。スクロールして画面内に入ってきたところではじめて表示する。
  • 通過点のエディット機能、ベジェ曲線で完璧な線路を引くためのGUI作成。ベジェ曲線 – diary 六帖
  • GoogleMapと連携する。地図上を列車が走る。
  • スキン機能。あらゆる路線図を作れるようにする。
  • ターゲットとなる列車を決めて、強調表示する。今どのあたりを走っているかが分かる。
  • 駅をクリックしたら情報を表示する。あと何分で電車が来るとか、目的地を決めたらそこまでかかる時間とか。
  • 列車をクリックしたら情報を表示する。現在速度とか表定速度とか、次はどこに止まるかとか。
  • 運賃を表示できるようにする。FareMap(自作)の機能を全部移植する。
  • 時刻表を自動生成する。
  • この際、NAVITIMEみたいな最短経路・最安経路生成機能も付けてしまう。

列車が動いた

六帖webアプリ
kickzone/TrainNavi2 · GitHub
非常に不審な動き。まだまだバグだらけのようだ。
まず全ての列車が線路の東側しか走ってない。さらに、ベクトルの計算式がおかしいのか、駅によって場所が激しくずれる。新宿近辺は特にカクカクしている。列車の読み込み機能にもバグがあるようで、しばらくすると列車がいなくなる。バグつぶしは仕事だけでたくさんだ。半日以上かかってもあまり進まなかったなぁ。つかれた。
さて、Ajaxで非同期処理をする際、処理の終了を待って先に進みたいこともある。このような場合はsetIntervalを使って、次のように書けばよいことが分かった。

DB.readTrains(startTime, dbReadTime, trains, AddTrains); //Ajax処理 終わったらonInitのフラグがなくなる
var wait = setInterval(function() {
if (!onInit) {
//初期化が終わったのでIntervalを削除。
clearInterval(wait);
//イベント登録、開始
createjs.Ticker.addEventListener("tick", OnTickMain);
createjs.Ticker.setFPS(fps);
}
}, 100); //100msごとにフラグを確認

Beethoven, Friedrich Gulda(pf): Piano Sonata No.28-29(CD11)

Amazon.co.jp: Ludwig van Beethoven, Horst Stein, Wiener Philharmoniker, Friedrich Gulda : Beethoven: Piano Sonata No. 1-32, Piano Concertos No. 1-5 – 音楽
★★★★★(σ゚∀゚)σ
まず28番。静かな第1楽章に続き、付点リズムでずーと踊ってる第2楽章が印象的だが、第3楽章が久しぶりに中盤の神がかったメロディー&付点付き超ダサメロディー&強烈な盛り上がり、とこれまでのベートーヴェン風味を凝縮したような濃い曲になっていて、しかも物寂しげなスパイスまでついているというこれまたすごい一曲。
そして29番ハンマークラヴィーア。これは最高傑作といっていいと思います。第1楽章は爆音ド派手派手、そしてひたすら手数が多いピアニスト泣かせの曲。箱根駅伝でいうと2区。第2楽章は何故かこの曲だけ短いスケルツォで、短いといえども中盤〜終盤にかけて意味不明ゾーンがあり気が抜けません。第3楽章はプログレもびっくりの約14分の超大曲。弾く人によっては20分にもなるらしい。これのどこが緩衝曲なんじゃと思うような押し殺した感情が延々と続きます。疲れます。終盤では押し殺しきれず時々激情がほとばしってます。箱根駅伝でいうと4区。
最後の第4楽章がやばい。やばすぎる。グルダさんこの曲だけ弾けてない。人間がやるもんじゃない。まさに山登りの5区。序盤の静謐で引いて引いてこちらが待ちきれなくなったところで、対位法の右から左からの旋律、執拗なトリル、頻発するオクターブまたぎ、あちこちから音が10分間にわたって責めてくる新感覚ピアノ曲でした。無限回廊、無限階段。どこまでいっても階段。それが精密機械よりも完璧に組み立てられている、キングオブわけわからんピアノ曲。普通の人間が弾いたらブレーキ間違いなし。なぜ駅伝に例えたかというと、はじめて、ピアノ曲を聞いただけでマラソンを走ったみたいに疲れるという経験をしたから。
しかし、wikipediaには
>現実には、作曲後20数年でクララ・シューマンやフランツ・リストがレパートリー化して、各地で演奏した。
って書いてあるんだよなぁ。人間ってすごい。


Beethoven, Friedrich Gulda(pf): Piano Sonata No.23-27(CD10)

Amazon.co.jp: Ludwig van Beethoven, Horst Stein, Wiener Philharmoniker, Friedrich Gulda : Beethoven: Piano Sonata No. 1-32, Piano Concertos No. 1-5 – 音楽
★★★★★
ピアノソナタも終盤戦、あと3枚。いきなり23番「熱情」で始まる。素晴らしい演奏です。右から左から奔流が走る、ちょっと早すぎるかも。特に最終第3楽章のシメの16分和音連打ゾーンは今聞いても衝撃だ。24番からは一変して非常に優しい雰囲気の曲に変わる。グルダさんダイナミクスつけすぎなくらいですね。25番は第3楽章が短いながらも躍動感があって好きです。
26番も有名な曲らしい。「告別」と自分でタイトルを付けたそうだ。第1楽章のオクターブ+下降のところが神メロディーでめちゃんこ心にしみる。第2楽章は単なる踏み台でそのまま超軽快な第3楽章へ。2分前と3分半くらいのところの右手オクターブのフォルテッシモからピアノ?に代わって跳ね回るところがすげぇです。この曲はピアノなのにドーパミンが出まくる。すごい。
27番もマイナーながら第1楽章は異様に激しいわ第2楽章は大きく包み込むようでいて中身の熱さが見え隠れする名曲。


JavaScript→PHPに多次元配列を渡す

PHPにデータを渡すために、POSTを使うが、POSTは一次元配列しか渡せない。この制限を回避するために、いろいろな方法があるようだ。
参考リンク:
jQueryのAjaxで多次元配列をPOST – ゆっくり*ゆっくり
JSで作った多次元配列をPOSTでPHPに渡す方法 | MiLKySHADe * ミルキーシェイド
ハッシュを使わないなら、JSONに一度変換して、PHP側でデコードするのが一番楽そうだと分かった。
JavaScript側

var ary = [
[92, 88, 64, 86],
[78, 92, 96, 81],
[68, 56, 84, 70]
];
var aryJSON = JSON.stringify(ary);
$.ajax({
async: true,
type: "POST",
url: "ajax.php",
data: { Ary : aryJSON }
}).done(function( msg ) {
//なんか処理
});

PHP側

$ary = json_decode($_POST['Ary']);
for($i=0; $i<count($ary); $i++)
{
	for($j=0; $j<count($ary[i]); $j++)
	{
		//$ary[i][j]を利用してなんか処理
	}
}

こんな風にできた。オブジェクトを渡したり、連想配列を渡したりした場合は、まだどうなるか不明。


Faust – Faust IV(1973)


★★★★★( ゚д゚ )彡
斜め上ロックチャンピオンの4枚目。またもジャンル分け、分類を拒む曲たち。執拗な繰り返しと意外性、期待を絶対に裏切ってやるという執念、でも曲として破綻していない上にエネルギーも感じられるという不思議な40数分間だった。ギターは(意図的に)コピー用紙みたいな音だし、ドラムも上手いわけじゃないのに、なぜか引き込まれてしまう。4曲目で下痢みたいなシンセもあるが悪くない。特に1曲目Krautrockの塊のようなサウンド、3曲目Jenifferや8曲目It’s a bit of Painの意味不明ギター、5曲目Picnic on a Frozen Riverのイントロと激しく乖離してずっこける歌部分と後半、はすさまじいものがある。過去の3作品と比べると、尖鋭性と演奏感が程よく合わさっているこのアルバムが個人的にはベストか。


列車の始点と終点

列車オブジェクトを画面上に配置するにあたって、その座標が問題となる。路線の上にそのまんま乗せると、上り電車と下り電車が衝突する。怖いし見づらい。したがって、若干線路からずらす必要がある。
日本の電車は左側通行なので、上図でいうと直線ABから一定距離離れた直線A1B’上を列車が動けばよい。この一定距離をrとする。
まず点A1の位置を求める。駅Aの位置を(Xa, Ya), 駅Bの位置を(Xb, Yb)とする。ベクトルABは(Xb-Xa, Yb-Ya)となる。
左側通行を実現するために単位法線ベクトルN=(Nx, Ny)を求める。ABを左側に90度回転して、さらにABの長さで割る。ABを90度回転したベクトルは(Ya-Yb, Xb-Xa)なので
Nx = (Ya-Yb) * Math.sqrt((Xb-Xa)^2 + (Yb-Ya)^2)
Ny = (Xb-Xa) * Math.sqrt((Xb-Xa)^2 + (Yb-Ya)^2)
あとはこれをr倍して(Xa, Ya)に足してやれば、点A1の位置が求まる。これが列車の始点になる。rは見た目から考えて一定値にはにならないだろう。倍率やスキンに応じて変更する。
次に駅Bの停車位置B1を求める。B1は駅Bに法線ベクトルを足したB’の位置ではない。B’とB”の間をつなぐ経路が必要だ。これを実現するため、駅Cに登場してもらう必要がある。B, CをBCから一定距離離した点B”, C’を考える。すると直線A1B’と直線B”Cの交点が、求める列車の停止位置B1になる。
さてB’、B”、C’はA1と同じ手法を使って求められるので、あとは、2直線の交点を求める作業だけだ。二元連立方程式を使ってもいいけど、でもそれだと万が一X軸Y軸に垂直な直線になった時困るなぁ。と思って探していたら、ちゃんと交点を求める手法があった。外積を使うらしい。
4点からなる交点の求め方 画像処理ソリューション
この式を使うなら、それぞれA1=(X1, Y1), B’=(X2, Y2), B”=(X3, Y3), C’=(X4, Y4)とすれば
S1 = {(X4 – X3) * (Y1 – Y3) – (Y4 – Y3) * (X1 – X3)} / 2
S2 = {(X4 – X3) * (Y3 – Y2) – (Y4 – Y3) * (X3 – X2)} / 2
交点の座標は
X = X1 + (X2 – X1) * S1 / (S1 + S2)
Y = Y1 + (Y2 – Y1) * S1 / (S1 + S2)
なんと4行で書ける!エレガントすぎる!図形的には、外積で三角形の面積S1とS2を求め、その比を使ってベクトルを定数倍する、という意味になる。これは素晴らしい。
あとは、順次C1,D1と列車の位置を求めていくことになる。他線への乗り入れがあることを考えると、列車の位置は駅によって一定ではない。列車ごとにそれぞれ計算することになるだろう。また、行き先表示の文字列は、上りは左側・下りは右側、なんて単純にはならないから、さっき求めた単位法線ベクトルを使って、線路と垂直な位置に文字を配置するとよいのでは。


Amon Tobin – Out From Out Where (2002)


★★★★★
4枚目。前作からの一番変わったのは、音質が格段に向上したこと。特に前半はヒップホップ風の曲もありやや明るく、夜中の2時が夜明け前の4時くらいになった。デジタル音の割合が増し、アナログ的な音を食っている。4曲目Searchersの印象が強烈だ。喉の詰まったような謎の笛なのか何かの音、突然入るストリングス、バックで流れている得体の知れないベース音と何考えてるかわからないドラムで気持ち悪さでは今までの曲の中で群を抜いている。ここからまた真っ暗闇の不気味なハイウェイぶっ飛ばし曲が増えていく。9曲目El Wraithも儀式めいていて怖い。毎回劇的に変貌するAmon Tobinさんの楽曲は次はどんな姿を見せてくれるのか。


King Crimson – The ConstruKction of Light(2000)


★★★☆☆
5年ぶり12枚目。何があった、と言いたくなるくらい音が変わっている。ヘビィなのはいいが、中途半端だ。FraKctured、Larks’ Tongues in Aspic-Part IV といった、以前の曲の焼き直しも、ヘビーなはずが以前よりも衝撃度がない。何がまずいってやっぱりドラムがスッカスカなところかなぁ。全然ドキドキしない。思い切りのいい ProzaKc blues と The World’s My Oyster Soup/Kitchen Floor Wax Museum は好きです。現時点で手に入るクリムゾンのオリジナルアルバムは、あと1枚。最後は、どんな音を聞かせてくれるのか。