このサイトで使用している暗号式は、以下のCGIスクリプトで生成しました。
動作させるためには、以下のものが必要です。
・perl-5.6以上が実行できる環境
GD.pm
GD(画像生成用のライブラリ), libpngライブラリ
・暗号文字用の適当なフォント(2種類)

私自身はUNIX環境でしかこのスクリプトの動作を試していません。
WindowsでperlやGDをインストールする場合は、このあたりのサイトが参考になるかもしれません。
なお実際に使用するためには、スクリプト冒頭の二カ所でフォントファイルの設定、および使う文字の設定が必要です。


今後の課題:
・適当に作ったのでスクリプトが汚い…(っていうかコメントぐらい書けよ)。
・扇形衝突判定ルーチンが遅い。多分、無駄な処理を何重にもしている
・扇形衝突判定ルーチンや、いくつかあるオブジェクト描画ルーチンのパッケージ化
・オブジェクトを増やして、より豊富な暗号式を生成可能に
・せっかくwrapperをかましているので、そこで切り離してGD以外の描画エンジンにも対応する
果たして使いたいなんて奇特な人がいるのか知りませんが、一応ライセンスはGPL ver.2以降としておきます。
#!/usr/bin/perl
use CGI;
use GD;
use Encode qw(decode);
use strict;

my $q = new CGI;

