2014年3月5日水曜日

boost::polygon はまった

三角形分割するのに、boost::polygon を使ってたんですが、残念ながら実数版は実装されているもののサポート対象外みたいで、ロバスト性が保証されていないようです。 Android をはじめとする GLES では、Tesselation(三角形分割)がサポートされていないので、Trapezoid (台形)化してポリゴンを塗り潰してたんですけども、残念です。 以下、削ったコード。
#include <boost/cstdint.hpp>
#include <boost/polygon/polygon.hpp>
#include <vector>

using boost::int32_t;
using boost::uint8_t;

namespace bpl = boost::polygon;
typedef float point_value_type;
typedef bpl::polygon_with_holes_data<point_value_type> Polygon;
typedef bpl::polygon_data<point_value_type> Ring;
typedef bpl::polygon_traits<Polygon>::point_type Point;
typedef std::vector<Point> PointSet;
typedef std::vector<Polygon> PolygonSet;

void set_points( Polygon& polygon, const point_value_type* pts, int32_t count ) {
  polygon.self_.coords_.resize( count );
  for( int32_t i = 0; i < count; ++i ) {
    polygon.self_.coords_[i].x( *pts++ );
    polygon.self_.coords_[i].y( *pts++ );
  }
}

void construct( PolygonSet& polygons, const point_value_type* pts, int32_t count ) {
  using namespace bpl::operators;
  Polygon polygon;
  set_points( polygon, pts, count );
  polygons |= polygon;  //// SIGSEGV
}


int main() {
  float pts[] = {
   -30162.277344, -21684.941406,
   -30154.300781, -21684.707031,
   -30147.291016, -21768.253906,
   -30148.601562, -21752.630859,
   -30156.675781, -21753.292969,
   -30155.425781, -21768.546875,
  };
  
  PolygonSet polygons;
  construct( polygons, pts, 6 );

  
  return 0;
}


追記:どんな図形か調べてみた。ま、往々にしてありがちな図形やね。平行な直線が折り返しているとダメなのであろうか?普通、平行な直線は交点の計算ができないので、交点を求めたりはしない。これをやろうとすると泥沼に陥る事が多い。
2014/03/06 追記: 整数の同じ構成にしてテストを行うと、ちゃんとパスする。
#ifndef SEGF
  typedef int32_t point_value_type;
#else
  typedef float point_value_type;
#endif
にして
  point_value_type pts[] = {
#ifndef SEGF
   -22277344,  -4941406,
   -14300781,  -4707031,
    -7291016, -88253906,
    -8601562, -72630859,
   -16675781, -73292969,
   -15425781, -88546875,
#else
   -22.277344,  -4.941406,
   -14.300781,  -4.707031,
    -7.291016, -88.253906,
    -8.601562, -72.630859,
   -16.675781, -73.292969,
   -15.425781, -88.546875,
#endif
  };
ここは、難しいようで、 polygon_arbitrary_format.hpp にもデバッグ用のコードがコメントアウトされる形で埋め込まれていた。 両者で実行して、違いを見比べてみたところ セーフバージョン
processEvent_
loop
current Y -72630881
scanline size 2
( -16675781, -73292969), ( -8601822, -72630881); ( -14300781, -4707031), ( -8601822, -72630881); 
found element in scanline 1
finding elements in tree
first iter y is -7.26309e+007
loop2
loop2
counts_from_scanline size 2
aggregating
loop3
loop3
落ちるバージョン
processEvent_
loop
current Y -72.6309
scanline size 2
( -16.6758, -73.293), ( -8.60156, -72.6309); ( -14.3008, -4.70703), ( -7.29102, -88.2539); 
found element in scanline 1
finding elements in tree
first iter y is -72.6309
loop2
counts_from_scanline size 1
aggregating
loop3
loop3
更に、loop2 の条件判定文のコメントを polygon_arbitrary_format.hpp に追加して追試してみたところ、
        if(iter != scanData_.end())
          std::cout << "first iter y is " << iter->first.evalAtX(x_) << "\n";
        while(iter != scanData_.end() &&
              ((iter->first.pt.x() == x_ && iter->first.pt.y() == currentY) ||
               (iter->first.other_pt.x() == x_ && iter->first.other_pt.y() == currentY))) {
                //iter->first.evalAtX(x_) == (high_precision)currentY) {
          std::cout << "loop2\n";
          elementIters.push_back(iter);
          counts_from_scanline.push_back(std::pair<std::pair<std::pair<Point, Point>, int>, active_tail_arbitrary*>
                                         (std::pair<std::pair<Point, Point>, int>(std::pair<Point, Point>(iter->first.pt,
                                                                                                          iter->first.other_pt),
                                                                                  iter->first.count),
                                          iter->second));
          ++iter;
          if( iter != scanData_.end() ) {
            std::cout << "CHK loop2 " << iter->first.pt.x() << " == " << x_ << " && " << iter->first.pt.y() << " == " << currentY << "\n";
            std::cout << "CHK loop2 " << iter->first.other_pt.x() << " == " << x_ << " && " << iter->first.other_pt.y() << " == " << currentY << "\n";
          }
        }
