高精細Virtual Starへの道

渋谷行きの電車でpset, rect, circle, ringまで作って、帰りで回転を使わずに正五角形の各頂点を描くところまでできた。

で、次は有理数ライブラリをつくるかーと思ったら作らなくてもあった: Boost Rational Number Library


いちいちpairとか作ったら遅いかなぁとか思ったけど、早すぎる最適化は諸悪の根源だな。 void add(const rat &a0, const rat &b0, const rat &a1, const rat &b1, rat &reta, rat &retb)とかやってるけどやめよう。


まちがってるんだけどこれはこれでいい。



さらに間違っている。



でけたでけた。高速化していないけど3分くらいかかるけど。これは2000x2000で出力してプレビューが縮小するのにまかせてある。



回転しようとしたらばぐった!これはこれでよい。



構図の調整。
計算間違いを1回して、計算があったけど今度は「2世代目の円の頭がちょうど上の辺に接する」という設計より「2世代目の円のまわりにできる五角形の頭がちょうど上の辺に接する」の方がきれいであることに気がついて(実際描いてみると五角形の頭が欠けてしまって美しくない)式を立て直して計算して三度目の正直。左下隅は極限の五角形の足であわせてある。

1/4サイズの8回再帰で1秒、9回で4秒、10回で2分30秒。描画される円の数は6倍ずつ増えるので10回はスラッシングが原因で遅くなっているんだと思われ。じゃあvectorで作ってきたけどsetに変えるか。

8回再帰で1分経っても終わらないくらい低速化した。ダメダメですな。ここでhash_setとか使うといいのかなぁ。8回再帰の段階で対象オブジェクトが40万個くらいあるのでなんだかんだでコスト高いんだなぁ。

プロファイラ掛けてみたけど純粋に計算が重い。Rationalをこの目的に特化したもので差し替えて1割速くなるかどうか…


寝て起きて、setがそんなに遅いはずがないと確認してみたら

    for(set<g2d>::iterator it=cur.begin(), end=cur.end(); it != end; ++i){

絶賛無限ループでした。修正したら10回再帰で12秒で終わるようになった。

next.size(): 5
next.size(): 20
next.size(): 70
next.size(): 226
next.size(): 685
next.size(): 1995
next.size(): 5625
next.size(): 15516
next.size(): 42120
next.size(): 113070

最終的に一番末端の円は9765625個から113070個に削減されたことになる。