ジュリア集合のアンチエイリアシングについて
いろいろ試した結果、重みを付けずに平均をとることにした。
昨日の結果を見てたんだけど、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