セーフバージョンと落ちるバージョンでは、そもそもscanline の構成が異なっている事がわかった
processEvent_
loop
current Y -72630881
scanline size 2
( -16675781, -73292969), ( -8601822, -72630881); ( -14300781, -4707031), ( -8601822, -72630881); 
found element in scanline 1
finding elements in tree
first iter y is -7.26309e+007
loop2
CHK loop2 -14300781 == -8601822 && -4707031 == -72630881
CHK loop2 -8601822 == -8601822 && -72630881 == -72630881
loop2
counts_from_scanline size 2
aggregating
processEvent_
loop
current Y -72.6309
scanline size 2
( -16.6758, -73.293), ( -8.60156, -72.6309); ( -14.3008, -4.70703), ( -7.29102, -88.2539); 
found element in scanline 1
finding elements in tree
first iter y is -72.6309
loop2
CHK loop2 -14.3008 == -8.60156 && -4.70703 == -72.6309
CHK loop2 -7.29102 == -8.60156 && -88.2539 == -72.6309
counts_from_scanline size 1
aggregating
loop3
loop3
浮動小数点型の演算は、難しいものだ。やはり、ロバスト性を確保するのは並大抵のことではない感じだ。

2014年2月10日月曜日

雪あかりの路2014

今年も行ってきました。




2014年2月7日金曜日

Android の Intent が宝の持ち腐れ

 ちょっ、Android の開発に関して、ぼやきます。  Intent を介してアプリケーションが連帯する仕組みが整っているのに、ファイル選択ダイアログといった単純なパーツさえ、自分でエクスプローラのアプリケーションを作成する勢いで書かないと、存在しない。 例えば、zip ファイルを選択させたいと思ったら、既存の枠組みでは、

  private static final int REQUEST_CHOOSE_ZIP = 1;
...

  private void selectZip() {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 
    // MIME/Type が微妙だが置いといて
    intent.setType("application/zip"); 
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    startActivityForResult(intent, REQUEST_CHOOSE_ZIP );
  }
と、呼び出してやれば済む話なのであるが、Androidに付属している標準のエクスプローラ・アプリは、得てして、この仕様に対応していない。

そうすると無料の広告付きアプリを入れてくるか、android-file-dialog(広告付きのオープンソース:改造可)を用意するか、とにかくイケてない。
ま、検索すれば AlertDialog.Builder ベースのファイル選択ダイアログというパーツも見つかるのだが、アクセス権限のないディレクトリに触った瞬間落ちるし、なんか、いけてない。Google さんも、Android の UIガイドと啓蒙みたいな部分に力を入れるよりも、こういった連帯ベース部分に力を入れたほうが、よほどエコなんじゃないでしょうか?  

2014年1月6日月曜日

SD-1 merrill を買いました

 皆さん、明けましておめでとうございます。  ファインダーのついてるカメラが欲しくなったのと、NEX-5Rのクオリティでは我慢できなくなってきたので、カメラを買い替えました。Sigma の SD-1 merrill で、foveon センサという、ちょっとユニークなカメラです。撮れる画像は、はまった時には超一流、だけど、その他の部分は、色々と酷評されている面から考えてもユニークなカメラです。  最近、目が肥えてきて、フルサイズのセンサーで撮影された写真が、なんとなくわかるようになってきました。なので、フルサイズにも惹かれてて、価格的にD610やEOS6Dも圏内でした。NIKON のカメラで撮影されたRAWデータを触らせてもらった事があるのですが、ダイナミック・レンジが半端なく広く感動していた事もあり、D610が有力だったんですが、レンズまで含めると、フルサイズのカメラは、価格的に、かなりしんどい。どうせD610行くならD800Eぐらいのが欲しいというのも頭をかすめました。  PENTAXのK-3も気になってはいたんですが、K-5IIsと比べて、画質は落ちるんじゃないかという部分と、APS-Cサイズな点で、結局SD-1 merrill を選択しちゃいました。  まだ少ししか触ってないんですが、早くも難しいカメラを選んでしまったというのが率直な感想です。ベイヤー方式と異なるカメラなので、RAWデータを弄る感覚が、今までと全く違う。実際どうなのかは、わかりませんが、ダイナミック・レンジは狭いんじゃないかな?という気がしてます。もしくは、現像ソフトで引き出せるダイナミック・レンジが狭いのか?12bit階調しかない NEX-5RのRAWデータでさえ、暗い部分を持ち上げて明るい部分を抑える芸当が、そこそこ効くのに、SD-1 merrill のRAWデータは、どれかを動かすと全体的に追従してきてしまう。しかも、白飛びした部分の潰れ方が極端で、ベタっとします。  手応えとしては、SD-1 merrill こそ HDR 向きなのではないかと感じている次第です。

