Revision 1:c26885f609ba

View differences:

pom.xml
3 3
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4 4
    <modelVersion>4.0.0</modelVersion>
5 5

  
6
    <name>Alite Vis2D package</name>
6
    <name>Alite Visualizer2D package</name>
7 7
    <groupId>cz.agents.alite</groupId>
8
    <artifactId>vis2d</artifactId>
9
    <version>1.0-SNAPSHOT</version>
8
    <artifactId>visualizer2d</artifactId>
9
    <version>0.0.1-SNAPSHOT</version>
10 10

  
11 11
    <parent>
12 12
        <groupId>cz.agents</groupId>
......
26 26
    </properties>
27 27

  
28 28
    <dependencies>
29
        <dependency>
29
        <!--<dependency>
30 30
            <groupId>cz.agents.alite</groupId>
31 31
            <artifactId>alite</artifactId>
32 32
            <version>1.1.0</version>
33
        </dependency>
33
        </dependency>-->
34 34
        <dependency>
35 35
            <groupId>junit</groupId>
36 36
            <artifactId>junit</artifactId>
......
41 41
            <groupId>java3d</groupId>
42 42
            <artifactId>vecmath</artifactId>
43 43
            <version>1.5.2</version>
44
            <type>jar</type>
44
            <!--<type>jar</type>-->
45 45
        </dependency>
46 46
    </dependencies>
47 47

  
src/main/java/cz/agents/alite/vis2d/Point2dAdapter.java
1
package cz.agents.alite.vis2d;
2

  
3
import javax.vecmath.Point2d;
4

  
5
/**
6
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
7
 */
8
public interface Point2dAdapter<T> {
9

  
10
    public static final Point2dAdapter<Point2d> IDENTITY = point2d -> point2d;
11

  
12
    public Point2d convert(T t);
13

  
14
}
src/main/java/cz/agents/alite/vis2d/Visualizable.java
1
package cz.agents.alite.vis2d;
2

  
3
import java.awt.*;
4
import java.awt.geom.Rectangle2D;
5

  
6
/**
7
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
8
 */
9
public interface Visualizable {
10

  
11
    public void paint(Graphics2D canvas, Rectangle2D drawingRectangle);
12

  
13
}
src/main/java/cz/agents/alite/vis2d/VisualizableLayer.java
1
package cz.agents.alite.vis2d;
2

  
3
import cz.agents.alite.vis.Vis;
4
import cz.agents.alite.vis.layer.AbstractLayer;
5

  
6
import java.awt.*;
7
import java.awt.geom.Rectangle2D;
8

  
9
/**
10
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
11
 */
12
public class VisualizableLayer extends AbstractLayer {
13

  
14
    private final VisualizableProvider provider;
15

  
16
    public VisualizableLayer(VisualizableProvider provider) {
17
        this.provider = provider;
18
    }
19

  
20
    @Override
21
    public void paint(Graphics2D canvas) {
22
        Dimension dim = Vis.getDrawingDimension();
23
        Rectangle2D drawingRectangle = new Rectangle(dim);
24
        provider.getData().forEach(element -> element.paint(canvas, drawingRectangle));
25
    }
26
}
src/main/java/cz/agents/alite/vis2d/VisualizableProvider.java
1
package cz.agents.alite.vis2d;
2

  
3
/**
4
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
5
 */
6
public interface VisualizableProvider {
7

  
8
    public Iterable<? extends Visualizable> getData();
9

  
10
}
src/main/java/cz/agents/alite/vis2d/demo/AngleProvider.java
1
package cz.agents.alite.vis2d.demo;
2

  
3
import javax.vecmath.Point2d;
4
import java.util.Timer;
5
import java.util.TimerTask;
6

  
7
/**
8
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
9
 */
10
class AngleProvider {
11

  
12
    private static final double RADIUS = 100;
13
    private static final double ANGLE_STEP = 0.05;
14
    private static final int PERIOD = 25;
15
    public static final double TRANS_Y = 500;
16
    public static final double TRANS_X = 500;
17

  
18
    private final Timer timer = new Timer("AngleProviderTimer", true);
19
    private volatile double angle = 0;
20
    private volatile Point2d point = new Point2d();
21

  
22
    public AngleProvider() {
23
        TimerTask task = new TimerTask() {
24
            @Override
25
            public void run() {
26
                angle += ANGLE_STEP;
27
                updatePoint();
28
            }
29
        };
30

  
31
        timer.scheduleAtFixedRate(task, 0, PERIOD);
32
    }
33

  
34
    private void updatePoint() {
35
        final double angle1 = angle;
36
        point = new Point2d(TRANS_X + RADIUS * Math.sin(angle1), TRANS_Y + RADIUS * Math.cos(angle1));
37
    }
38

  
39
    public double getAngle() {
40
        return angle;
41
    }
42

  
43
    public Point2d getPoint() {
44
        return point;
45
    }
46
}
src/main/java/cz/agents/alite/vis2d/demo/Demo.java
1
package cz.agents.alite.vis2d.demo;
2

  
3
import cz.agents.alite.vis.VisManager;
4
import cz.agents.alite.vis.layer.common.ColorLayer;
5
import cz.agents.alite.vis2d.VisualizableLayer;
6
import cz.agents.alite.vis2d.implementation.PointVis;
7

  
8
import javax.vecmath.Point2d;
9
import java.awt.*;
10
import java.util.Arrays;
11

  
12
import static cz.agents.alite.vis2d.Point2dAdapter.IDENTITY;
13

  
14
/**
15
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
16
 */
17
public class Demo {
18

  
19

  
20
    public static void main(String[] args) {
21
        final AngleProvider angleProvider = new AngleProvider();
22
        VisManager.setInitParam("Test", 1024, 768, 1024, 768);
23
        VisManager.registerLayer(ColorLayer.create(Color.BLACK));
24
        VisManager.registerLayer(new VisualizableLayer(() -> Arrays.asList(
25
                new PointVis<>(new Point2d(AngleProvider.TRANS_X, AngleProvider.TRANS_Y), 3, Color.RED, IDENTITY),
26
                new PointVis<>(angleProvider.getPoint(), 3, Color.WHITE, IDENTITY))));
27
        VisManager.init();
28
    }
29

  
30
}
src/main/java/cz/agents/alite/vis2d/implementation/PointVis.java
1
package cz.agents.alite.vis2d.implementation;
2

  
3
import cz.agents.alite.vis.Vis;
4
import cz.agents.alite.vis2d.Point2dAdapter;
5
import cz.agents.alite.vis2d.Visualizable;
6

  
7
import javax.vecmath.Point2d;
8
import java.awt.*;
9
import java.awt.geom.Ellipse2D;
10
import java.awt.geom.Rectangle2D;
11

  
12
/**
13
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
14
 */
15
public class PointVis<T> implements Visualizable {
16

  
17
    private final T centerPosition;
18
    private final int radiusInPx;
19
    private final Point2dAdapter<T> adapter;
20
    private final Color color;
21

  
22
    public PointVis(T centerPosition, int radiusInPx, Color color, Point2dAdapter<T> adapter) {
23
        this.centerPosition = centerPosition;
24
        this.radiusInPx = radiusInPx;
25
        this.adapter = adapter;
26
        this.color = color;
27
    }
28

  
29
    @Override
30
    public void paint(Graphics2D canvas, Rectangle2D drawingRectangle) {
31
        Point2d center = adapter.convert(centerPosition);
32
        int x = Vis.transX(center.x);
33
        int y = Vis.transY(center.y);
34
        canvas.setColor(color);
35

  
36
        Ellipse2D point = new Ellipse2D.Double(x - radiusInPx, y - radiusInPx,
37
                2 * radiusInPx + 1, 2 * radiusInPx + 1);
38

  
39
        if (drawingRectangle.intersects(point.getBounds2D())) {
40
            canvas.fill(point);
41
        }
42
    }
43
}
src/main/java/cz/agents/alite/visualizer2d/Layer.java
1
package cz.agents.alite.visualizer2d;
2

  
3
/**
4
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
5
 */
6
public interface Layer {
7

  
8
    public void paint(VisCanvas canvas);
9

  
10
}
src/main/java/cz/agents/alite/visualizer2d/LayerContainer.java
1
package cz.agents.alite.visualizer2d;
2

  
3
import java.util.List;
4
import java.util.concurrent.CopyOnWriteArrayList;
5

  
6
/**
7
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
8
 */
9
public class LayerContainer {
10

  
11
    private final List<Layer> layers = new CopyOnWriteArrayList<>();
12

  
13
    final void updateLayers(final VisCanvas visCanvas) {
14
        for (Layer layer : layers) {
15
            layer.paint(visCanvas);
16
        }
17
    }
18

  
19
    public void addLayer(Layer layer) {
20
        if (!layers.contains(layer)) {
21
            layers.add(layer);
22
        }
23
    }
24

  
25
}
src/main/java/cz/agents/alite/visualizer2d/Point2dAdapter.java
1
package cz.agents.alite.visualizer2d;
2

  
3
import javax.vecmath.Point2d;
4

  
5
/**
6
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
7
 */
8
public interface Point2dAdapter<T> {
9

  
10
    public static final Point2dAdapter<Point2d> IDENTITY = point2d -> point2d;
11

  
12
    public Point2d convert(T t);
13

  
14
}
src/main/java/cz/agents/alite/visualizer2d/VisCanvas.java
1
package cz.agents.alite.visualizer2d;
2

  
3
import java.awt.*;
4
import java.awt.geom.AffineTransform;
5

  
6
/**
7
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
8
 */
9
public final class VisCanvas {
10

  
11
    private boolean originalTransformSet = true;
12
    private final AffineTransform worldAffineTransform;
13
    private final AffineTransform originalTransform;
14
    private final Graphics2D canvas;
15

  
16
    public VisCanvas(AffineTransform worldAffineTransform, Graphics2D canvas) {
17
        this.originalTransform = canvas.getTransform();
18
        this.worldAffineTransform = new AffineTransform(originalTransform);
19
        this.worldAffineTransform.concatenate(worldAffineTransform);
20
        this.canvas = canvas;
21
    }
22

  
23
    public final Graphics2D getWorldCanvas() {
24
        if (originalTransformSet) {
25
            canvas.setTransform(worldAffineTransform);
26
            originalTransformSet = false;
27
        }
28
        return canvas;
29
    }
30

  
31
    public final Graphics2D getOriginalCanvas() {
32
        if (!originalTransformSet) {
33
            canvas.setTransform(originalTransform);
34
            originalTransformSet = true;
35
        }
36
        return canvas;
37
    }
38
}
src/main/java/cz/agents/alite/visualizer2d/VisPane.java
1
package cz.agents.alite.visualizer2d;
2

  
3
import javax.swing.*;
4
import java.awt.*;
5
import java.awt.geom.AffineTransform;
6
import java.awt.image.BufferStrategy;
7
import java.util.concurrent.ScheduledThreadPoolExecutor;
8
import java.util.concurrent.TimeUnit;
9

  
10
/**
11
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
12
 */
