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); } }