Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.vesalainen.ui.Plotter Maven / Gradle / Ivy
/*
* Copyright (C) 2014 Timo Vesalainen
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.vesalainen.ui;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import javax.imageio.ImageIO;
import org.ejml.data.DenseMatrix64F;
import org.vesalainen.math.Circle;
import org.vesalainen.math.Point;
import org.vesalainen.math.Polygon;
import org.vesalainen.math.Rect;
/**
*
* @author Timo Vesalainen
*/
public class Plotter extends AbstractView
{
private Color color = Color.BLACK;
protected final List drawables = new ArrayList<>();
private File dir;
private double lastX = Double.NaN;
private double lastY = Double.NaN;
protected final Color background;
public Plotter(int width, int height)
{
this(width, height, new Color(255, 255, 255, 255));
}
public Plotter(int width, int height, Color background)
{
super.setScreen(width, height);
this.background = background;
}
public void clear()
{
drawables.clear();
}
public void setDir(File dir)
{
this.dir = dir;
}
public void setColor(Color color)
{
this.color = color;
}
public void drawCircle(Circle circle)
{
drawCircle(circle.getX(), circle.getY(), circle.getRadius());
}
public void drawCircle(double x, double y, double r)
{
updateCircle(x, y, r);
drawables.add(new Circl(color, x, y, r));
}
public void drawPoint(DenseMatrix64F point)
{
assert point.numCols == 1;
assert point.numRows == 2;
double[] d = point.data;
double x = d[0];
double y = d[1];
updatePoint(x, y);
drawables.add(new Pnt(color, x, y));
}
public void drawPoint(Point p)
{
drawPoint(p.getX(), p.getY());
}
public void drawPoint(double x, double y)
{
updatePoint(x, y);
drawables.add(new Pnt(color, x, y));
}
public void drawPolygon(Polygon polygon)
{
updatePolygon(polygon);
drawables.add(new Poly(color, polygon));
}
public void drawPolygon(DenseMatrix64F polygon)
{
updatePolygon(polygon);
drawables.add(new Poly(color, polygon));
}
public void lineTo(double x, double y)
{
if (Double.isNaN(lastX))
{
moveTo(x, y);
}
else
{
drawLine(lastX, lastY, x, y);
moveTo(x, y);
}
}
public void moveTo(double x, double y)
{
lastX = x;
lastY = y;
}
public void drawLine(Point p1, Point p2)
{
drawLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
}
public void drawLine(double x1, double y1, double x2, double y2)
{
updatePoint(x1, y1);
updatePoint(x2, y2);
drawables.add(new Lin(color, x1, y1, x2, y2));
}
public void drawPolyline(Polyline polyline)
{
updateRect(polyline.getBounds());
drawables.add(polyline);
}
public void drawCoordinateLine(double x1, double y1, double x2, double y2)
{
updatePoint(x1, y1);
updatePoint(x2, y2);
drawables.add(0, new Lin(color, x1, y1, x2, y2));
}
public void drawLines(double[] data)
{
updatePolygon(data, data.length);
drawables.add(new Lines(color, data));
}
public void drawLines(Polygon polygon)
{
updatePolygon(polygon);
drawables.add(new Lines(color, polygon));
}
public void drawLines(DenseMatrix64F polygon)
{
updatePolygon(polygon);
drawables.add(new Lines(color, polygon));
}
public void drawCoordinates()
{
Color safe = color;
int minx = (int) (xMin-1);
int maxx = (int) (xMax+1);
int miny = (int) (yMin-1);
int maxy = (int) (yMax+1);
color = Color.BLACK;
drawCoordinateLine(minx, 0, maxx, 0);
drawCoordinateLine(0, miny, 0, maxy);
color = Color.LIGHT_GRAY;
for (int x=minx;x<=maxx;x++)
{
drawCoordinateLine(x, miny, x, maxy);
}
for (int y=miny;y<=maxy;y++)
{
drawCoordinateLine(minx, y, maxx, y);
}
color = safe;
}
@Override
public void setScreen(double width, double height)
{
throw new UnsupportedOperationException("Screen coordinates must be set in constructor");
}
public void plotToDocFiles(Class> cls, String filename, String ext) throws IOException
{
String dirName = String.format("src/main/resources/%s/doc-files",
cls.getPackage().getName().replace('.', '/'));
File dir = new File(dirName);
dir.mkdirs();
File file = new File(dir, filename+"."+ext);
plot(file, ext);
}
public void plot(String filename, String ext) throws IOException
{
File file;
if (dir != null)
{
file = new File(dir, filename+'.'+ext);
}
else
{
file = new File(filename+'.'+ext);
}
plot(file, ext);
}
public void plot(File file, String ext) throws IOException
{
BufferedImage image = new BufferedImage((int)width, (int)height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D graphics2D = image.createGraphics();
graphics2D.setBackground(background);
graphics2D.clearRect(0, 0, (int)width, (int)height);
Graphics2DDrawer g2d = new Graphics2DDrawer(graphics2D);
drawables.stream().forEach((d) ->
{
d.draw(g2d);
});
try (FileOutputStream fos = new FileOutputStream(file))
{
//System.err.println(Arrays.toString(ImageIO.getWriterMIMETypes())); // [image/vnd.wap.wbmp, image/png, image/x-png, image/jpeg, image/bmp, image/gif]
ImageIO.write(image, ext, fos);
}
catch (IOException ex)
{
throw ex;
}
}
public static class Drawable
{
Color color;
public Drawable(Color color)
{
this.color = color;
}
public void draw(Drawer drawer)
{
drawer.color(color);
}
}
protected class Pnt extends Drawable
{
double x;
double y;
public Pnt(Color color, double x, double y)
{
super(color);
this.x = x;
this.y = y;
}
@Override
public void draw(Drawer drawer)
{
super.draw(drawer);
int sx = (int) toScreenX(x);
int sy = (int) toScreenY(y);
drawer.ellipse(sx-2, sy-2, 2, 2);
}
}
protected class Circl extends Pnt
{
double r;
public Circl(Color color, double x, double y, double r)
{
super(color, x, y);
this.r = r;
}
@Override
public void draw(Drawer drawer)
{
super.draw(drawer);
int sx = (int) toScreenX(x);
int sy = (int) toScreenY(y);
int sr = (int) scaleToScreen(r);
drawer.ellipse(sx-sr, sy-sr, sr, sr);
}
}
protected class Poly extends Drawable
{
double[] data;
public Poly(Color color, double[] data)
{
super(color);
this.data = data;
}
public Poly(Color color, Polygon polygon)
{
super(color);
DenseMatrix64F m = polygon.points;
this.data = Arrays.copyOf(m.data, m.getNumElements());
}
private Poly(Color color, DenseMatrix64F m)
{
super(color);
this.data = Arrays.copyOf(m.data, m.getNumElements());
}
@Override
public void draw(Drawer drawer)
{
super.draw(drawer);
int len = data.length/2;
if (len >= 2)
{
double x1 = toScreenX(data[2*(len-1)]);
double y1 = toScreenY(data[2*(len-1)+1]);
for (int r=0;r= 2)
{
double x[] = new double[len];
double y[] = new double[len];
x[0] = toScreenX(data[0]);
y[0] = toScreenY(data[1]);
for (int r=1;r xData = new ArrayList<>();
private List yData = new ArrayList<>();
private Rect bounds = new Rect();
protected Polyline(Color color)
{
super(color);
}
public void lineTo(Point p)
{
lineTo(p.getX(), p.getY());
}
public void lineTo(double x, double y)
{
xData.add(x);
yData.add(y);
bounds.update(x, y);
}
public void lineTo(Stream stream)
{
stream.forEach(this::lineTo);
}
public Rect getBounds()
{
return bounds;
}
@Override
public void draw(Drawer drawer)
{
super.draw(drawer);
double[] xArr = new double[xData.size()];
double[] yArr = new double[yData.size()];
int len = xArr.length;
for (int ii=0;ii