Skip to content

Instantly share code, notes, and snippets.

@siritori
Created November 14, 2014 01:46
Show Gist options
  • Save siritori/fd9f9e225f85a5048b1a to your computer and use it in GitHub Desktop.
Save siritori/fd9f9e225f85a5048b1a to your computer and use it in GitHub Desktop.
複素関数論 マンデルブロ集合
!!!html5
%html
%body
%form{:action => '.', :method => 'get'}
width
%input{:name => 'width', :value => @params['width']}
height
%input{:name => 'height', :value => @params['height']}
fineness
%input{:name => 'fineness', :value => @params['fineness']}
center_x
%input{:name => 'center_x', :value => @params['center_x']}
center_y
%input{:name => 'center_y', :value => @params['center_y']}
%input{:type => 'submit', :value => '描画'}
%img{src: @result_path}
#include <math.h>
#include <complex.h>
const int MAX_ITERATION = 20;
const double THRESHOLD = 3.5f;
int calc
(
const unsigned w, const unsigned h, const double cx, const double cy,
const double step,
const unsigned x, const unsigned y
)
{
double real = step * (x - w/2.0) + cx;
double imag = step * (h/2.0 - y) + cy;
double complex c = real + I * imag;
double complex z = c;
for(int i = 0; i < MAX_ITERATION; ++i) {
if(cabs(z) > THRESHOLD) {
return 255 - i * 10;
}
z = z * z + c;
}
return 0;
}
# coding: UTF-8
require 'ffi'
require 'zlib'
require 'sinatra'
module Mandelbrot
extend FFI::Library
ffi_lib "libmandelbrot.so"
attach_function :calc, [:uint, :uint, :double, :double, :double, :uint, :uint], :int
end
# チャンクのバイト列生成関数
def chunk(type, data)
[data.bytesize, type, data, Zlib.crc32(type + data)].pack('NA4A*N')
end
def data2png width, height, data
# ファイルシグニチャ
res = "\x89PNG\r\n\x1a\n".force_encoding(Encoding::BINARY)
# ヘッダ
res += chunk('IHDR', [width, height, 8, 2, 0, 0, 0].pack('NNCCCCC'))
# 画像データ
img_data = data.map {|l| ([0] + l.flatten).pack('C*') }.join
res += chunk('IDAT', Zlib::Deflate.deflate(img_data))
# 終端
res + chunk('IEND', '')
end
get '/' do
defaults = {
'width' => '500',
'height' => '500',
'fineness' => '0.006',
'center_x' => '-0.7',
'center_y' => '0.0',
}
@params = params
defaults.keys.each do |s|
@params[s] ||= defaults[s]
@params[s] = @params[s].to_f
end
@params['width'] = @params['width'].to_i
@params['height'] = @params['height'].to_i
raw_data = (0...@params['height']).map do |y|
(0...@params['width']).map do |x|
res = Mandelbrot.calc @params['width'], @params['height'], @params['center_x'], @params['center_y'], @params['fineness'], x, y
[res, res, res]
end
end
png = data2png @params['width'], @params['height'], raw_data
@result_path = rand(999999).to_s + '.png'
File.binwrite('./public/' + @result_path, png)
haml :index
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment