mkb@rover.ri.cmu.edu (Mike Blackwell) (03/07/91)
Here are two routines I whipped up which draw a line with an arrowhead at
the end. They both use the fixed point math routines for speed. The first
draws the arrowhead with an arc of a circle, the second makes the arrowhead
with all straight lines.
Mike Blackwell mkb@rover.ri.cmu.edu
/************************************************************************/
/* Draw a line with an arrowhead at the end. */
/* */
/* Mike Blackwell mkb@rover.ri.cmu.edu */
/* The Robotics Institute Carnegie Mellon University */
/************************************************************************/
void OldArrow(Point start, Point end, short size)
// Draw a line from start to end, and put an arrowhead at the end.
// No error checking - start and end better not be the same...
{
Fixed ang;
long iang;
Rect r;
// Figure out the angle of the line
ang = FixATan2(end.h - start.h, end.v - start.v);
// Convert to degrees
ang = FixMul(ang, X2Fix(57.2957795131));
iang = 270 + Fix2Long(ang); // Convert to Arc style angle
// Draw the line
MoveTo(start.h, start.v);
LineTo(end.h, end.v);
// Center a square over the end point
SetRect(&r, -size, -size, size, size);
OffsetRect(&r, end.h, end.v);
// Draw the arrow head (arc section of a circle)
PaintArc(&r, iang - 15, 30);
}
void Arrow(Point start, Point end, short size)
// Draw a line from start to end, and put an arrowhead at the end. Size is
// length of arrowhead, and also width of base. Line length must be non-zero
// for anything to be drawn.
{
Fixed len; // Length of line
long dx, dy; // Delta X and Y of line
Fixed lx, ly; // dx/len, dy/len
Fixed xm, ym; // The point where the arrow base crosses the line
Fixed xa, ya; // Arrow base point translated to start, rotated 90
long p1x, p1y; // One arrow base point
long p2x, p2y; // And the other
PolyHandle arrowHead;
dx = end.h - start.h;
dy = end.v - start.v;
len = X2Fix(sqrt((extended)((dx * dx) + (dy * dy))));
if (len > 0) {
lx = FixDiv(Long2Fix(dx), len);
ly = FixDiv(Long2Fix(dy), len);
xm = Long2Fix((long)start.h) + FixMul((len - Long2Fix((long)size)), lx);
ym = Long2Fix((long)start.v) + FixMul((len - Long2Fix((long)size)), ly);
xa = FixMul(Long2Fix((long)(size / 2)), lx);
ya = FixMul(Long2Fix((long)(size / 2)), ly);
// Rotate the point +/- 90, and translate up to mid point
p1x = Fix2Long(xm - ya);
p1y = Fix2Long(ym + xa);
p2x = Fix2Long(xm + ya);
p2y = Fix2Long(ym - xa);
MoveTo(start.h, start.v);
LineTo(end.h, end.v);
arrowHead = OpenPoly();
MoveTo(end.h, end.v);
LineTo(p1x, p1y);
LineTo(p2x, p2y);
LineTo(end.h, end.v);
ClosePoly();
PaintPoly(arrowHead);
KillPoly(arrowHead);
}
}