13
public class VisPane {
14

  
15
    private double scale = 1;
16
    private double transX = 0, transY = 0;
17
    private double rotationInRad = 0;
18

  
19
    private static final int REFRESH_IN_MS = 40; //25 FPS
20
    private static final int VIS_THREAD_PRIORITY = Thread.MIN_PRIORITY;
21

  
22
    private final LayerContainer layerContainer = new LayerContainer();
23

  
24
    private boolean reinitializeBuffers = true;
25
    private BufferStrategy strategy;
26
    private Graphics2D graphics;
27

  
28
    private final JPanel panel = new JPanel();
29
    private final Canvas canvas = new Canvas();
30

  
31
    public VisPane() {
32
        canvas.setBounds(0, 0, 1024, 768);
33
        panel.add(canvas);
34
    }
35

  
36
    public void start() {
37
        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
38
        executor.scheduleAtFixedRate(this::update, 0, REFRESH_IN_MS, TimeUnit.MILLISECONDS);
39
    }
40

  
41
    public JPanel getPanel() {
42
        return panel;
43
    }
44

  
45
    public void registerLayer(Layer layer) {
46
        layerContainer.addLayer(layer);
47
    }
48

  
49
    private boolean reinitializeBuffers() {
50
        if (reinitializeBuffers) {
51
            reinitializeBuffers = false;
52

  
53
            canvas.createBufferStrategy(2);
54
            strategy = canvas.getBufferStrategy();
55

  
56
            graphics = (Graphics2D) strategy.getDrawGraphics();
57
            graphics.setColor(Color.WHITE);
58
            graphics.setBackground(Color.BLACK);
59

  
60
            return true;
61
        }
62

  
63
        return false;
64
    }
65

  
66
    private void update() {
67
        if (canvas.isDisplayable()) {
68
            reinitializeBuffers();
69

  
70
            AffineTransform affineTransform = calculateAffineTransform();
71
            VisCanvas visCanvas = new VisCanvas(affineTransform, graphics);
72

  
73
            layerContainer.updateLayers(visCanvas);
74
            strategy.show();
75
        }
76
    }
77

  
78
    private AffineTransform calculateAffineTransform() {
79
        AffineTransform affineTransform = new AffineTransform();
80
        synchronized (this) {
81
            affineTransform.translate(transX, transY);
82
            affineTransform.scale(scale, scale);
83
            affineTransform.rotate(rotationInRad);
84
        }
85
        return affineTransform;
86
    }
87

  
88
}
src/main/java/cz/agents/alite/visualizer2d/Visualizable.java
1
package cz.agents.alite.visualizer2d;
2

  
3
import java.awt.*;
4

  
5
/**
6
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
7
 */
8
public interface Visualizable {
9

  
10
    public void paint(Graphics2D canvas);
11

  
12
}
src/main/java/cz/agents/alite/visualizer2d/VisualizableLayer.java
1
package cz.agents.alite.visualizer2d;
2

  
3
import java.awt.*;
4

  
5
/**
6
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
7
 */
8
public class VisualizableLayer implements Layer {
9

  
10
    private final VisualizableProvider provider;
11

  
12
    public VisualizableLayer(VisualizableProvider provider) {
13
        this.provider = provider;
14
    }
15

  
16
    //TODO check if forEach is as fast as for each cycle
17
    @Override
18
    public void paint(VisCanvas canvas) {
19
        final Graphics2D worldCanvas = canvas.getWorldCanvas();
20
        provider.getData().forEach(element -> element.paint(worldCanvas));
21
    }
22
}
src/main/java/cz/agents/alite/visualizer2d/VisualizableProvider.java
1
package cz.agents.alite.visualizer2d;
2

  
3
/**
4
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
5
 */
6
public interface VisualizableProvider {
7

  
8
    public Iterable<? extends Visualizable> getData();
9

  
10
}
src/main/java/cz/agents/alite/visualizer2d/demo/AngleProvider.java
1
package cz.agents.alite.visualizer2d.demo;
2

  
3
import javax.vecmath.Point2d;
4
import java.util.Timer;
5
import java.util.TimerTask;
6

  
7
/**
8
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
9
 */
10
class AngleProvider {
11

  
12
    private static final double RADIUS = 100;
13
    private static final double ANGLE_STEP = 0.05;
14
    private static final int PERIOD = 25;
15
    public static final double TRANS_Y = 500;
16
    public static final double TRANS_X = 500;
17

  
18
    private final Timer timer = new Timer("AngleProviderTimer", true);
19
    private volatile double angle = 0;
20
    private volatile Point2d point = new Point2d();
21

  
22
    public AngleProvider() {
23
        TimerTask task = new TimerTask() {
24
            @Override
25
            public void run() {
26
                angle += ANGLE_STEP;
27
                updatePoint();
28
            }
29
        };
30

  
31
        timer.scheduleAtFixedRate(task, 0, PERIOD);
32
    }
33

  
34
    private void updatePoint() {
35
        final double angle1 = angle;
36
        point = new Point2d(TRANS_X + RADIUS * Math.sin(angle1), TRANS_Y + RADIUS * Math.cos(angle1));
37
    }
38

  
39
    public double getAngle() {
40
        return angle;
41
    }
42

  
43
    public Point2d getPoint() {
44
        return point;
45
    }
46
}
src/main/java/cz/agents/alite/visualizer2d/demo/Demo.java
1
package cz.agents.alite.visualizer2d.demo;
2

  
3
import cz.agents.alite.visualizer2d.VisPane;
4
import cz.agents.alite.visualizer2d.VisualizableLayer;
5
import cz.agents.alite.visualizer2d.implementation.ColorLayer;
6
import cz.agents.alite.visualizer2d.implementation.Point;
7

  
8
import javax.swing.*;
9
import javax.vecmath.Point2d;
10
import java.awt.*;
11
import java.util.Arrays;
12

  
13
import static cz.agents.alite.visualizer2d.Point2dAdapter.IDENTITY;
14

  
15
/**
16
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
17
 */
