Java中每个像素的延迟绘制

时间:2018-11-06 09:04:49

标签: java canvas javafx rendering pixel

我尝试使用Java逐像素绘制Sierpinski三角形。而且成功了。但是现在我想以较小的延迟绘制每个像素。我使用了不同类型的方法,但是没有成功。

  • Javafx动画计时器
  • Thread.sleep(100)

这是我的 Main.class

import java.util.Random;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.stage.Stage;

public class Main extends Application {

    private Point[] triangle;
    private static int points = 1000000;
    private static Point midPoint;

    private int width = 600, height = 600;

    @Override
    public void start(Stage primaryStage) {

        Canvas canvas = new Canvas(width,height);
        GraphicsContext gc = canvas.getGraphicsContext2D();

        Scene scene = new Scene(new Group(canvas));
        primaryStage.setScene(scene);
        primaryStage.show();

        Random ran = new Random();
        triangle = new Point[3];
        triangle[1] = new Point(0d, 0d);
        triangle[0] = new Point(width/2d, (double)height);
        triangle[2] = new Point((double)width, 0d);
        midPoint = Point.findMidTo(triangle[0], triangle[1], triangle[2]);
        while(points-- > 0){
                int r = ran.nextInt(3);
                midPoint = midPoint.findMidTo(triangle[r]);
                gc.fillOval(midPoint.getX(), midPoint.getY(),1,1);
                /*
                    Need a delay for each iteration  (Problem !!!!!!!!!!)
                */
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这是 Point.class ,它保持x和y坐标以及一些有用的像素键功能

class Point {

    private double x, y; 

    public Point(double x, double y) { 
        this.x = x;
        this.y = y;
    }

    public double getX() { return this.x; } 
    public double getY() { return this.y; } 

    // bunch of overloaded functions 
    public Point findMidTo(Point p) { 
    return new Point((this.getX() + p.getX())/2, (this.getY() + p.getY())/2);
    }

    public Point findMidTo(Point p1, Point p2) { 
    return new Point((this.getX() + p1.getX() + p2.getX())/3, 
             (this.getY() + p1.getY() + p2.getY())/3 ); 
    }

    public static Point findMidTo(Point p1, Point p2, Point p3) {
        return new Point((p1.getX() + p2.getX() + p3.getX())/3,
             (p1.getY() + p2.getY() + p3.getY())/3 ); 
    }
}

3 个答案:

答案 0 :(得分:3)

动画计时器似乎可以正常工作。

主要

00.434 => 0.434

答案 1 :(得分:2)

我真的很喜欢@ bakcsa83的答案,但是我会使用Timeline。它为您提供了更多内置控制,让您可以更快地填充点。

import java.util.Random;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Main extends Application
{

    Timeline timer;

    private Point[] triangle;
    private static int points = 1000000;
    private static Point midPoint;

    private int width = 600, height = 600;

    @Override
    public void start(Stage primaryStage)
    {
        Canvas canvas = new Canvas(width, height);
        GraphicsContext gc = canvas.getGraphicsContext2D();

        Scene scene = new Scene(new Group(canvas));
        primaryStage.setScene(scene);
        primaryStage.show();

        Random ran = new Random();
        triangle = new Point[3];
        triangle[1] = new Point(0d, 0d);
        triangle[0] = new Point(width / 2d, (double) height);
        triangle[2] = new Point((double) width, 0d);
        midPoint = Point.findMidTo(triangle[0], triangle[1], triangle[2]);

        timer = new Timeline(new KeyFrame(Duration.millis(.1), (ActionEvent event) -> {
            if (points-- > 0) {
                int r = ran.nextInt(3);
                midPoint = midPoint.findMidTo(triangle[r]);
                gc.fillOval(midPoint.getX(), midPoint.getY(), 1, 1);
            }
            else {
                System.out.println("Stopping!");
                timer.stop();
            }
        }));
        timer.setCycleCount(Timeline.INDEFINITE);
        timer.play();

    }

    public static void main(String[] args)
    {
        launch(args);
    }
}

答案 2 :(得分:-2)

使用线程是延迟Java程序中某些任务的最佳选择