rsync 備忘録

   3台のマシンがあって、入り口のマシンは1台。いちいちコピーしてたら日が暮れるので、ファイル転送部分だけは定型化しておく事にした。


  • MenteMachine
  • MainMachine
  • SubMachine
ユーザ foo で作業するとして、

MenteMachine 上に

 /home/foo/to_main
 /home/foo/to_sub

MainMacihne 上に

 /home/foo/to_mente

SubMacihne 上に

 /home/foo/to_mente

と、こんな感じディレクトリを構築しておく


MenteMachine 上に、データを収集するためのシェル
#!/bin/bash
rsync -av --delete -e 'ssh -c arcfour' foo@MainMachine:/home/foo/to_mente/ /home/foo/to_main/
rsync -av --delete -e 'ssh -c arcfour' foo@SubMachine:/home/foo/to_mente/ /home/foo/to_sub/
MenteMachine 上のデータを配送するためのシェル
#!/bin/bash
rsync -av --delete -e 'ssh -c arcfour' /home/foo/to_main/ foo@MainMachine:/home/foo/to_mente/ 
rsync -av --delete -e 'ssh -c arcfour' /home/foo/to_sub/ foo@SubMachine:/home/foo/to_mente/ 

2013年12月20日金曜日

mac osx 環境変数 忘備録

関連ファイル /etc/profile /etc/bashrc ターミナルを開く毎に実行 ~/.bashrc ログイン時に実行 ~/.profile ~/.bash_profile 自分は、~/.profile に記述してるよ
##
# Cinder part
##
# export CINDER_HOME=/usr/local/src/cinder_0.8.2_mac

##
# Cuda SDK part
##
export PATH=/usr/local/cuda/bin:$PATH
export DYLD_LIBRARY_PATH=/usr/local/cuda/lib:$DYLD_LIBRARY_PATH
export GPU_INCDIR="/Developer/GPU Computing/C/common/inc"
export C_INCLUDE_PATH=$GPU_INCDIR:$C_INCLUDE_PATH
export CPLUS_INCLUDE_PATH=$GPU_INCDIR:$CPLUS_INCLUDE_PATH

##
# Android NDK part
##
export ANDROID_NDK=/opt/android-ndk-r8d
export PATH=$ANDROID_NDK:$PATH
export ANDROID_TOOLCHAIN_CMAKE=$ANDROID_NDK/toolchains/android.toolchain.cmake

alias android-cmake='cmake -DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN '

##
# Your previous /Users/okimiyuki/.profile file was backed up as /Users/okimiyuki/.profile.macports-saved_2012-06-03_at_22:46:38
##

# MacPorts Installer addition on 2012-06-03_at_22:46:38: adding an appropriate PATH variable for use with MacPorts.
export PATH=/opt/local/bin:/opt/local/sbin:$PATH
# Finished adapting your PATH environment variable for use with MacPorts.


2013年11月14日木曜日

postgresql から json

 php で postgresql からデータを取り出して JSON に加工して返すとか、めんどくさいなぁと思って調べてみました。社員に、どうやって実装してたん?て聞いたら、データ取り出して加工してたという事でした。うんうん、やっぱそうだよなー、面倒くせぇwwwwて思ってたんですが、ラッキーな事に、version 9.2 から row_to_json という関数がサポートされたようです。 まずは、データ準備
create table hoge (id integer primary key, name text);
insert into hoge (id,name) values (1, 'fuga');
insert into hoge (id,name) values (2, 'moge');
ほんで、取り出し
select array_to_json( array_agg( row_to_json(foo) ) )
  from (select id, name from hoge) foo;
結果
[{"id":1,"name":"fuga"},{"id":2,"name":"moge"}]
いやー、素晴らしいですね! 参考:Faster JSON Generation with PostgreSQL