株式会社ホクソエムのブログ

R, Python, データ分析, 機械学習

Rと3Dプリンターで八ヶ岳のミニチュアを作る。

この記事について

この記事はR Advent Calendar 2019の19日目の記事です。

はじめに

ホクソエムサポーターの輿石です。最近3Dプリンターを買いました。遠い世界のガジェットのように思っていましたが、家庭用であれば3万円前後で買えてしまうんですね。
3Dプリンターの使い方としてCADで自分の作りたいものを設計していくのが一般的かと思いますが、Rで3Dのプロットを作成することで、データから立体物を作ることが可能です。
この記事では、3Dのプロットを作成できるrayshaderパッケージと、基盤地図情報の地形図データをRに読み込むことができるfgdrパッケージを使って、故郷八ヶ岳周辺のミニチュアを作ってみます。

データの取得

国土地理院の基盤地図情報サイトからデータをダウンロードします。 今回は数値標高モデルの10mメッシュのデータを使います。八ヶ岳周辺のメッシュコードは533862、533863、533872、533873でした。地名検索機能が付いた地図のUIが用意されており、クリックだけで欲しい場所のデータを指定することができました。

データの読み込み

まずは今回必要になるパッケージを読み込みます。

library(fgdr)
library(rayshader)
library(raster)
library(tidyverse)

基盤地図情報からダウンロードしたxml形式のデータをfgdrパッケージのread_fgd_dem関数を使ってraster形式で読み込みます。広い範囲(複数のメッシュコードの範囲)を対象にしたい場合には複数のxmlファイル結合する必要があるので、読み込んでからraster::margeで結合します。

files <-
  list.files("data/", full.names = T, pattern = "dem10b")   
files
[1] "data/FG-GML-5338-62-dem10b-20161001.xml" "data/FG-GML-5338-63-dem10b-20161001.xml" "data/FG-GML-5338-72-dem10b-20161001.xml"
[4] "data/FG-GML-5338-73-dem10b-20161001.xml"
raster_list <-
  files %>%
  map(~fgdr::read_fgd_dem(., resolution = 10, return_class = "raster"))

r <- purrr::reduce(raster_list, raster::merge,  tolerance = 0.2)

rayshaderを使った3D出力

rayshaderは公式のドキュメントが充実しているので、詳細はこちらが役に立つと思います。
rayshaderで扱えるようにrasterをmatrixに変換してからプロットします。

elmat <- rayshader::raster_to_matrix(r)
elmat %>%
  rayshader::sphere_shade(texture = "desert") %>%
  rayshader::plot_map()

f:id:kosshi08:20191216015641p:plain:w500
基盤数値情報DEMデータを元に作成

elmat %>%
  rayshader::sphere_shade(texture = "desert") %>%
  rayshader::plot_3d(elmat, zscale = 10, fov = 0, theta = 135, zoom = 0.75, phi = 45, windowsize = c(1000, 800))

rayshader::render_snapshot(clear=FALSE)

f:id:kosshi08:20191216020508p:plain
基盤数値情報DEMデータを元に作成

3Dプリンターで印刷する

rayshaderパッケージのsave_3dprint関数を使うことで、3Dプリンターでは一般的なstlというフォーマットでデータを出力することができます。stlは造形物を三角形の集合体で表現するファイル形式なようです。
今回私が購入した熱溶解積層方式の3DプリンターはstlファイルをG-Codeというファイル形式に変換して読み込む必要があるので、3Dプリンターに付属しているソフトで変換します。(stlファイルがあればほとんどの3Dプリンターで何らかの方法で出力できるのではと思います。)

rayshader::save_3dprint("Yatsugatake.stl")
# このあと3Dプリンター付属のファイルでG-coede形式に変換

G-code形式のファイルを3Dプリンターに送って出力します。こんな感じで線を描き少しずつ重ねていって八ヶ岳を出力していきます。

f:id:kosshi08:20191218010817j:plain:w500

私が使っている3Dプリンターでは、15cm四方の大きさで8時間で出力できました。(7cm四方の大きさで約1時間弱、25cm四方だと6日間弱かかります!)

f:id:kosshi08:20191218011238j:plain:w500
基盤数値情報DEMデータを元に作成

八ヶ岳の裾野までプリントしたため山の部分が小さくなってしまいました。標高1600m以上の部分に絞ってプリントしてみます。

values(r)[values(r) < 1600] <- NA
elmat = rayshader::raster_to_matrix(r)
elmat %>%
  sphere_shade(texture = "desert") %>%
  plot_3d(elmat, zscale = 10, fov = 0, theta = 135, zoom = 0.5, phi = 45, windowsize = c(1000, 800))
save_3dprint("Yatsugatake_1600m.stl")

f:id:kosshi08:20191218010614j:plain:w500
基盤数値情報DEMデータを元に作成

山の稜線がはっきり認識できるミニチュアができました。

3Dプリンターについて

3Dプリンターにもいくつか種類があり、家庭用では主にプラスチックを熱で溶かして少しずつ積層していく熱溶解積層方式と、光をレジンに当てて硬化させていく光造形方式の二つが主流になっています。
私の購入した3DプリンターはANYCUBICというメーカーの熱溶解積層方式のエントリーモデルで、Amazonでもベストセラーになっている定番のものです。 光造形方式の方がきれいに出力できるようですが、レジンの取り扱いが難しかったり、造形時のレジンの臭いが気になる人もいるようなので、熱溶解積層方式を選びました。エントリーには熱溶解積層方式が良いのではと思います。

おわりに

この記事ではRとfgdrとrayshaderを使って八ヶ岳を3Dで可視化し、3Dプリンターで出力してみました。rayshaderではggplot2のオブジェクトも3Dで表示できるので、一般的なプロットも3Dプリンターで印刷することができます(使いどころは??)。3Dプリンターがあると可視化の幅が広がりますね。2020年、一家に1台3Dプリンターはいかがでしょうか。

Enjoy!

参考