18
public class Demo {
19

  
20

  
21
    public static void main(String[] args) {
22
        final AngleProvider angleProvider = new AngleProvider();
23
        JFrame frame = new JFrame("Visualizer2d Demo");
24
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
25
        frame.setSize(1024, 768);
26
        //frame.setLayout(new GridLayout(1, 1));
27

  
28
        VisPane visPane = new VisPane();
29
        frame.setContentPane(visPane.getPanel());
30

  
31
        visPane.registerLayer(new ColorLayer(Color.BLACK));
32
        visPane.registerLayer(new VisualizableLayer(() -> Arrays.asList(
33
                new Point<>(new Point2d(AngleProvider.TRANS_X, AngleProvider.TRANS_Y), 3, Color.RED, IDENTITY),
34
                new Point<>(angleProvider.getPoint(), 3, Color.WHITE, IDENTITY))));
35
        visPane.start();
36
        frame.setVisible(true);
37
        //frame.pack();
38
    }
39

  
40
}
src/main/java/cz/agents/alite/visualizer2d/implementation/ColorLayer.java
1
package cz.agents.alite.visualizer2d.implementation;
2

  
3
import cz.agents.alite.visualizer2d.Layer;
4
import cz.agents.alite.visualizer2d.VisCanvas;
5

  
6
import java.awt.*;
7

  
8
/**
9
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
10
 */
11
public class ColorLayer implements Layer {
12

  
13
    private final Color color;
14

  
15
    public ColorLayer(Color color) {
16
        this.color = color;
17
    }
18

  
19
    @Override
20
    public void paint(VisCanvas canvas) {
21
        Graphics2D graphics = canvas.getOriginalCanvas();
22
        graphics.setColor(color);
23
        Rectangle rectangle = graphics.getClipBounds();
24
        graphics.fillRect(0, 0, 1024, 768);
25
    }
26
}
src/main/java/cz/agents/alite/visualizer2d/implementation/Point.java
1
package cz.agents.alite.visualizer2d.implementation;
2

  
3
import cz.agents.alite.visualizer2d.Point2dAdapter;
4
import cz.agents.alite.visualizer2d.Visualizable;
5

  
6
import javax.vecmath.Point2d;
7
import java.awt.*;
8
import java.awt.geom.Ellipse2D;
9

  
10
/**
11
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
12
 */
13
public class Point<T> implements Visualizable {
14

  
15
    private final T centerPosition;
16
    private final int radiusInPx;
17
    private final Point2dAdapter<T> adapter;
18
    private final Color color;
19

  
20
    public Point(T centerPosition, int radius, Color color, Point2dAdapter<T> adapter) {
21
        this.centerPosition = centerPosition;
22
        this.radiusInPx = radius;
23
        this.adapter = adapter;
24
        this.color = color;
25
    }
26

  
27
    @Override
28
    public void paint(Graphics2D canvas) {
29
        Point2d center = adapter.convert(centerPosition);
30
        canvas.setColor(color);
31

  
32
        Ellipse2D point = new Ellipse2D.Double(center.x - radiusInPx, center.y - radiusInPx,
33
                2 * radiusInPx + 1, 2 * radiusInPx + 1);
34
        canvas.fill(point);
35
    }
36
}

Also available in: Unified diff