blog.monophile.net

Takaaki Yamamoto

東京工業大学において計算機科学と応用数学を学び、情報科学芸術大学院大学[IAMAS]においてメディア表現を専攻し修了。 現在は digitiminimi Inc. において、インフラエンジニアとして生計をたててている。 また、計算を主題に制作を行い、現代音楽作品や公共インスタレーション作品など技術提供を行う。 三輪眞弘に師事する。

List

c++でboostを使って座標変換

今、openframeworksでグラフィックな作品を作っています。 C++を真面目に使い始めたのは今回が初めてなので、悪戦苦闘してます。 さて、3dをやっているとどうしても直行座標系と極座標系を行ったり来たりしたくなるのではないでしょうか? そのくらい、簡単にできるよね?って思ってたら、案外検索かけても出て来なかったので・・・びっくり。 boostを使えばできるみたいなので、やってみました。

code

#include <iostream>
#include <cmath>
#include <boost/geometry.hpp>
#include <boost/format.hpp>
using namespace std;
namespace cp {
  namespace bg = boost::geometry;
  typedef bg::model::point<double, 3, bg::cs::cartesian> point3d;
  typedef bg::model::point<double, 3, bg::cs::spherical<bg::radian> > spherical3d;
  point3d polar2cartesian(const spherical3d &p0) {
    point3d p1;
    return bg::transform(p0, p1) ? p1 : false;
  }
  spherical3d cartesian2polar(const point3d &p0) {
    spherical3d p1;
    return bg::transform(p0, p1) ? p1 : false;
  }
  string str(const point3d &p) {
    return (boost::format("(x, y, z):(%8.3f, %8.3f, %8.3f)") % p.get<0>()
    % p.get<1>() % p.get<2>()).str();
  }
  string str(const spherical3d &p1) {
    return (boost::format("(r, theta, phi):(%8.3f, %8.3f, %8.3f)") % p1.get<2>()
    % p1.get<1>() % p1.get<0>()).str();
  }
}
int main(void) {
  // cp::spherical3d(phi, theta, r)
  cp::spherical3d p0(M_PI / 4, M_PI / 2, 1);
  cp::point3d p1 = cp::polar2cartesian(p0);
  cp::spherical3d p2 = cp::cartesian2polar(p1);
  cout << "p0:" << cp::str(p0) << endl;
  cout << "p1:" << cp::str(p1) << endl;
  cout << "p2:" << cp::str(p2) << endl;
  return 0;
}

output

逆変換もうまく行ってるみたいですね。めでたし、めでたし。

p0:(r, theta, phi):(   1.000,    1.571,    0.785)
p1:(x, y, z)      :(   0.707,    0.707,    0.000)
p2:(r, theta, phi):(   1.000,    1.571,    0.785)

references