#使う文字の設定
my @strset1 = split(//, "ԱԲԳԴԵԶԷԸԹԺԻԽԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՒՓՔՕՖաբգդեզէըթժլխծկհձղճմյնշոչպջռսվտրւփքօֆ0123456789");
my @strset2 = split(//, decode("utf8", "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"));

my $font1 = "MshtakanRegular.ttf"; # 暗号文字に使用するフォント(アルメニア語)
my $font2 = "Thonburi.ttf"; # 英字フォント
my $range = ($q->param("range") || 2);;
my $width = ($q->param("width") || 800) * $range;
my $height = ($q->param("height") || 600) * $range;
my $zoom = ($q->param("zoom") || 3);
my $max_objs = 200;
my $nr_objs = 0;
my $seed = $q->param('seed') || int(rand(999999));
my $log = "seed: $seed\n";
my $npp = 5; # nr_retry per point
srand($seed);

my $x = $width/2;
my $y = $height/2;

my @pattern = (
	{ weight => 1, draw => \&pat1_draw, objs => \&pat1_objs, cons => \&pat1_cons },
	{ weight => 1, draw => \&pat2_draw, objs => \&pat2_objs, cons => \&pat2_cons },
	{ weight => 1, draw => \&pat3_draw, objs => \&pat3_objs, cons => \&pat3_cons },
	{ weight => 1, draw => \&pat4_draw, objs => \&pat4_objs, cons => \&pat4_cons },
	{ weight => .8, draw => \&pat5_draw, objs => \&pat5_objs, cons => \&pat5_cons },
	{ weight => 1, draw => \&genr_draw, objs => \&genr_objs, cons => \&genr_cons },
);
my $pwsum = 0;
$pwsum += $_->{weight} for @pattern;
if (!$q->param('g')) {
	print "Content-type: text/html\n\n";
	print '';
	print "\n";
	exit;
}

$zoom /= $range;
my $im = new GD::Image($width*$zoom,$height*$zoom);
#$im->interlaced(true);

my $white = $im->colorAllocate(255,255,255);
my $black = $im->colorAllocate(0,0,0);
my $red = $im->colorAllocate(255,0,0);
my $green = $im->colorAllocate(0,255,0);

my $color = $white;
$im->fill(1,1,$black);
$im->transparent($black);

my $a180 = 3.1415926535897932384626;
my $a360 = $a180 * 2;
my $a90 = $a180 / 2;
my $a60 = $a180 / 3;
my $a45 = $a180 / 4;
my $a30 = $a180 / 6;
my $deg = $a180/180;

if (0) {
	$pattern[0]->{draw}($x+200, $y+200, 0, 0xffff);
	$x -= 100; $y -= 100;
	my ($pat, $flag) = (4,0);
	my $dir = 180;
	my $cons = $pattern[$pat]->{cons}($x, $y, $dir, $flag);
	draw_triangle_mark($_->[0], $_->[1], 0, $_->[2]) foreach (@$cons);
	$pattern[$pat]->{draw}($x, $y, $dir, $flag);
	my $objs = $pattern[$pat]->{objs}($x, $y, $dir, $flag);
	if (1) {
		$color = $red;
		foreach (@$objs) {
			draw_circle(@$_);
			draw_line_from_circle($_->[0], $_->[1], 0, 0, $_->[2], $_->[3]) if ($_->[3]);
			draw_line_from_circle($_->[0], $_->[1], 0, 0, $_->[2], $_->[4]) if ($_->[4]);
		}
		$color=$white;
	}
} else {
	arrange_patterns($x, $y);
}
draw_str($im, 5, 10*$range, 0, $font2, 9*$range, $log, $white) if $q->param('log');

print "Content-type: image/png\n\n", $im->png;
exit;


##########################################################

# wrapper

sub draw_arc {
	my ($im,$x,$y,$w,$h,$b,$e,$p,$c) = @_;
	my $d = $p * $zoom / 2 - 1;
	do {
		$im->arc($x*$zoom,$y*$zoom,$w*$zoom-$d,$h*$zoom-$d,$b,$e,$c);
		$im->arc($x*$zoom+1,$y*$zoom,$w*$zoom-$d,$h*$zoom-$d,$b,$e,$c);
		$im->arc($x*$zoom-1,$y*$zoom,$w*$zoom-$d,$h*$zoom-$d,$b,$e,$c);
		$im->arc($x*$zoom,$y*$zoom,$w*$zoom-$d+1,$h*$zoom-$d,$b,$e,$c);
		$im->arc($x*$zoom,$y*$zoom,$w*$zoom-$d-1,$h*$zoom-$d,$b,$e,$c);
	} while ($d-- > -$p*$zoom/2);
}

sub draw_line {
	my ($im,$x,$y,$x2,$y2,$p,$s,$c) = @_;
	map {$_ = int($_+0.5)} ($x, $y, $x2, $y2);
	my $d = $p * $zoom / 2;
	do {
		my $ix = ($d/2) * ($y-$y2) / sqrt(($x2-$x)**2 + ($y2-$y)**2);
		my $iy = ($d/2) * ($x2-$x) / sqrt(($x2-$x)**2 + ($y2-$y)**2);
		$im->line($x*$zoom+$ix+$s*$iy,$y*$zoom+$iy-$s*$ix,
					$x2*$zoom+$ix-$s*$iy,$y2*$zoom+$iy+$s*$ix,$c);
		$im->line($x*$zoom+$ix+$s*$iy+1,$y*$zoom+$iy-$s*$ix,
					$x2*$zoom+$ix-$s*$iy+1,$y2*$zoom+$iy+$s*$ix,$c);
	} while(--$d >= -$p*$zoom/2)
}

sub draw_str {
	my ($im,$x,$y,$dir,$font,$size,$str,$c) = @_;
	return $im->stringFT($c,$font,$size*$zoom,$dir,$x*$zoom,$y*$zoom,$str);
}

sub draw_triangle {
	my ($im,$x,$y,$dir,$size,$c) = @_;
	my $dx1 = sin($dir+$a45) * $size * $zoom;
	my $dy1 = cos($dir+$a45) * $size * $zoom;
	my $dx2 = sin($dir-$a45) * $size * $zoom;
	my $dy2 = cos($dir-$a45) * $size * $zoom;
	$im->line($x*$zoom, $y*$zoom, $x*$zoom+$dx1, $y*$zoom+$dy1, $c);
	$im->line($x*$zoom, $y*$zoom, $x*$zoom+$dx2, $y*$zoom+$dy2, $c);
	$im->line($x*$zoom+$dx1, $y*$zoom+$dy1, $x*$zoom+$dx2, $y*$zoom+$dy2, $c);
	$im->fill($x*$zoom+($dx1+$dx2)/3, $y*$zoom+($dy1+$dy2)/3, $c);
}

# command lv 1

sub draw_circle {
	my ($x, $y, $r, $start, $end) = @_;
	$start -= int($start/360 - ($start<0?1:0))*360;
	$end -= int($end/360 - ($end<0?1:0))*360;
	$end += 360 if ($start >= $end);
	draw_arc($im, $x, $y, $r*2, $r*2, 360+450-$end, 360+450-$start, 4, $color);
}

sub draw_text_on_line {
	my ($x, $y, $dir, $str, $font, $s) = @_;
	my $size = $s || 5;
	$dir -= 90;
	$dir *= $deg;
	$x += sin($dir) * 8 + cos($dir) * 8;
	$y += cos($dir) * 8 - sin($dir) * 8;
	my @bounds = draw_str($im,$x,$y,$dir,$font,$size,$str,$color);
}

sub draw_text_in_circle {
	my ($x, $y, $r, $start, $end, $str, $font, $s) = @_;
	my $len = length $str;
	my $o = $r - 13;
	my $size = $s || 10;
	$start += 8;
	$end += 5;
	$start *= $deg;
	$end *= $deg;
	for(my $i = 0; $i<$len; $i++) {
		my $t = $start + ($end-$start)/$len*$i;
		my $s = sin($t);
		my $c = cos($t);
		my @bounds = draw_str($im,$x-$size*$c+$o*$s,$y+$size*$s+$o*$c,$t+$a180,$font,$size,substr($str,$i,1),$color);
	}
}

sub random_str {
	my $loop = $_[0];
	$_ = "";
	$_ .= ($loop > 3 && rand() < 0.1) ? " " : $strset1[int(rand($#strset1))] while ($loop-->=0);
	$_;
}

sub random_str2 {
	my $loop = $_[0];
	$_ = "";
	$_ .= ($loop > 3 && rand() < 0.2) ? " " : $strset2[int(rand($#strset2))] while ($loop-->=0);
	$_;
}

sub draw_triangle_mark {
	my ($x, $y, $r, $dir) = @_;
	$dir *= $deg;
	$x += sin($dir)*$r;
	$y += cos($dir)*$r;
	draw_triangle($im,$x,$y,$dir,8,$color);
}

sub draw_triangle_mark2 {
	my ($x, $y, $r, $dir, $l, $s) = @_;
	$dir *= $deg;
	$x += sin($dir)*($r+$l);
	$y += cos($dir)*($r+$l);
	my $dx = -sin($s*$deg+$a45)*$l;
	my $dy = -cos($s*$deg+$a45)*$l;
	my $dx2 = -sin($s*$deg-$a45)*$l;
	my $dy2 = -cos($s*$deg-$a45)*$l;
	draw_line($im,$x,$y,$x+$dx,$y+$dy,4,1,$color);
	draw_line($im,$x+$dx,$y+$dy,$x+$dx2,$y+$dy2,4,1,$color);
	draw_line($im,$x+$dx2,$y+$dy2,$x,$y,4,1,$color);
}

sub draw_3c_mark {
	my ($x, $y, $r, $dir, $a) = @_;
	$a = $a || 0;
	draw_circle($x+sin($dir*$deg)*$r-sin($dir*$deg+$a*$a180)*8,
						$y+cos($dir*$deg)*$r-cos($dir*$deg+$a*$a180)*8, 3);
	draw_circle($x+sin($dir*$deg)*$r-sin(($dir+120)*$deg+$a*$a180)*8,
						$y+cos($dir*$deg)*$r-cos(($dir+120)*$deg+$a*$a180)*8, 3);
	draw_circle($x+sin($dir*$deg)*$r-sin(($dir+240)*$deg+$a*$a180)*8,
						$y+cos($dir*$deg)*$r-cos(($dir+240)*$deg+$a*$a180)*8, 3);
}

sub calc_line_from_circle {
	my ($x, $y, $r, $start, $l, $dir) = @_;
	my $x1 = $x + $r * sin($start*$a180/180);
	my $y1 = $y + $r * cos($start*$a180/180);
	my $x2 = $x1 + $l * sin($dir*$a180/180);
	my $y2 = $y1 + $l * cos($dir*$a180/180);
	return ($x1, $y1, $x2, $y2);
}

sub draw_line_from_circle {
	my ($x, $y, $r, $start, $l, $dir, $text) = @_;
	my ($x1, $y1, $x2, $y2) = calc_line_from_circle(@_);
	draw_line($im, $x1,$y1,$x2,$y2,4,0,$color);
	if ($text) {
		my $str = "";
		my $_text = $text;
		$text = -$_text if ($_text < 0);
		for (; $text > 0; $text -= 3) {
			$str .= random_str2(int($l/15)*($text>3?3:$text)) . "\n";
		}
		draw_text_on_line($_text>0?$x2:$x1, $_text>0?$y2:$y1, $dir+($_text>0?180:0), $str, $font2);
	}
	return ($x1,$y1, $x2, $y2);
}

sub draw_triangle_in_circle {
	my ($x, $y, $r, $start, $text) = @_;
	draw_line_from_circle($x, $y, $r, $start, $r*1.732, $start+150, $text&1);
	draw_line_from_circle($x, $y, $r, $start+120, $r*1.732, $start+270, $text&2/2);
	draw_line_from_circle($x, $y, $r, $start+240, $r*1.732, $start+390, ($text&4)/4);
	
}

sub draw_triangle_in_circle2 {
	my ($x, $y, $r, $start, $text) = @_;
	my $d = 15;
	my $s = 0.82;
	draw_line_from_circle($x, $y, $r, $start+30, $r*1.732*$s, $start-120-$d, $text&1);
	draw_line_from_circle($x, $y, $r, $start+150, $r*1.732*$s, $start-$d, $text&2);
	draw_line_from_circle($x, $y, $r, $start-90, $r*1.732*$s, $start+120-$d, ($text&4)/2);
}

# collision checking

sub len2 {
	return ($_[0] - $_[2])*($_[0] - $_[2]) + ($_[1] - $_[3])*($_[1] - $_[3]);
}

sub vpoint {
	my ($l1, $x, $y) = @_;
	my ($x1, $y1, $x2, $y2) = @$l1;
	my $dx = $x2-$x1;
	my $dy = $y2-$y1;
	my $a = $dx*$dx + $dy*$dy;
	return ($x1, $y1) if ($a == 0);
	my $b = $dx*($x1-$x) + $dy*($y1-$y);
	my $t = -($b/$a);
	$t = 0 if $t < 0;
	$t = 1 if $t > 1;
	return ($t*$dx+$x1, $t*$dy+$y1);
}

sub inangle {
	my ($u,$s,$t) = @_;
	return -1 unless ($s || $t);
	my $cola = 5;
	$s -= int($s/360 - ($s<0?1:0))*360;
	$t -= int($t/360 - ($t<0?1:0))*360;
	$u -= int($t/360 - ($u<0?1:0))*360;
	$t += 360 if ($s > $t);
	return ($s+$cola < $u && $u < $t-$cola || $s+$cola < $u+360 && $u+360 < $t-$cola);
}

sub infan {
	my ($x, $y, $f2) = @_;
	my ($a, $b, $r, $s, $t) = @$f2;
	my $dx = $x-$a;
	my $dy = $y-$b;
	$r -= 3;

	return 0 if ($dx*$dx+$dy*$dy>$r*$r);
	return 1 unless ($s && $t);
	
	my $u = atan2($dx,$dy) / $deg;
	return inangle($u,$s,$t);
}

sub llcol {
	my ($l1,$l2) = @_;
	my ($x1,$y1,$x2,$y2) = @$l1;
	my ($x3,$y3,$x4,$y4) = @$l2;
	(($x1-$x2)*($y3-$y1)+($y1-$y2)*($x1-$x3)) *
	(($x1-$x2)*($y4-$y1)+($y1-$y2)*($x1-$x4)) < 0 and
	(($x3-$x4)*($y1-$y3)+($y3-$y4)*($x3-$x1)) *
	(($x3-$x4)*($y2-$y3)+($y3-$y4)*($x3-$x2)) < 0;
}

sub lfcol {
	my ($l1,$f2) = @_;
	my ($x1,$y1,$x2,$y2) = @$l1;
	my ($a,$b,$r,$s,$t) = @$f2;
	$r -= 2;
	my $px1 = $a + sin($s*$deg)*$r;
	my $py1 = $b + cos($s*$deg)*$r;
	my $px2 = $a + sin($t*$deg)*$r;
	my $py2 = $b + cos($t*$deg)*$r;

	return 1 if &llcol($l1,[$a,$b,$px1,$py1]);
	return 2 if &llcol($l1,[$a,$b,$px2,$py2]);

	return 3 if &infan($x1,$y1,$f2);
	return 4 if &infan($x2,$y2,$f2);
	return 5 if &infan(&vpoint($l1,$a,$b),$f2);
	return 0;
}

sub ffcol {
	my ($f1,$f2) = @_;
	my ($x1,$y1,$r1,$s1,$t1) = @$f1;
	my ($x2,$y2,$r2,$s2,$t2) = @$f2;
	my $dx = $x2-$x1;
	my $dy = $y2-$y1;
	$r1 -= 2;
	$r2 -= 2;

	return 0 if ($dx*$dx+$dy*$dy>($r1+$r2)*($r1+$r2));

	my $u = atan2($dx,$dy) / $deg;
	return 1 if (inangle($u, $s1, $t1) && inangle($u+180, $s2, $t2));

	return 2 if &infan($x2,$y2,$f1);
	if ($s1 || $t1) {
		my $px1 = $x1 + sin($s1*$deg)*$r1;
		my $py1 = $y1 + cos($s1*$deg)*$r1;
		my $px2 = $x1 + sin($t1*$deg)*$r1;
		my $py2 = $y1 + cos($t1*$deg)*$r1;
		return 4 if &lfcol([$x1,$y1,$px1,$py1],$f2);
		return 5 if &lfcol([$x1,$y1,$px2,$py2],$f2);
	}
	if ($s1 || $t1) {
		my $px1 = $x1 + sin($s1*$deg)*$r1;
		my $py1 = $y1 + cos($s1*$deg)*$r1;
		my $px2 = $x1 + sin($t1*$deg)*$r1;
		my $py2 = $y1 + cos($t1*$deg)*$r1;
		return 4 if &lfcol([$x1,$y1,$px1,$py1],$f2);
		return 5 if &lfcol([$x1,$y1,$px2,$py2],$f2);
	}
	if ($s2 || $t2) {
		my $px1 = $x2 + sin($s2*$deg)*$r2;
		my $py1 = $y2 + cos($s2*$deg)*$r2;
		my $px2 = $x2 + sin($t2*$deg)*$r2;
		my $py2 = $y2 + cos($t2*$deg)*$r2;
		return 6 if &lfcol([$x2,$y2,$px1,$py1],$f1);
		return 7 if &lfcol([$x2,$y2,$px2,$py2],$f1);
	}
	return 0;
}

sub collision_check {
	my ($objs, $lines, $f, $line) = @_;
	if ($line) {
		foreach (@$objs) {
			return -1 if (lfcol($line, $_));  # line-objs collision
		}
	}
	foreach (@$lines) {
		return 1 if (lfcol($_, $f)); # obj-lines collision
	}
	foreach (@$objs) {
		return 2 if (ffcol($f, $_)); # obj-objs collision
	}
	return 0;
}


# arrange_patterns

sub arrange_patterns {
	my @objs = ();
	my @lines = ([0,0,$width,0], [$width,0,$width,$height], [$width,$height,0,$height], [0,$height,0,0]);
	my @point = ([$npp, $x, $y, 90], [$npp, $x, $y, -90]);
	my $max_retry = 5000;
	my $abort = 0;
	
	# timeout
	$SIG{ALRM} = sub {$abort = 1; $log .= "timeout!!\n"; $SIG{ALRM} = "DEFAULT"; alarm(10);};
	alarm(20);
	
	while ($#point >= 0) {
		my $index = int(rand($#point+1));
		my $target = $point[$index];	# connector to the object
		#$color = $green; draw_triangle_mark($target->[0],$target->[1],0,$target->[2]); $color = $white;
		my $flag = int(rand(0x10000));
		my $patk = rand($pwsum);
		my $pati = -1;
		for (my $c = 0; $c < $patk; $c += $pattern[$pati]{weight}) { $pati += 1 }
		my $pat = $pattern[$pati];
		my $cons = $pat->{cons}(0, 0, 0, $flag);
		my $coni = int(rand($#{@$cons}+1));
		my $cont = $cons->[$coni];  # connector used inside the object
		splice(@$cons, $coni, 1);

		foreach my $line (rand() < .4 ? (0, 25, 50, 100) : (80, 200)) {
			my $dir = (180 + $target->[3] - $cont->[2]) % 360;
			#print STDERR "[$#point] @$target  line: $line\n";
			my $x = $target->[1] - cos($dir*$deg) * $cont->[0] - sin($dir*$deg) * $cont->[1];
			my $y = $target->[2] + sin($dir*$deg) * $cont->[0] - cos($dir*$deg) * $cont->[1];
			#$color = $red; draw_triangle_mark($x, $y, 0, $dir); $color = $white;
			# add line
			my $x1 = $target->[1];
			my $y1 = $target->[2];
			my $x2 = $x1 + sin($target->[3]*$deg) * $line;
			my $y2 = $y1 + cos($target->[3]*$deg) * $line;
			$x += $x2-$x1;
			$y += $y2-$y1;

			# collision check
			my $objs = $pat->{objs}($x, $y, $dir, $flag);
			my $need_retry = !($x >= 0 && $x < $width && $y >= 0 && $y < $height);
			if (!$need_retry) {
				foreach (@$objs) {
					$need_retry = collision_check(\@objs, \@lines, $_, $line ? [$x1, $y1, $x2, $y2] : undef);
					last if ($need_retry);
				}
			}
			if ($need_retry) {
				if ($max_retry-- <= 0 || $abort) {
					$log .= "too many retries!!\n" unless ($abort);
					$log .= "objs : $nr_objs\n";
					return;
				}
				if ($need_retry < 0 || $line == 100 || $line == 200) {
					splice(@point, $index, 1) if (--$target->[0] <= 0)
				}
				last if ($need_retry < 0);
				next;
			}

			# draw and add info
			splice(@point, $index, 1);
			$pat->{draw}($x, $y, $dir, $flag);
			push(@objs, @$objs);
			$cons = $pat->{cons}($x, $y, $dir, $flag);
			splice(@$cons, $coni, 1);
			push(@point, map {unshift(@$_, $npp); $_}	# nr_retry per point
								grep {$_->[0] >= 0 && $_->[0] < $width &&
										$_->[1] >= 0 && $_->[1] < $height} @$cons);
			if ($line) {
				draw_line($im, $x1, $y1, $x2, $y2, 4, 0, $color);
				draw_text_on_line($x1, $y1, atan2($x2-$x1, $y2-$y1)/$deg, random_str2($line/8), $font2) if (rand()<.4);
				push(@lines, [$x1, $y1, $x2, $y2]);
			}
			if (++$nr_objs >= $max_objs || $abort) {
				#$log .= "retry-remain: $max_retry\n";
				$log .= "objs : $nr_objs\n";
				return;
			}
			last;
		}
	}
	#$log .= "retry-remain: $max_retry\n";
	$log .= "objs : $nr_objs\n";
}


sub add_con {
	my ($ret, $x, $y, $r, $d) = @_;
	my ($x1, $y1) = (calc_line_from_circle($x, $y, $r, $d))[2,3];
	push(@$ret, [$x1, $y1, $d]);
}

# patterns

sub pat1_draw {
	my ($x, $y, $dir, $flag) = @_;

	draw_circle($x, $y, 100);
	draw_text_in_circle($x, $y, 100, 0, 360, random_str(80), $font1);

	draw_triangle_in_circle2($x, $y, 100, 45+$dir, 7);

	if ($flag & 0x800) {
		draw_circle($x, $y, 5);
		draw_line_from_circle($x, $y, 0, 0, 10, $dir+90);
		draw_line_from_circle($x, $y, 0, 0, 10, $dir-90);
		draw_line_from_circle($x, $y, 5, $dir, 30, $dir);
	}

	draw_triangle_mark($x, $y, 12, $dir+180) if ($flag & 0x100);

	draw_circle($x, $y, 26, $dir+120, $dir+240) if ($flag & 0x200);

	draw_3c_mark($x, $y, 50, $dir) if ($flag & 0x400);

	draw_line_from_circle($x, $y, 100, $dir+180, 50, $dir+180);
	draw_line_from_circle($x, $y, 150, $dir+180, 50, $dir+180, 11);
	
	draw_circle($x, $y, 200, $dir+180, $dir+195);
	draw_text_in_circle($x, $y, 200+16, $dir+180, $dir+195, random_str(8), $font1);

	draw_3c_mark($x, $y, 112, $dir+15, 1) if ($flag & 0x1000);

	if ($flag & 0x1) {
		my ($dx, $dy, $x2, $y2) = draw_line_from_circle($x, $y, 100, $dir+195, 15, $dir+210);
		draw_circle($x2, $y2, 15);
		draw_line_from_circle($x2, $y2, 0, 0, 15, $dir+120);
		draw_line_from_circle($x2, $y2, 0, 0, 15, $dir+300);
	
		draw_circle($x2, $y2, 30, $dir+150, $dir+322);
		draw_line_from_circle($x2, $y2, 15, $dir+150, 25, $dir+150);
		draw_circle($x2, $y2, 40, $dir+125, $dir+(($flag & 0x2)?160:210));
		draw_circle($x2, $y2, 40, $dir+240, $dir+320);
	}
	
	return unless ($flag & 0x2);

	draw_line_from_circle($x, $y, 100, $dir+225, 75, $dir+225);
	draw_circle($x, $y, 130, $dir+180, $dir+225);

	draw_circle($x, $y, 150, $dir+135+(($flag & 0x4)?10:0), $dir+405);
	draw_line_from_circle($x, $y, 100, $dir+45, 75, $dir+45);
	my ($dx, $dy, $x2, $y2) = draw_line_from_circle($x, $y, 100, $dir+135, 75, $dir+135);
	if ($flag & 0x4) {
		draw_circle($x2, $y2, 25);
		draw_circle($x2, $y2, 50, $dir, $dir+270-7);
		draw_circle($x2, $y2, 70, $dir+90, $dir+180);
		draw_text_in_circle($x2, $y2, 70, $dir+45, $dir+225, random_str(30), $font1);
	}
	
	draw_line_from_circle($x, $y, 100, $dir+270, 30, $dir+270);
	draw_circle($x, $y, 130, $dir+240, $dir+270);
	draw_text_in_circle($x, $y, 150, $dir+240, $dir+305, random_str(25), $font1);

	($dx, $dy, $x2, $y2) = draw_line_from_circle($x, $y, 100, $dir+315, 40, $dir+315);
	draw_line_from_circle($x, $y, 140, $dir+315, 20, $dir+315);
	if ($flag & 0x4000) {
		draw_circle($x2, $y2, 20);
		draw_circle($x2, $y2, 7, $dir+135, $dir+315);
		draw_line_from_circle($x2, $y2, 0, 0, 20, $dir+45);
	}
}

sub pat1_objs {
	my ($x, $y, $dir, $flag) = @_;
	my @ret = ([$x, $y, 100], [$x, $y, 200+16, $dir+180, $dir+195]);

	if ($flag & 0x1) {
		my ($x1, $y1, $x2, $y2) = calc_line_from_circle($x, $y, 100, $dir+195, 15, $dir+210);
		push(@ret, [$x2, $y2, 40]);
	}
	
	if ($flag & 0x2) {
		push (@ret, [$x, $y, 150, $dir+135, $dir+405]);
		if ($flag & 0x4) {
			my ($x1, $y1, $x2, $y2) = calc_line_from_circle($x, $y, 100, $dir+135, 75, $dir+135);
			push (@ret, [$x2, $y2, 70]);
		}
	}
	return \@ret;
}

sub pat1_cons {
	my ($x, $y, $dir, $flag) = @_;
	my @ret = ();
	add_con(\@ret, $x, $y, 200+16, $dir+180);
	if ($flag & 2) {
		add_con(\@ret, $x, $y, 175, $dir+45);
		add_con(\@ret, $x, $y, 175, $dir+135) unless ($flag & 4);
		add_con(\@ret, $x, $y, 175, $dir+225);
		add_con(\@ret, $x, $y, 160, $dir+315);
	}
	return \@ret;
}

#=======

sub pat2_draw {
	my ($x, $y, $dir, $flag) = @_;

	draw_circle($x, $y, 50);
	draw_circle($x, $y, 100);
	draw_text_in_circle($x, $y, 100, $dir+120, $dir+175, random_str(15), $font1);
	draw_line_from_circle($x, $y, 0, 0, 50, $dir+45);
	draw_line_from_circle($x, $y, 50, $dir+45, 50, $dir+45, -11);
	draw_line_from_circle($x, $y, 100, $dir+45, 100, $dir+45);
	draw_line_from_circle($x, $y, 0, 0, 200, $dir-135, 1);
	draw_line_from_circle($x, $y, 0, 0, 200, $dir+90);
	draw_circle($x, $y, 200, $dir+90, $dir+120);
	draw_text_in_circle($x, $y, 200, $dir+90, $dir+120, random_str(14), $font1);

	draw_circle($x+sin(($dir+105)*$deg)*100, $y+cos(($dir+105)*$deg)*100, 15) if ($flag & 0x100);
	draw_circle($x+sin(($dir+202)*$deg)*100, $y+cos(($dir+202)*$deg)*100, 15) if ($flag & 0x200);
	draw_circle($x, $y, 15) if ($flag & 0x400);
	#

	if ($flag & 0x1) {
		draw_line_from_circle($x, $y, 50, $dir-45, 50, $dir-45);
		draw_text_in_circle($x, $y, 96, $dir-58, $dir-45, random_str2(5), $font2, 5);
		draw_text_in_circle($x, $y, 90, $dir-56, $dir-45, random_str2(4), $font2, 5);
		draw_text_in_circle($x, $y, 84, $dir-54, $dir-45, random_str2(3), $font2, 5);
		draw_line_from_circle($x, $y, 100, $dir-45, 100, $dir-45);
		draw_circle($x, $y, 140, $dir-45, $dir-22.5);
		draw_circle($x, $y, 150, $dir-45, $dir-30);
		draw_circle($x, $y, 200, $dir-45, $dir-15);
		draw_text_in_circle($x, $y, 200, $dir-45, $dir-15, random_str(15), $font1);
	}

	if ($flag & 0x2) {
		draw_line_from_circle($x, $y, 100, $dir+135, 50, $dir+135);
		draw_text_in_circle($x, $y, 165, $dir+95, $dir+150, random_str(30), $font1, 7);
		draw_text_in_circle($x, $y, 142, $dir+115, $dir+130, random_str2(8), $font2, 5);
		draw_text_in_circle($x, $y, 135, $dir+115, $dir+130, random_str2(8), $font2, 5);
		draw_text_in_circle($x, $y, 128, $dir+115, $dir+130, random_str2(8), $font2, 5);
		draw_text_in_circle($x, $y, 142, $dir+140, $dir+155, random_str2(8), $font2, 5);
		draw_text_in_circle($x, $y, 135, $dir+140, $dir+170, random_str2(15), $font2, 5);
		draw_text_in_circle($x, $y, 128, $dir+140, $dir+155, random_str2(8), $font2, 5);
	}

	if ($flag & 0x4) {
		draw_line_from_circle($x, $y, 100, $dir+180, 50, $dir+180, -2);
	}
	
	if ($flag & 0x8) {
		my ($dx1, $dy1, $x1, $y1) = draw_line_from_circle($x, $y, 50, $dir-45, 140, $dir-90, -1);
		my ($dx1, $dy1, $x2, $y2) = draw_line_from_circle($x, $y, 50, $dir-135, 140, $dir-90, -1);
		draw_line_from_circle($x, $y, 50, $dir-135, 145, $dir-62);
		$x1 = ($x1+$x2)/2;
		$y1 = ($y1+$y2)/2;
		draw_circle($x1, $y1, 35.4);
		
		if ($flag & 0x10) {
			draw_text_in_circle($x1, $y1, 75, $dir-150, $dir-45, random_str(25), $font1, 7);
			draw_text_on_line($x1+sin(($dir-90)*$deg)*40+cos(($dir-90)*$deg)*40, $y1+cos(($dir-90)*$deg)*40-sin(($dir-90)*$deg)*40, $dir+90, random_str2(9)."\n".random_str2(9)."\n".random_str2(9), $font2);
			draw_text_on_line($x1+sin(($dir-90)*$deg)*60+cos(($dir-90)*$deg)*15, $y1+cos(($dir-90)*$deg)*60-sin(($dir-90)*$deg)*15, $dir+180, "        ".random_str2(2)."\n    ".random_str2(4)."\n".random_str2(6), $font2, 3);
		}
	}
	
	if (($flag & 0x22) == 0x22) {
		draw_circle($x, $y, 150);
	}
	
	if ($flag & 0x40) {
		draw_line_from_circle($x, $y, 200, $dir+90, 50, $dir+90);
		draw_circle($x, $y, 250, $dir+75, $dir+90);
		draw_text_in_circle($x, $y, 254, $dir+75, $dir+86, random_str2(12), $font2, 5);
		draw_text_in_circle($x, $y, 248, $dir+75, $dir+86, random_str2(11), $font2, 5);
		draw_text_in_circle($x, $y, 242, $dir+75, $dir+86, random_str2(11), $font2, 5);
	}
}

sub pat2_objs {
	my ($x, $y, $dir, $flag) = @_;
	my @ret = ([$x, $y, (($flag&0x22)==0x22)?150:100], [$x, $y, 200, $dir+90, $dir+120],
					[$x, $y, 200, $dir+35, $dir+55], [$x, $y, 200, $dir+215, $dir+235]);
	push (@ret, [$x, $y, 200, $dir-45, $dir-15]) if ($flag & 0x1);
	push (@ret, [$x, $y, 165, $dir+90, $dir+150]) if ($flag & 0x2);

	if ($flag & 0x8) {
		my ($dx1, $dy1, $x1, $y1) = calc_line_from_circle($x, $y, 50, $dir-45, 140, $dir-90);
		my ($dx2, $dy2, $x2, $y2) = calc_line_from_circle($x, $y, 50, $dir-135, 140, $dir-90);
		push(@ret, [$x1, $y1, 100, $dir+90, $dir+120]);
		push(@ret, [$x2, $y2, 100, $dir+60, $dir+90]);
		$x1 = ($x1+$x2)/2;
		$y1 = ($y1+$y2)/2;
		push(@ret, [$x1, $y1, 35.4]);
		
		push(@ret, [$x1, $y1, 75, $dir-150, $dir-45]) if ($flag & 0x10);
	}

	push(@ret, [$x, $y, 250, $dir+75, $dir+90]) if ($flag & 0x40);

	return \@ret;
}

sub pat2_cons {
	my ($x, $y, $dir, $flag) = @_;
	my @ret = ();
	add_con(\@ret, $x, $y, 200, $dir+45);
	add_con(\@ret, $x, $y, 200, $dir-135);
	add_con(\@ret, $x, $y, $flag&0x40?250:200, $dir+90);

	add_con(\@ret, $x, $y, 200, $dir-45) if ($flag & 0x1);
	add_con(\@ret, $x, $y, 150, $dir+180) if ($flag & 0x4);
	return \@ret;
}


#=======

sub pat3_draw {
	my ($x, $y, $dir, $flag) = @_;
	
	draw_circle($x, $y, 50);
	draw_text_in_circle($x, $y, 50, $dir+15, $dir+150, random_str(10), $font1);
	draw_circle($x, $y, 100);
	draw_triangle_in_circle($x, $y, 100, $dir, ($flag>>9)&7);
	draw_line_from_circle($x, $y, 0, 0, 100, $dir) if ($flag & 0x100);;

	draw_circle($x, $y, 75, $dir+228, $dir+348) if ($flag & 0x1000);

	if ($flag & 0x07) {
		draw_circle($x, $y, 140, $dir+90, $dir+225);
		draw_circle($x, $y, 150, $dir+45, $dir+108);
		draw_line_from_circle($x, $y, 100, $dir+45, 50, $dir+45);
		draw_line_from_circle($x, $y, 100, $dir+225, 75, $dir+225);
		draw_text_in_circle($x, $y, 140, $dir+90, $dir+135, random_str(10), $font1);
		draw_text_in_circle($x, $y, 140, $dir+150, $dir+210, random_str(20), $font1);
		draw_line_from_circle($x, $y, 100, $dir+135, 150, $dir+135);
	
		if ($flag & 0x02) {
			draw_circle($x, $y, 175, $dir+225, $dir+315);
			draw_text_in_circle($x, $y, 175, $dir+225, $dir+315, random_str(30), $font1);
		}
		if ($flag & 0x04) {
			my ($x1, $y1, $x2, $y2) = calc_line_from_circle($x, $y, 0, 0, 160, $dir+135);
			draw_circle($x2, $y2, 75, $dir+15, $dir+255);
		
			draw_circle($x, $y, 190, $dir+45, $dir+150);
			draw_line_from_circle($x, $y, 140, $dir+150, 50, $dir+150);
			draw_text_in_circle($x, $y, 190, $dir+60, $dir+107, random_str(20), $font1);
			draw_text_in_circle($x, $y, 208, $dir+45, $dir+90, random_str(20), $font1);
		}
	}
}

sub pat3_objs {
	my ($x, $y, $dir, $flag) = @_;
	my @ret = ([$x, $y, 100]);

	if ($flag & 0x07) {
		push(@ret, [$x, $y, 150, $dir+45, $dir+45225]);

		if ($flag & 0x02) {
			push(@ret, [$x, $y, 175, $dir+225, $dir+315]);
		}
		if ($flag & 0x04) {
			my ($x1, $y1, $x2, $y2) = calc_line_from_circle($x, $y, 0, 0, 160, $dir+135);
			push(@ret, [$x2, $y2, 75]);
			push(@ret, [$x, $y, 190, $dir+45, $dir+150]);
		}
	}

	return \@ret;
}

sub pat3_cons {
	my ($x, $y, $dir, $flag) = @_;
	my @ret = ();
	
	add_con(\@ret, $x, $y, 100, $dir);
	if ($flag & 0x07) {
		add_con(\@ret, $x, $y, 250, $dir+135);
		add_con(\@ret, $x, $y, 175, $dir+225);
	}
	return \@ret;
}

#=======

sub pat4_draw {
	my ($x, $y, $dir, $flag) = @_;
	
	draw_circle($x, $y, 2);
	draw_circle($x, $y, 25);
	draw_circle($x, $y, 50);
	draw_line_from_circle($x, $y, 0, 0, 50, $dir+270);
	draw_line_from_circle($x, $y, 25, $dir+225, 25, $dir+225);
	draw_text_in_circle($x, $y, 40, $dir+285, $dir+330, random_str2(6), $font2, 5);
	draw_triangle_mark($x, $y, 35, $dir+90) if ($flag & 0x100);

	if ($flag & 0x3f) {
		draw_circle($x, $y, 100, $dir+100, $dir+180);
		draw_line_from_circle($x, $y, 50, $dir+180, 70, $dir+180);
		draw_circle($x, $y, 100, $dir-80, $dir+80);
		draw_circle($x, $y, 120, $dir+100, $dir+255);
		draw_text_in_circle($x, $y, 100, $dir+100, $dir+120, random_str(5), $font1) if ($flag & 0x200);
		draw_text_in_circle($x, $y, 120, $dir+120, $dir+180, random_str(20), $font1);
	}

	if ($flag & 0x2) {
		draw_line_from_circle($x, $y, 120, $dir+225, 55, $dir+225);
		draw_circle($x, $y, 175, $dir+220, $dir+230);
	}

	if ($flag & 0x4) {
		draw_line_from_circle($x, $y, 75, $dir, 50, $dir);
		my ($dx, $dy, $x1, $y1) = calc_line_from_circle($x, $y, 65, $dir, 30, $dir-90);
		draw_text_on_line($x1, $y1, $dir+90, random_str2(10), $font2);
	}

	if ($flag & 0x8) {
		draw_line_from_circle($x, $y, 100, $dir+45, 20, $dir+45);
		draw_circle($x, $y, 120, $dir+30, $dir+60);
	}

	if ($flag & 0x10) {
		draw_line_from_circle($x, $y, 75, $dir+270, 75, $dir+270);
		my ($dx, $dy, $x1, $y1) = calc_line_from_circle($x, $y, 65, $dir+270, 55, $dir+270);
		draw_circle($x1, $y1, 45, $dir+80, $dir+100);
		draw_circle($x1, $y1, 20, $dir+90, $dir+270);
		draw_circle($x1, $y1, 2);
		draw_circle($x1, $y1, 30, $dir+90, $dir+252);
		draw_text_in_circle($x1, $y1, 25, $dir+120, $dir+180, random_str2(4), $font2, 5);
		($dx, $dy, $x1, $y1) = calc_line_from_circle($x, $y, 0, 0, 150, $dir+270);
		draw_circle($x1, $y1, 10);
		draw_circle($x1, $y1, 2);
	}
	
	if ($flag & 0x20) {
		draw_triangle_mark2($x, $y, 125, $dir+180, 20, $dir+180);
		draw_triangle_mark2($x, $y, 120, $dir+170, 20, $dir);
		draw_triangle_mark2($x, $y, 120, $dir+190, 20, $dir);
	}
}

sub pat4_objs {
	my ($x, $y, $dir, $flag) = @_;
	my @ret = ([$x, $y, ($flag&0x3f)?100:50]);
	if ($flag&0x3f) {
		push(@ret, [$x, $y, 120, $dir+90, $dir+270]);
		push(@ret, [$x, $y, 175, $dir+220, $dir+230]) if ($flag&0x02);
		push(@ret, [$x, $y, 120, $dir+30, $dir+60]) if ($flag&0x08);
		push(@ret, [$x, $y, 160, $dir+255, $dir+275]) if ($flag&0x10);
		push(@ret, [$x, $y, 160, $dir+160, $dir+200]) if ($flag&0x20);
	}
	return \@ret;
}

sub pat4_cons {
	my ($x, $y, $dir, $flag) = @_;
	my @ret = ();
	if ($flag & 0x3f) {
		add_con(\@ret, $x, $y, ($flag&0x04)?125:100, $dir);
		add_con(\@ret, $x, $y, 175, $dir+225) if ($flag & 0x02);
		add_con(\@ret, $x, $y, 120, $dir+45) if ($flag & 0x08);
		add_con(\@ret, $x, $y, 160, $dir+270) if ($flag & 0x10);
		add_con(\@ret, $x, $y, 120, $dir+180) unless ($flag & 0x20);
	} else {
		add_con(\@ret, $x, $y, 50, $dir+225);
		add_con(\@ret, $x, $y, 50, $dir+270);
	}
	return \@ret;
}

#=======

sub pat5_draw {
	my ($x, $y, $dir, $flag) = @_;
	
	if ($flag & 0x200) {
		draw_circle($x, $y, 100, $dir, $dir+188);
		draw_circle($x, $y, 100, $dir+202, $dir+360);
	} else {
		draw_circle($x, $y, 100);
	}
	draw_text_in_circle($x, $y, 100, $dir+245, $dir+290, random_str(10), $font1);

	draw_line_from_circle($x, $y, 0, 0, 100, $dir);
	draw_line_from_circle($x, $y, 0, 0, 100, $dir+15);
	draw_line_from_circle($x, $y, 0, 0, 100, $dir+90);
	draw_line_from_circle($x, $y, 0, 0, 70, $dir+180);
	draw_line_from_circle($x, $y, 70, $dir+180, 20, $dir+90);
	draw_line_from_circle($x, $y, 70, $dir+180, 20, $dir+270);
	draw_line_from_circle($x, $y, 78, $dir+180, 20, $dir+90);
	draw_line_from_circle($x, $y, 78, $dir+180, 20, $dir+270);
	draw_line_from_circle($x, $y, 78, $dir+180, 22, $dir+180);
	draw_line_from_circle($x, $y, 0, 0, 100, $dir+240);
	draw_circle($x, $y, 25, $dir, $dir+15);
	draw_circle($x, $y, 33, $dir, $dir+15);
	draw_circle($x, $y, 70, $dir+15, $dir+90);
	draw_circle($x, $y, 25, $dir+90, $dir+240);
	draw_circle($x, $y, 50, $dir+240, $dir+375);
	draw_text_in_circle($x, $y, 62, $dir+270, $dir+300, random_str(3), $font1);

	if ($flag & 0x100) {
		my ($dx1, $dy1, $x1, $y1) = calc_line_from_circle($x, $y, 0, 0, 100, $dir+90);
		draw_circle($x1, $y1, 30);
	}
	
	if ($flag & 0x200) {
		my ($dx1, $dy1, $x1, $y1) = calc_line_from_circle($x, $y, 0, 0, 100, $dir+195);
		draw_circle($x1, $y1, 12);
		draw_line_from_circle($x1, $y1, 0, 0, 12, $dir+195);
		draw_line_from_circle($x1, $y1, 0, 0, 12, $dir+15);
	}

	if ($flag & 0x400) {
		draw_circle($x, $y, 110, $dir+230, $dir+250);
	}

	if ($flag & 0x01) {
		draw_line_from_circle($x, $y, 100, $dir+180, 20, $dir+180);
		draw_circle($x, $y, 120, $dir+150, $dir+210);
		draw_text_in_circle($x, $y, 135, $dir+150, $dir+210, random_str(15), $font1);
	}
}

sub pat5_objs {
	my ($x, $y, $dir, $flag) = @_;
	my @ret = ([$x, $y, 100]);
	if ($flag&0x200) {
		push(@ret, [$x, $y, 135, $dir+150, $dir+210]);
	}
	return \@ret;
}

sub pat5_cons {
	my ($x, $y, $dir, $flag) = @_;
	my @ret = ();
	add_con(\@ret, $x, $y, 100, $dir);
	add_con(\@ret, $x, $y, 100, $dir+90);
	unless ($flag&0x400) {
		add_con(\@ret, $x, $y, 100, $dir+240);
	}
	unless ($flag&0x1) {
		add_con(\@ret, $x, $y, 100, $dir+180);
	}
	return \@ret;
}


#=======

sub genr_draw {
	my ($x, $y, $dir, $flag) = @_;
	my (@r, @s, @t, @lf, $i);

	$r[0] = $flag&0x01?100:75;
	$s[0] = int(rand(8))*45;
	$t[0] = $s[0] + int(rand(5))*90;
	draw_circle($x, $y, $r[0]);
	draw_text_in_circle($x, $y, $r[0], $s[0], $t[0], random_str($r[0]/1.5*($t[0]-$s[0])/360), $font1);

	$r[1] = ($flag&0x01 && rand()<0.5) ? 75 : 50;
	$r[2] = 25;
	
	for (1..2) {
		$s[$_] = int(rand(8))*45;
		$t[$_] = $s[$_] + int(rand(5))*90;
		$t[$_] = $s[$_]+45 if ($s[$_] == $t[$_]);
		draw_circle($x, $y, $r[$_], $s[$_], $t[$_]);
	}

	for (1..2) {
		$lf[$_] = [];
		for ($i = 0; $i < 4; $i++) {
			my $k = ($s[$_]/45 + int(rand(($t[$_]-$s[$_])/45+1))) % 8;
			$lf[$_][$k] = 1;
			for (my $j = $_-1; $j >= 1; $j--) {
				unless ( $s[$j] < $k*45 && $k*45 < $t[$j] ||
							$t[$j] > 360 && $k*45 < $t[$j]-360 ) {
					$lf[$j][$k] = 1;
				}
			}
		}
	}
	for my $k (1..2) {
		for ($i = 0; $i < 8; $i++) {
			draw_line_from_circle($x, $y, $r[$k], $i*45, $r[$k-1]-$r[$k], $i*45, 3*(rand()<0.3)) if ($lf[$k][$i]);
		}
	}
	if ($t[2]-$s[2] <= 90 || $t[2]-$s[2] == 180 && rand() < 0.5 ) {
		draw_line_from_circle($x, $y, 0, 0, $r[2], $s[2]);
		draw_line_from_circle($x, $y, 0, 0, $r[2], $t[2]);
	}
}

sub genr_objs {
	my ($x, $y, $dir, $flag) = @_;
	my @ret = ([$x, $y, $flag&0x01?100:75]);
	return \@ret;
}

sub genr_cons {
	my ($x, $y, $dir, $flag) = @_;
	my @ret = ();
	my $r = $flag&0x01?100:75;
	for (my $d = 0; $d < 360; $d+=45) {
		add_con(\@ret, $x, $y, $r, $dir+$d);
	}
	return \@ret;
}