Slide 1

Slide 1 text

Elm でつくる ルービックキューブ カシフクトモヤ

Slide 2

Slide 2 text

自己紹介
 カシフクトモヤ @tnyo43 ( @cashooooou) 普段は TypeScript と React でフロントエンドを書いてる. 2018年に初めて Elm で小さい Webアプリを作った. ポケモンが好き(このあと昨日出た新作をやる) 1 / 11

Slide 3

Slide 3 text

作ったもの
 ブラウザで遊べるルービックキューブ https://tnyo43.github.io/elm-cubic/ デモ動画 2 / 11

Slide 4

Slide 4 text

作り方
 1. データ構造を定義する 2. データをディスプレイに表示する 3. マウス操作できるようにする 3 / 11

Slide 5

Slide 5 text

データ構造を定義する
 4 / 11 3×3×3のルービックキューブは3種類のキューブによって構成される. コーナーキューブ (8個) エッジキューブ (12個) センターキューブ (6個)

Slide 6

Slide 6 text

データ構造を定義する
 5 / 11 回転させるとき、キューブは種類ごとに独立して考えられる. キューブの種類ごとに色と位置に番号をつけたベクトルとみなす. (本当は個々のキューブの向きも管理する必要があるのでもうちょっと複雑) type alias Cube = { corner : Array Int , edge : Array Int , center : Array Int } init : () -> Cube init _ = Cube (Array.fromList [0, 1, 2, 3, 4, 5, 6, 7]) (Array.fromList [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) (Array.fromList [0, 1, 2, 3, 4, 5]) 0 5 2 3 1 6 7

Slide 7

Slide 7 text

データ構造を定義する
 6 / 11 回転はベクトルの順番の入れ替えとみなせる. (例)上面の回転は、 0 → 1 → 2 → 3 → 0 の入れ替えをしている 0 1 2 3

Slide 8

Slide 8 text

データ構造を定義する
 rotate: Side -> Cube -> Cube rotate side cube = case side of Top -> { corner = replace cube.corner [(0, 1), (1, 2), (2, 3), (3, 0)] , edges = replace cube.edges [(0, 3), (3, 2), (2, 1), (1, 0)] } Left -> { corner = replace cube.corner [(0, 3), (3, 7), (7, 4), (4, 0)] , edges = replace cube.edges [(1, 8), (8, 5), (5, 11), (11, 1)] } ... 7 / 11

Slide 9

Slide 9 text

データをディスプレイに表示する
 ianmackenzie/elm-3d-scene というライブラリを使用 3D のオブジェクトを canvas 要素を使ってブラウザ上に表示する. 直方体を作る Scene3d.block と平面を作る Scene3d.quad を組み合わせて 個々のキューブを作り、組み合わせる. + quad いっぱい 並べる 8 / 11

Slide 10

Slide 10 text

マウスで操作できるようにする
 マウスで操作するために,マウスとオブジェクトの位置を 頑張って計算する. 3次元座標空間のいくつかの点が canvas のどこに表示されるか計測し、変換 式を作る. 3D空間上の点をディスプレイ上の点 にうまく変換するように、 パラメータ a~h を計測 ディスプレイ上の (x, y) 3D空間上の (x, y, z) 9 / 11

Slide 11

Slide 11 text

マウスで操作できるようにする
 キューブの各頂点が表示される点が計算できるので、 convexhull アルゴリズムを使ってキューブの領域を検出する. マウスが領域の内部にあることは ray-casting アルゴリズムで検出する. convexhull 10 / 11

Slide 12

Slide 12 text

よかったこと
 数学っぽい計算が多くて楽しかった Elm の関数型言語としての良さを感じた. 自分が操作に慣れてしまうと、初見ユーザのハードルの排除を怠る. マウスでのフィードバックのうまいテストのやり方がわからなかった. わからなかったこと・難しかったこと
 11 / 11