package japlot;
import org.freehep.graphics2d.VectorGraphics;
import java.awt.Polygon;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import org.apache.commons.math3.util.FastMath;
public class DrawUtils {
// variable to build arrows
protected int al = 10; // Arrow length
protected int aw = 5; // Arrow width
protected int haw = 2; // Half arrow width
protected double hhaw = 0.5; // Half arrow width
protected int xValues[] = new int[3];
protected int yValues[] = new int[3];
public void drawArrow(VectorGraphics g, int x1, int y1, int x2, int y2) {
// Draw line
g.drawLine(x1, y1, x2, y2);
// Calculate x-y values for arrow head
calcValues(x1, y1, x2, y2);
g.fillPolygon(xValues, yValues, 3);
}
/* CALC VALUES: Calculate x-y values. */
public void calcValues(int x1, int y1, int x2, int y2) {
// North or south
if (x1 == x2) {
// North
if (y2 < y1)
arrowCoords(x2, y2, x2 - haw, y2 + al, x2 + haw, y2 + al);
// South
else
arrowCoords(x2, y2, x2 - haw, y2 - al, x2 + haw, y2 - al);
return;
}
// East or West
if (y1 == y2) {
// East
if (x2 > x1)
arrowCoords(x2, y2, x2 - al, y2 - haw, x2 - al, y2 + haw);
// West
else
arrowCoords(x2, y2, x2 + al, y2 - haw, x2 + al, y2 + haw);
return;
}
// Calculate quadrant
calcValuesQuad(x1, y1, x2, y2);
}
/*
* CALCULATE VALUES QUADRANTS: Calculate x-y values where direction is not
* parallel to eith x or y axis.
*/
public void calcValuesQuad(int x1, int y1, int x2, int y2) {
double arrowAng = FastMath.toDegrees(FastMath.atan((double) haw / (double) al));
double dist = FastMath.sqrt(al * al + aw);
double lineAng = FastMath.toDegrees(FastMath.atan(((double) FastMath.abs(x1 - x2))
/ ((double) FastMath.abs(y1 - y2))));
// Adjust line angle for quadrant
if (x1 > x2) {
// South East
if (y1 > y2)
lineAng = 180.0 - lineAng;
} else {
// South West
if (y1 > y2)
lineAng = 180.0 + lineAng;
// North West
else
lineAng = 360.0 - lineAng;
}
// Calculate coords
xValues[0] = x2;
yValues[0] = y2;
calcCoords(1, x2, y2, dist, lineAng - arrowAng);
calcCoords(2, x2, y2, dist, lineAng + arrowAng);
}
/*
* CALCULATE COORDINATES: Determine new x-y coords given a start x-y and a
* distance and direction
*/
public void calcCoords(int index, int x, int y, double dist, double dirn) {
// System.out.println("dirn = " + dirn);
while (dirn < 0.0)
dirn = 360.0 + dirn;
while (dirn > 360.0)
dirn = dirn - 360.0;
// System.out.println("dirn = " + dirn);
// North-East
if (dirn <= 90.0) {
xValues[index] = x + (int) (FastMath.sin(FastMath.toRadians(dirn)) * dist);
yValues[index] = y - (int) (FastMath.cos(FastMath.toRadians(dirn)) * dist);
return;
}
// South-East
if (dirn <= 180.0) {
xValues[index] = x
+ (int) (FastMath.cos(FastMath.toRadians(dirn - 90)) * dist);
yValues[index] = y
+ (int) (FastMath.sin(FastMath.toRadians(dirn - 90)) * dist);
return;
}
// South-West
if (dirn <= 90.0) {
xValues[index] = x
- (int) (FastMath.sin(FastMath.toRadians(dirn - 180)) * dist);
yValues[index] = y
+ (int) (FastMath.cos(FastMath.toRadians(dirn - 180)) * dist);
}
// Nort-West
else {
xValues[index] = x
- (int) (FastMath.cos(FastMath.toRadians(dirn - 270)) * dist);
yValues[index] = y
- (int) (FastMath.sin(FastMath.toRadians(dirn - 270)) * dist);
}
}
// ARROW COORDS: Load x-y value arrays */
public void arrowCoords(int x1, int y1, int x2, int y2, int x3, int y3) {
xValues[0] = x1;
yValues[0] = y1;
xValues[1] = x2;
yValues[1] = y2;
xValues[2] = x3;
yValues[2] = y3;
}
/**
* Draw arrow
*
*
* this allows you to draw an arrow with
* headlength (headsize),
* headwidth (headsize - difference),
* hedheight (factor (relative to headlength)),
*
* @param g
* @param x1
* @param y1
* @param x2
* @param y2
*/
public void drawArrow2(VectorGraphics g,int x1, int y1, int x2, int y2) {
// g.drawPolygon(getArrow(x1, y1, x2, y2, 10, 5,0.5));
g.drawPolygon(getArrow(x1, y1, x2, y2, al, aw, hhaw));
}
private Polygon getArrow(int x1, int y1, int x2, int y2, int headsize, int difference, double factor) {
int[] crosslinebase = getArrowHeadLine(x1, y1, x2, y2, headsize);
int[] headbase = getArrowHeadLine(x1, y1, x2, y2, headsize - difference);
int[] crossline = getArrowHeadCrossLine(crosslinebase[0], crosslinebase[1], x2, y2, factor);
Polygon head = new Polygon();
head.addPoint(headbase[0], headbase[1]);
head.addPoint(crossline[0], crossline[1]);
head.addPoint(x2, y2);
head.addPoint(crossline[2], crossline[3]);
head.addPoint(headbase[0], headbase[1]);
head.addPoint(x1, y1);
return head;
}
private int[] getArrowHeadLine(int xsource, int ysource,int xdest,int ydest, int distance) {
int[] arrowhead = new int[2];
int headsize = distance;
double stretchfactor = 0;
stretchfactor = 1 - (headsize/(FastMath.sqrt(((xdest-xsource)*(xdest-xsource))+((ydest-ysource)*(ydest-ysource)))));
arrowhead[0] = (int) (stretchfactor*(xdest-xsource))+xsource;
arrowhead[1] = (int) (stretchfactor*(ydest-ysource))+ysource;
return arrowhead;
}
private int[] getArrowHeadCrossLine(int x1, int x2, int b1, int b2, double factor) {
int [] crossline = new int[4];
int x_dest = (int) (((b1-x1)*factor)+x1);
int y_dest = (int) (((b2-x2)*factor)+x2);
crossline[0] = (int) ((x1+x2-y_dest));
crossline[1] = (int) ((x2+x_dest-x1));
crossline[2] = crossline[0]+(x1-crossline[0])*2;
crossline[3] = crossline[1]+(x2-crossline[1])*2;
return crossline;
}
/**
* Draws a point-type corresponding to a symbolic constant, yielding values
* from 0 to NO_SYMBOL (==13).
*
* @param index
* symbolic constant
* @param g2
* graphics 2D instance
* @param x
* x-coordinate of the midpoint of the point
* @param y
* y-coordinate of the midpoint of the point
* @param ps
* size of the point in pixels
*/
public static void drawPointType(int index, VectorGraphics g2, double _x, double _y,
float ps) {
if (index > 12 || ps <= 0.0f)
return;
float x = (float) (_x) - ps / 2.0f;
float y = (float) (_y) - ps / 2.0f;
if (index == 0)
g2.draw(new Ellipse2D.Float(x, y, ps, ps));
else if (index == 1)
g2.draw(new Rectangle2D.Float(x, y, ps, ps));
else if (index == 2) {
GeneralPath gp = new GeneralPath();
gp.moveTo(x, y + ps / 2.0f);
gp.lineTo(x + ps / 2.0f, y + ps);
gp.lineTo(x + ps, y + ps / 2.0f);
gp.lineTo(x + ps / 2.0f, y);
gp.lineTo(x, y + ps / 2.0f);
g2.draw(gp);
} else if (index == 3) {
GeneralPath gp = new GeneralPath();
gp.moveTo(x, y + ps);
gp.lineTo(x + ps, y + ps);
gp.lineTo(x + ps / 2.0f, y);
gp.lineTo(x, y + ps);
g2.draw(gp);
}
if (index == 4) {
g2.draw(new Ellipse2D.Float(x, y, ps, ps));
g2.fill(new Ellipse2D.Float(x, y, ps, ps));
} else if (index == 5) {
g2.draw(new Rectangle2D.Float(x, y, ps, ps));
g2.fill(new Rectangle2D.Float(x, y, ps, ps));
} else if (index == 6) {
GeneralPath gp = new GeneralPath();
gp.moveTo(x, y + ps / 2.0f);
gp.lineTo(x + ps / 2.0f, y + ps);
gp.lineTo(x + ps, y + ps / 2.0f);
gp.lineTo(x + ps / 2.0f, y);
gp.lineTo(x, y + ps / 2.0f);
g2.draw(gp);
g2.fill(gp);
} else if (index == 7) {
GeneralPath gp = new GeneralPath();
gp.moveTo(x, y + ps);
gp.lineTo(x + ps, y + ps);
gp.lineTo(x + ps / 2.0f, y);
gp.lineTo(x, y + ps);
g2.draw(gp);
g2.fill(gp);
} else if (index == 8) {
g2.draw(new Line2D.Float(x, y + ps / 2.0f, x + ps, y + ps / 2.0f));
g2.draw(new Line2D.Float(x + ps / 2.0f, y, x + ps / 2.0f, y + ps));
} else if (index == 9) {
g2.draw(new Line2D.Float(x, y, x + ps, y + ps));
g2.draw(new Line2D.Float(x + ps, y, x, y + ps));
} else if (index == 10) {
g2.draw(new Line2D.Float(x, y + ps / 2.0f, x + ps, y + ps / 2.0f));
g2.draw(new Line2D.Float(x + ps / 2.0f, y, x + ps / 2.0f, y + ps));
g2.draw(new Line2D.Float(x, y, x + ps, y + ps));
g2.draw(new Line2D.Float(x + ps, y, x, y + ps));
} else if (index == 11) {
g2.draw(new Line2D.Float(x + ps / 2.0f, y + ps / 2.0f, x + ps
/ 2.0f, y + ps / 2.0f));
} else if (index == 12) {
g2.draw(new Line2D.Float(x, y + ps / 3.0f, x + ps, y + ps / 3.0f));
g2.draw(new Line2D.Float(x, y + 2.0f * ps / 3.0f, x + ps, y + 2.0f
* ps / 3.0f));
g2.draw(new Line2D.Float(x + ps / 3.0f, y, x + ps / 3.0f, y + ps));
g2.draw(new Line2D.Float(x + 2.0f * ps / 3.0f, y, x + 2.0f * ps
/ 3.0f, y + ps));
}
}
}
Ads help maintain this website.