* dx ->
*/
if (m_polygon == null)
{
Point2DArray arr = new Point2DArray();
try
{
ArrowType type = getArrowType();
double a = Geometry.toRadians(getArrowAngle());
double sina = Math.sin(a);
double cosa = Math.cos(a);
// NOTE: b is not the base angle here, it's the corner EAB
// i.e. going from E to A to B, where B is point[2] and A is the
// intersection of the midline (thru S and E)
// and the line thru point [1] and [2].
double b_degrees = 180 - getBaseAngle() - getArrowAngle();
double b = Geometry.toRadians(b_degrees);
double sinb = Math.sin(b);
double cosb = Math.cos(b);
double w = getBaseWidth();
double aw = getHeadWidth();
Point2D s = getStart(); // arr.getPoint(0);
Point2D e = getEnd(); // arr.getPoint(1);
Point2D dv = e.minus(s);
Point2D dx = dv.unit(); // unit vector in the direction of SE
Point2D dy = dx.perpendicular();
if (type == ArrowType.AT_END || type == ArrowType.AT_END_TAPERED || type == ArrowType.AT_BOTH_ENDS)
{
// cosa*r
//
// S----+---E
// | a/ sina*r=aw/2
// sina*r | / r
// |/
// 2
//
double r = aw / (2 * sina);
double z = r * cosa;
Point2D p2 = e.minus(dx.times(z)).minus(dy.times(aw / 2));
Point2D p4 = e.minus(dx.times(z)).plus(dy.times(aw / 2));
// cosb*r2
//
// 1---+
// \b |
// \ | sinb*r2=(aw-w)/2
// r2 \|
// 2
//
Point2D p1 = p2.plus(dy.times((aw - w) / 2));
Point2D p5 = p4.minus(dy.times((aw - w) / 2));
if (b_degrees != 90)
{
double r2 = (aw - w) / (2 * sinb);
Point2D d1 = dx.times(r2 * cosb);
p1 = p1.minus(d1);
p5 = p5.minus(d1);
}
arr.push(p1);
arr.push(p2);
arr.push(e);
arr.push(p4);
arr.push(p5);
}
else if (type == ArrowType.AT_START)
{
Point2D q0 = e.plus(dy.times(-w / 2));
Point2D q6 = e.plus(dy.times(w / 2));
arr.push(q0);
arr.push(q6);
}
else
// ArrowType.AT_START_TAPERED
{
arr.push(e);
}
if (type == ArrowType.AT_START || type == ArrowType.AT_START_TAPERED || type == ArrowType.AT_BOTH_ENDS)
{
// cosa*r
//
// S----+---E
// | a/ sina*r=aw/2
// sina*r | / r
// |/
// 2
//
double r = aw / (2 * sina);
double z = r * cosa;
Point2D q2 = s.plus(dx.times(z)).minus(dy.times(aw / 2));
Point2D q4 = s.plus(dx.times(z)).plus(dy.times(aw / 2));
// cosb*r2
//
// 1---+
// \b |
// \ | sinb*r2=(aw-w)/2
// r2 \|
// 2
//
Point2D q1 = q2.plus(dy.times((aw - w) / 2));
Point2D q5 = q4.minus(dy.times((aw - w) / 2));
if (b_degrees != 90)
{
double r2 = (aw - w) / (2 * sinb);
Point2D d1 = dx.times(r2 * cosb);
q1 = q1.plus(d1);
q5 = q5.plus(d1);
}
arr.push(q5);
arr.push(q4);
arr.push(s);
arr.push(q2);
arr.push(q1);
}
else if (type == ArrowType.AT_END)
{
Point2D p0 = s.plus(dy.times(-w / 2));
Point2D p6 = s.plus(dy.times(w / 2));
arr.push(p6);
arr.push(p0);
}
else
// ArrowType.AT_END_TAPERED
{
arr.push(s);
}
}
catch (GeometryException e)
{
// This can happen e.g. when S and E are the same point.