File: SVDrawImpl.mesa
Last edited by Bier on May 31, 1984 4:10:03 pm PDT
Author: Eric Bier on July 29, 1984 2:36:42 pm PDT
Contents: Some convenience functions to draw shapes not directly available in Cedar Graphics
DIRECTORY
Graphics,
GraphicsColor,
SV2d,
SVDraw,
SVLines2d,
SVVector2d;
SVDrawImpl: PROGRAM
IMPORTS Graphics, SVLines2d, SVVector2d
EXPORTS SVDraw =
BEGIN
Point2d: TYPE = SV2d.Point2d;
Polygon: TYPE = SV2d.Polygon;
globalSandwich: Graphics.Path ← Graphics.NewPath[2];
DrawLine:
PROC [dc: Graphics.Context, fromX, fromY, toX, toY:
REAL] = {
Graphics.SetCP[dc, fromX, fromY];
Graphics.DrawTo[dc, toX, toY];
};
Cross:
PUBLIC
PROC [dc: Graphics.Context, originX, originY, length:
REAL] = {
halfLength: REAL ← length/2.0;
DrawLine[dc, originX-halfLength, originY, originX+halfLength, originY];
DrawLine[dc, originX, originY-halfLength, originX, originY+halfLength];
};
centerLine: SV2d.TrigLine ← SVLines2d.CreateEmptyTrigLine[];
LineSandwich:
PUBLIC
PROC [dc: Graphics.Context, fromX, fromY, toX, toY:
REAL] = {
leftFirst, leftSecond, rightFirst, rightSecond: Point2d;
Draw three parallel lines, 2 black with 1 white in between so that the total width is three screen dots. This requires that we calculate the points with are 1 unit from the given central line segment and normal to that line segment.
Find the left and right segments given the center segment
SVLines2d.FillTrigLineFromPoints[[fromX, fromY], [toX, toY], centerLine];
leftFirst ← SVLines2d.PointLeftOfTrigLine[1, [fromX, fromY], centerLine];
leftSecond ← SVLines2d.PointLeftOfTrigLine[1, [toX, toY], centerLine];
rightFirst ← SVVector2d.Add[SVVector2d.Sub[[fromX, fromY], leftFirst], [fromX, fromY]];
rightSecond ← SVVector2d.Add[SVVector2d.Sub[[toX, toY], leftSecond], [toX, toY]];
Now draw the left line
Graphics.SetColor[dc, GraphicsColor.black]; -- black
Graphics.SetCP[dc, leftFirst[1], leftFirst[2]];
Graphics.DrawTo[dc, leftSecond[1], leftSecond[2]];
Now draw the center line
Graphics.SetColor[dc, GraphicsColor.white]; -- white
Graphics.SetCP[dc, fromX, fromY];
Graphics.DrawTo[dc, toX, toY];
Finally, draw the right line
Graphics.SetColor[dc, GraphicsColor.black]; -- black
Graphics.SetCP[dc, rightFirst[1], rightFirst[2]];
Graphics.DrawTo[dc, rightSecond[1], rightSecond[2]];
};
PadToScreen:
PUBLIC
PROC [padPoint: Point2d, origin: Point2d, scalar:
REAL ← 1]
RETURNS [screenPoint: Point2d] = {
padPoint ← SVVector2d.Scale[padPoint, scalar];
screenPoint[1] ← padPoint[1] + origin[1];
screenPoint[2] ← padPoint[2] + origin[2];
};
CrossHairs:
PUBLIC
PROC [dc: Graphics.Context, origin: Point2d] = {
leftPoint, rightPoint, topPoint, bottomPoint, screenPoint: Point2d;
leftPoint ← [-1000, 0];
rightPoint ← [1000, 0];
topPoint ← [0, 1000];
bottomPoint ← [0, -1000];
screenPoint ← PadToScreen[leftPoint, origin];
Graphics.MoveTo[globalSandwich, screenPoint[1], screenPoint[2]];
screenPoint ← PadToScreen[rightPoint, origin];
Graphics.LineTo[globalSandwich, screenPoint[1], screenPoint[2]];
Graphics.DrawStroke[dc, globalSandwich, 0, FALSE, square];
screenPoint ← PadToScreen[topPoint, origin];
Graphics.MoveTo[globalSandwich, screenPoint[1], screenPoint[2]];
screenPoint ← PadToScreen[bottomPoint, origin];
Graphics.LineTo[globalSandwich, screenPoint[1], screenPoint[2]];
Graphics.DrawStroke[dc, globalSandwich, 0, FALSE, square];
};
DrawPolygon:
PUBLIC
PROC [dc: Graphics.Context, poly: Polygon, origin: Point2d, scalar:
REAL ← 1] = {
poly is in Pad coordinates
transform each point to screen coordinates and draw using Graphics.
screenPoint0, screenPoint1, screenPoint2: Point2d;
IF poly.len <= 1 THEN RETURN;
screenPoint0 ← screenPoint1 ← PadToScreen[poly[0], origin, scalar];
FOR i:
NAT
IN [1..poly.len)
DO
screenPoint2 ← PadToScreen[poly[i], origin, scalar];
LineSandwich[dc, screenPoint1[1], screenPoint1[2], screenPoint2[1], screenPoint2[2]];
screenPoint1 ← screenPoint2;
ENDLOOP;
LineSandwich[dc, screenPoint1[1], screenPoint1[2], screenPoint0[1], screenPoint0[2]];
};
END.