package rescuecore2.misc.gui; import rescuecore2.misc.Pair; import java.awt.Graphics; /** A bunch of useful functions for drawing things. */ public final class DrawingTools { /** A default angle for arrow barbs. */ public static final double DEFAULT_ARROW_ANGLE = Math.toRadians(135); /** A default length (in pixels) for arrow barbs. */ public static final double DEFAULT_ARROW_LENGTH = 5; /** A default distance along the line for arrow barbs. */ public static final double DEFAULT_ARROW_DISTANCE = 0.5; private DrawingTools() {} /** Get the coordinates for arrow heads along a line. @param startX The start of the line (X). @param startY The start of the line (Y). @param endX The end of the line (X). @param endY The end of the line (Y). @param angle The angle of the arrow barbs. @param length The length of the arrow barbs. @param d The distance along the line to place the barbs. This must be between zero and one. @return A pair of coordinate pairs for the ends of the arrow barbs. */ public static Pair<Pair<Integer, Integer>, Pair<Integer, Integer>> getArrowHeads(int startX, int startY, int endX, int endY, double angle, double length, double d) { double dx = endX - startX; double dy = endY - startY; double headX = startX + (d * dx); double headY = startY + (d * dy); double vectorX = ((Math.cos(angle) * dx) - (Math.sin(angle) * dy)); double vectorY = ((Math.sin(angle) * dx) + (Math.cos(angle) * dy)); // Normalise the vector double vLength = Math.hypot(vectorX, vectorY); vectorX /= vLength; vectorY /= vLength; // Now calculate end points double leftX = headX + (vectorX * length); double leftY = headY + (vectorY * length); double rightX = headX - (vectorY * length); double rightY = headY + (vectorX * length); Pair<Integer, Integer> left = new Pair<Integer, Integer>((int)leftX, (int)leftY); Pair<Integer, Integer> right = new Pair<Integer, Integer>((int)rightX, (int)rightY); return new Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>(left, right); } /** Draw an arrowhead on a line. @param startX The start of the line (X). @param startY The start of the line (Y). @param endX The end of the line (X). @param endY The end of the line (Y). @param angle The angle of the arrow barbs. @param length The length of the arrow barbs. @param d The distance along the line to draw the barbs. This must be between zero and one. @param g The graphics object to draw on. */ public static void drawArrowHeads(int startX, int startY, int endX, int endY, double angle, double length, double d, Graphics g) { Pair<Pair<Integer, Integer>, Pair<Integer, Integer>> barbs = getArrowHeads(startX, startY, endX, endY, angle, length, d); int leftX = barbs.first().first(); int leftY = barbs.first().second(); int rightX = barbs.second().first(); int rightY = barbs.second().second(); double dx = endX - startX; double dy = endY - startY; int headX = (int)(startX + (d * dx)); int headY = (int)(startY + (d * dy)); g.drawLine(leftX, leftY, headX, headY); g.drawLine(rightX, rightY, headX, headY); } /** Draw an arrowhead on a line with some default options. @param startX The start of the line (X). @param startY The start of the line (Y). @param endX The end of the line (X). @param endY The end of the line (Y). @param g The graphics object to draw on. */ public static void drawArrowHeads(int startX, int startY, int endX, int endY, Graphics g) { drawArrowHeads(startX, startY, endX, endY, DEFAULT_ARROW_ANGLE, DEFAULT_ARROW_LENGTH, DEFAULT_ARROW_DISTANCE, g); } }