ジュリア集合のアンチエイリアシングについて
いろいろ試した結果、重みを付けずに平均をとることにした。
昨日の結果を見てたんだけど、Chromeで昨日のページを眺めてて、
縮小された画像が良い感じだったので、それに近くなるように変更してみた。
結果的に、こんな感じ。(一部抜粋)
use v5.14; use strict; use warnings; use Imager; use List::Util qw/max sum/; use Time::HiRes qw/time/; use Getopt::Long qw/:config posix_default no_ignore_case bundling auto_help/; use Inline C => Config => LIBS => '-lm' => OPTIMIZE => '-O'; use Inline C => q{ #include <stdio.h> #include <math.h> static IV fLoopLimit = 1000; static NV fP0_r = 0.0; // 実部(x方向) static NV fP0_i = 0.0; // 虚部(y方向) static NV fP1_r = 0.5; static NV fP1_i = 0.5; void set_loop_limit(IV limit) { fLoopLimit = limit; } void set_render_area(NV p0_r, NV p0_i, NV p1_r, NV p1_i) { fP0_r = p0_r; fP0_i = p0_i; fP1_r = p1_r; fP1_i = p1_i; } IV calculate(NV z_r, NV z_i, NV a_r, NV a_i) { IV i = 0; for (; i<fLoopLimit; i++) { const NV z2_r = (z_r * z_r) - (z_i * z_i) + a_r; const NV z2_i = (2.0 * z_r * z_i) + a_i; if ( 4.0 < ((z2_r * z2_r) + (z2_i * z2_i)) ) { break; } z_r = z2_r, z_i = z2_i; } return i; } SV * generate(IV w, IV h, NV a_r, NV a_i) { const NV d_r = ( fP1_r - fP0_r ) / w; const NV d_i = ( fP1_i - fP0_i ) / h; const NV dd_r = d_r / 3.0; const NV dd_i = d_i / 3.0; const NV dd2_r = dd_r / sqrt(2.0); const NV dd2_i = dd_i / sqrt(2.0); IV *dst = NULL; Newx( dst, (w * h), IV ); printf( "progress: %4d/%4d", 0, h ); fflush( stdout ); for (IV iy=0; iy<h; iy++) { IV *p = dst + (w * iy); for (IV ix=0; ix<h; ix++) { const NV z_r = (ix * d_r) + fP0_r; const NV z_i = (iy * d_i) + fP0_i; IV wk = calculate( z_r, z_i, a_r, a_i ); wk += calculate( z_r + dd_r, z_i, a_r, a_i ); wk += calculate( z_r - dd_r, z_i, a_r, a_i ); wk += calculate( z_r, z_i + dd_i, a_r, a_i ); wk += calculate( z_r, z_i - dd_i, a_r, a_i ); wk += calculate( z_r + dd2_r, z_i + dd2_i, a_r, a_i ); wk += calculate( z_r + dd2_r, z_i - dd2_i, a_r, a_i ); wk += calculate( z_r - dd2_r, z_i + dd2_i, a_r, a_i ); wk += calculate( z_r - dd2_r, z_i - dd2_i, a_r, a_i ); p[ix] = wk; } printf( "\rprogress: %4d/%4d", iy + 1, h ); fflush( stdout ); } printf( " -> calclated!\n" ); SV *ret = newAV(); av_fill( ret, (w * h) - 1 ); SV **base = AvARRAY( ret ); for (IV iy=0; iy<h; iy++) { const IV *p = dst + (w * iy); for (IV ix=0; ix<w; ix++) { (*base++) = newSViv( p[ix] ); } } Safefree( dst ); return newRV_noinc( (SV *)ret ); } }; # 以下、前回と同じ
Inline::C
に書いたgenerate()
で重み付けするのをやめただけ。
1画素を決定するのに、周囲8箇所を加えて計9回計算するくらいなら、
幅・高さを倍にしてリサンプリングした方が良いのでは?って思ってて、
次は、その辺を試そうと思う。
ほんとは、パレットのバリエーションを増やすべく、
この辺についていろいろやる予定だったんだけど・・・。
というわけで、本日の1枚。
$ perl aaa.pl --param="0.34,-0.422" --dst="test"
おしまい。
Leave a Comment