寄付窓口はこちら

Swift Light | try! Swift Tokyo 2019 1-4

Glowforgeの3Dレーザープリンターは木、革、アクリルなどから美しい製品を作り出します。Coregraphicsと他のiOS APIを利用することで、アプリのユーザーはGlowforgeに送ることができるベクターグラフィックを作成したり、操作したりすることができます。このトークではこれらの機能をSwiftを用いてどのように構築したか、そしてSwiftを用いることで私達のソリューションがどのようにより堅牢でエレガントで安全になったかを説明します。

f:id:niwatako:20190321113221j:plain

f:id:niwatako:20190321113410j:plain

ビルドをするとき、レーザープリンターを立ち上げる

Glouforgeは3DレーザープリンターiPhoneケースや額縁などがつくれる

f:id:niwatako:20190321113503j:plain

写真からこんなふうに作れます

f:id:niwatako:20190321113517j:plain

ベクタ絵も利用できます

これはコースター用

f:id:niwatako:20190321113544j:plain

f:id:niwatako:20190321113553j:plain

Web向けにはいろいろツールがあると思います。

f:id:niwatako:20190321113557j:plain

SVGで画像を表示することがあると思いますが、それを超えると複雑な事が必要。

Glowforgeで私はその部分を担当しています。

PNG

f:id:niwatako:20190321113633j:plain

f:id:niwatako:20190321113641j:plain

Traceがお気に入りです。写真から、Traceを使って

この写真のなかで穴を開けて裏の素材をみせる

f:id:niwatako:20190321113706j:plain

f:id:niwatako:20190321113727j:plain

どうやるのでしょう。アプリで縁取りする

f:id:niwatako:20190321113735j:plain

f:id:niwatako:20190321113755j:plain

ピクセルを特定してボーダーをマーキング、ベジエパスで縁取りしていく。

Flood Fillingアルゴリズムを使っている。

たとえば

f:id:niwatako:20190321113824j:plain

中心をタップすると白のピクセルを選択してくれる

f:id:niwatako:20190321113841j:plain

f:id:niwatako:20190321113848j:plain

Lという文字の縁取りができる。通常はピクセルは2Dになっていると思いますが、2DのArrayのピクセルは余り使わないので1DのArrayにする

f:id:niwatako:20190321113921j:plain

f:id:niwatako:20190321113925j:plain

2Dポイントにアクセスできなくなるので対応する

f:id:niwatako:20190321113929j:plain

4*4だとします

f:id:niwatako:20190321113947j:plain

Pixcelを行として特定する。2*4、そして+1

タッチするとIndexは9,これが1DArray中の位置。

f:id:niwatako:20190321114023j:plain

SVGはこんな感じ。Groupタグが重要

f:id:niwatako:20190321114046j:plain

6つ個々のViewになる。独立してインタラクション可能

f:id:niwatako:20190321114109j:plain

f:id:niwatako:20190321114114j:plain

穴とか、黒の領域があるので、プリントできる場所に持って活かせることができる

f:id:niwatako:20190321114137j:plain

f:id:niwatako:20190321114143j:plain

ベジエパスを描画してboundingをとってframeをつかって描画

f:id:niwatako:20190321114215j:plain

それぞれOriginが定義されている。これに基づいてPNGを描画できる。Transformが重要、丸の真ん中に配置させることができる

f:id:niwatako:20190321114242j:plain

f:id:niwatako:20190321114246j:plain

Drag Groupで独立して扱えるように

Drag Groupを表示する際はViewに入れる

f:id:niwatako:20190321114302j:plain

LayerをVeiwに追加していく

f:id:niwatako:20190321114316j:plain

LayerをPathから追加していく。

ただ予想外のことが

ずれてしまった

f:id:niwatako:20190321114339j:plain

先程、猫の目の中をタップしてふちどりました。ぴったり領域にハマっていたが、ここではハマっていない

なぜか

f:id:niwatako:20190321114402j:plain

Layer Frameがあって、もともとはこうなっていた。この位置というのは、もともとのSVGファイルのための場所だった。

f:id:niwatako:20190321114439j:plain

目の中にうまくハマるポジションに移動させる。Origin Point - 1という形で計算します、それを使ってトランスレーションを活用してTransformをかける

うまくはまりました

f:id:niwatako:20190321114516j:plain

イメージの話です

f:id:niwatako:20190321114522j:plain

プロパティとしてこれらがあります。表示にはImageViewを使います

f:id:niwatako:20190321114546j:plain

f:id:niwatako:20190321114553j:plain

Viewが手に入ったらDragGroupViewを適用

でもどうでしょう

f:id:niwatako:20190321114608j:plain

かなり丸からずれてしまっています。

Transformのプロパティはこのように定義されています

f:id:niwatako:20190321114621j:plain

これが理由です

f:id:niwatako:20190321114636j:plain

15度右に回転させます、そううるとこういう形で出てくるのが期待されるが、SVGの中ではOriginの周りで回転するので、違いはかなり大きくなります。

これをどう修正したら良いでしょう

f:id:niwatako:20190321114716j:plain

iOSでは中心、SVGではOrigin.回転軸を中心に移動して、PointをOriginに戻してやる

このExtensionを作りました

f:id:niwatako:20190321114749j:plain

f:id:niwatako:20190321114824j:plain

Viewの中のTransformationはこのような形になります

コースターはこのような見た目になりました。

f:id:niwatako:20190321114840j:plain

安全性を重視しています。レーザーを扱っているので。

f:id:niwatako:20190321114855j:plain

祖父からもらった素材があったが、2回も壊すことは出来ない。大切に扱わなくてはいけない。

アプリは、バグがあったら修正してもう一度再起動すればいいが素材の場合層は行かない。

ValueTypeをつかい、不要な、もしくは予期せぬ変化が起きないようにした。

Abstranctions、独立して使えるようにそれぞれテストしていくことが重要、Transformationは独立して起きる。

Testing テストされていないコードは不完全なコードです、非常に重要であると考えています。ユーザーの貴重な素材を破壊したくないので色々なテストを、独立して行い、統合のためのテストも行っている。

f:id:niwatako:20190321115050j:plain

Glowforgeにおいてコードをテストする際に、いろいろなものを作ってビルドを確認するが、楽しい作業であると同時にストレスを溜めるものでもある。そのためにいろいろな素材を集めてやらなくてはならない。

なぜImageがPathの外にあるのかということを検索しても無い。

今日そういった違いをお見せすることができていれば幸いです。