double alpha = Math.atan(anchor.getHeight() / anchor.getWidth());
AffineTransform at = new AffineTransform();
Shape shape = null;
Path p = null;
Rectangle2D bounds;
double scaleY = Math.pow(2, tailWidth.ordinal());
double scaleX = Math.pow(2, tailLength.ordinal());
switch (getLineTailDecoration()) {
case OVAL:
p = new Path();
shape = new Ellipse2D.Double(0, 0, lineWidth * scaleX, lineWidth * scaleY);
bounds = shape.getBounds2D();
at.translate(x2 - bounds.getWidth() / 2, y2 - bounds.getHeight() / 2);
at.rotate(alpha, bounds.getX() + bounds.getWidth() / 2, bounds.getY() + bounds.getHeight() / 2);
break;
case ARROW:
p = new Path();
GeneralPath arrow = new GeneralPath();
arrow.moveTo((float) (-lineWidth * 3), (float) (-lineWidth * 2));
arrow.lineTo(0, 0);
arrow.lineTo((float) (-lineWidth * 3), (float) (lineWidth * 2));
shape = arrow;
at.translate(x2, y2);
at.rotate(alpha);
break;
case TRIANGLE:
p = new Path();
scaleY = tailWidth.ordinal() + 1;
scaleX = tailLength.ordinal() + 1;
GeneralPath triangle = new GeneralPath();
triangle.moveTo((float) (-lineWidth * scaleX), (float) (-lineWidth * scaleY / 2));
triangle.lineTo(0, 0);