航空路のビジュアライゼーション2

サンプルコード

前回、すべての航路を平面上にマッピングできたので、今回は3次元にマッピングしてみる。

(前回の最後に実習した、すべての航路の平面マッピングはサンプルコードの「plot_route_all」参照)


peasycamでズーミング

まずは、前回のサンプル「plot_airport_onmap_zoom」を参考に、3次元空間の平面にマッピングしてズーミングできるようにしてみる。「plot_airport_onmap_zoom」では空港をsphereでプロットしたが、全航路のpositionをsphereで表現すると非常に重たくなるので、vertexでプロットする。

vertexで点をプロットするには、以下のようにする。

stroke(255);
noFill();
beginShape(POINTS); //引数にPOINTS
vertex(x0, y0, z0);
vertex(x1, y1, z1);
vertex(x2, y2, z2);
endShape();

線でプロットするには以下のようにする。

stroke(255);
noFill();
beginShape();  //引数なし
vertex(x0, y0, z0);
vertex(x1, y1, z1);
vertex(x2, y2, z2);
endShape();

参考:beginShape()

完成形は「plot_route_all_zoom」。以下は、点でプロットした様子。


球面へのマッピング

Google Earthのように球面に航路をマッピングしてビジュアライズしよう。
経度(lon)、緯度(lat)、地球の半経をrとすると、3次元座標への変換は次のようになる。

x = r * sin(PI/2 - lat) * sin(lon);
y = -1 * r * cos(PI/2 - lat);
z = r * sin(PI/2 - lat) * cos(lon);

ただし、この公式ではlonとlatはラジアンなので、度から変換すると式は次のようになる。

x = r * sin(PI/2 - radians(lat)) * sin(radians(lon));
y = -1 * r * cos(PI/2 - radians(lat));
z = r * sin(PI/2 - radians(lat)) * cos(radians(lon));

ちなみに、rは地球の半径に相当する変数なので任意の数値で構わないのだが、今回はそれに高度が加わるため、

r = (任意の数) + 高度

となる。

これを、「pointToEarth()」関数に実装して、これまでのプログラムのPositionクラスで実行していた「pointToXY()」の代わりに実行しよう。

  //Positionクラス

  Position(String _line){
    lon = float(_line.split(",")[0]);
    lat = float(_line.split(",")[1]);
    alt = float(_line.split(",")[2]);
    //地球の半径を200pxとする。高度(m)を2000で割って足す
    pointToEarth(lon, lat, 200 + alt/2000);
  }

  void pointToEarth(float _lon, float _lat, float _r){
    x =  _r * sin(PI/2 - radians(_lat)) * sin(radians(_lon));
    y = -1 * _r * cos(PI/2 - radians(_lat));
    z = _r * sin(PI/2 - radians(_lat)) * cos(radians(_lon));
  }

また、メインのdraw関数では、地球をsphereで描画するよう書き換えよう。

ここで、fillにアルファ値を指定して地球の裏側も少し透過して見えるようにするには、setup関数で

hint(ENABLE_DEPTH_SORT);

を実行しておくとよい。(ただし、演算に負荷がかかるので注意。)

draw関数は次のようになるが、ライティングについては「素数のインフォグラフィクス」で紹介した3D-visualizationの基本サンプルを参考にしてもよい。

void draw(){
  background(0);

  //地球の描画
  lights();
  fill(0,60,170,90);
  noStroke();
  sphere(200); //地球の半径を200とする

   for (int i = 0; i < routes.size(); i++) {
     routes.get(i).draw();
   }
}

完成形は「plot_route_earth」

点でプロットした様子

線でプロットした様子


演習

  • 地球のテクスチャをマッピングする。(参考:https://processing.org/examples/texturesphere.html
  • 航空路以外にも様々な地理情報を持ったデータを探してみて、地球上にマッピングしてみる。(経度、緯度を持つ情報ならなんでも可能)
    • 参考例:芸術衛星(ARTSAT)「Invader」の全航跡がapiから取得できます。データをCSVでこちらからもダウンロードできるようにしました。データはカンマ区切りで、time,lat,lon,altです。timeはunix時間、高度の単位はkmです。ちなみに航空路の高度の単位はmです。航空路はだいたい10,000m(約10km)。衛星はだいたいその40倍の400kmくらいを飛んでいます。同時にビジュアライズすると面白いかもです。

results matching ""

    No results matching ""