Mandelbrot

 

�X�N���v�g

MandelbrotWorker.java

import java.util.concurrent.BlockingQueue;
 
import com.sun.javafx.runtime.async.AbstractAsyncOperation;
import com.sun.javafx.runtime.async.AsyncOperationListener;
 
public class MandelbrotWorker extends AbstractAsyncOperation<Object> {
    // �C�x���g�f�B�X�p�b�`�X���b�h�Ƌ��L����L���[
    // �X���b�h�Z�[�t��BlockingQueue�C���^�t�F�[�X���g�p����
    private BlockingQueue<Point> queue;
    
    public MandelbrotWorker(BlockingQueue<Point> queue, AsyncOperationListener<Object> listener) {
        super(listener);
         
        // �C�x���g�f�B�X�p�b�`�X���b�h�ƃL���[�����L
        this.queue = queue;
    }
 
    // �񓯊��ɍs������
    @Override
    public Object call() throws InterruptedException {
        for (double x = -2.0; x <= 0.6; x += 0.005) {
            for (double y = -1.2; y <= 1.2; y += 0.005) {
                Point c = new Point(x, y, 0);
                Point z = new Point(0.0, 0.0, 0);
 
                while (true) {
                    // �Q�����̌v�Z
                    z = calcNextPoint(z, c);
 
                    // z�̑傫����100,000�ȏ�ł���Ζ�����ƌ��Ȃ�
                    // �܂��A215��ȏ�̃C�e���[�V�������J��Ԃ��Ă�
                    // 100,000�ȏ�ɂȂ�Ȃ���΃}���f���u���W���ɑ����Ă���ƌ��Ȃ�
                    if (z.length() > 100000 || z.number > 215) {
                        break;
                    }
                }
                // �C�e���[�V���������R�s�[����
                c.number = z.number;
 
                // �v�Z���ʂ��L���[�ɓ����
                queue.put(c);
            }
        }
 
        return null;
    }
 
    // �}���f���u���̑Q����
    private Point calcNextPoint(Point z, Point c) {
        double x = z.x * z.x - z.y * z.y + c.x;
        double y = 2 * z.x * z.y + c.y;
 
        return new Point(x, y, z.number + 1);
    }
}

Point.java

// �}���f���u���̌v�Z���ʂ��i�[����N���X
public class Point {
    public double x;
    public double y;
 
    // ������ƌ��Ȃ����C�e���[�V������
    // �ő�215��Ƃ���
    public int number;
 
    public Point(double x, double y, int number) {
        this.x = x;
        this.y = y;
        this.number = number;
    }
 
    public double length() {
        return x * x + y * y;
    }
}

Mandelbrot.fx

import javafx.async.AbstractAsyncOperation;
 
import java.lang.Object;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
 
import com.sun.javafx.runtime.async.AsyncOperationListener;
 
public class Mandelbrot extends AbstractAsyncOperation {
    // �X���b�h�ԂŃf�[�^���󂯓n������L���[
    // �X���b�h�Z�[�t��BlockingQueue�C���^�t�F�[�X���g�p����
    var queue: BlockingQueue;
     
    // �񓯊��������s��Java�N���X
    var worker: MandelbrotWorker;
 
    public override function start(): Void {
        // �X���b�h�Ԃ̌v�Z���ʂ̈��n���ɃL���[���g�p����
        // BlockingQueue�C���^�t�F�[�X�̃R���N���[�g�N���X�Ƃ���
        // LinkedBlockingQueue�N���X���g�p����
        queue = new LinkedBlockingQueue();
 
        // Java�̔񓯊���������
        worker = new MandelbrotWorker(queue, listener);
        // �񓯊������̊J�n
        worker.start();
    }
 
    public override function cancel(): Void {
        // �񓯊������̃L�����Z��
        worker.cancel();
    }
 
    public override function onCompletion(value: Object): Void {}
 
    // �L���[����v�Z���ʂ����o��
    public function poll(): Point {
        queue.poll() as Point;
    }
}

MandelbrotViewer.fx

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.ext.swing.SwingButton;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
 
import java.awt.image.BufferedImage;
 
// �F�̃C���f�b�N�X
var colors: Integer[] = for(i in [0..7]) {
    for (blue in [0, 0x66, 0xff], green in [0, 0x66, 0xff], red in [0, 0x66,0xff]) {
        var color = (0xff - red) * 0x10000 + (0xff - green) * 0x100 + (0xff - blue);
    }
}
 
// Image�N���X�̓s�N�Z���ɃA�N�Z�X�ł��Ȃ��̂ŁABufferedImage�N���X���g�p����
var bufferedImage: BufferedImage;
var image: Image;
 
// �񓯊��Ń}���f���u���̌v�Z���s���N���X
var mandelbrot: Mandelbrot;
 
// �񓯊��ōs���鏈�����猋�ʂ��󂯎�邽�߂̃^�C�����C��
var timeline: Timeline;
timeline = Timeline {
    repeatCount: Timeline.INDEFINITE
    keyFrames: [
        KeyFrame {
            time: 0.0s
            action: function() {
                while(true) {
                    // �L���[����v�Z���ʂ̎��o��
                    var point = mandelbrot.poll();
                    if (point != null) {
                        // �v�Z���ʂ���C���[�W�ɐF���Z�b�g����
                        var x = (point.x * 200 + 400) as Integer;
                        var y = (point.y * 200 + 240) as Integer;
                        var color = colors[point.number];
                        bufferedImage.setRGB(x, y, color);
                    } else {
                        // �L���[����ł���΁A0.1�b�҂�
                        break;
                    }
                }
                // BufferedImage����Image�I�u�W�F�N�g�𐶐�����
                image = Image.fromBufferedImage(bufferedImage);
            }
        },
        KeyFrame {
            time: 0.1s
            action: function() {
                // �񓯊��������I�����Ă�����Atimeline���X�g�b�v������
                if (mandelbrot.done) {
                    timeline.stop();
                }
            }
        }
    ]
}
 
Stage {
    title: "Mandelbrot"
    scene: Scene {
        width: 520
        height: 480
        fill: Color.BLACK
        content: [
            ImageView {
                image: bind image
            },
            SwingButton {
                text: "DRAW"
                action: function() {
                    timeline.stop();
                    if (mandelbrot != null) {
                        // �񓯊��ŏ������s���Ă���ꍇ�̓L�����Z��
                        mandelbrot.cancel();
                    }
 
                    // �C���[�W��Mandelbrot�I�u�W�F�N�g��V���ɐ������A
                    // �񓯊��������J�n����
                    bufferedImage = new BufferedImage(520, 480, BufferedImage.TYPE_INT_RGB);
                    mandelbrot = Mandelbrot {};
                    timeline.play();
                }
            }
        ]
    }
}