<> <> <> <> DIRECTORY GGLines, GGModelTypes, GGShapes, Imager, ImagerBackdoor, ImagerPath, ImagerTransformation, Real; GGShapesImpl: CEDAR PROGRAM IMPORTS GGLines, Imager, ImagerBackdoor, ImagerPath EXPORTS GGShapes = BEGIN Camera: TYPE = GGModelTypes.Camera; Circle: TYPE = GGModelTypes.Circle; Line: TYPE = GGModelTypes.Line; Point: TYPE = GGModelTypes.Point; Ray: TYPE = GGModelTypes.Ray; Vector: TYPE = GGModelTypes.Vector; DrawSquare: PUBLIC PROC [dc: Imager.Context, center: Point, side: REAL] = { halfSide: REAL _ side/2.0; DoDrawSquare: PROC = { SquarePath: Imager.PathProc = { moveTo[[- halfSide, - halfSide]]; lineTo[[- halfSide, halfSide]]; lineTo[[ halfSide, halfSide]]; lineTo[[ halfSide, - halfSide]]; lineTo[[- halfSide, - halfSide]]; }; Imager.SetXY[dc, [center[1], center[2]]]; Imager.Trans[dc]; Imager.SetStrokeWidth[dc, 1.0]; Imager.MaskStroke[dc, SquarePath, TRUE]; }; Imager.DoSaveAll[dc, DoDrawSquare]; }; DrawPlus: PUBLIC PROC [dc: Imager.Context, center: Point] = { halfSide: REAL = 5.0; DoDrawPlus: PROC = { Horiz: Imager.PathProc = { moveTo[[-halfSide, 0.0]]; lineTo[[halfSide, 0.0]]; }; Vert: Imager.PathProc = { moveTo[[0.0, -halfSide]]; lineTo[[0.0, halfSide]]; }; Imager.SetXY[dc, [center[1], center[2]]]; Imager.Trans[dc]; Imager.SetStrokeWidth[dc, 2.0]; Imager.MaskStroke[dc, Horiz, FALSE]; Imager.MaskStroke[dc, Vert, FALSE]; }; Imager.DoSaveAll[dc, DoDrawPlus]; }; DrawRectangle: PUBLIC PROC [dc: Imager.Context, loX, loY, hiX, hiY: REAL] = { <> RectanglePath: Imager.PathProc = { moveTo[[loX, loY]]; lineTo[[loX, hiY]]; lineTo[[ hiX, hiY]]; lineTo[[ hiX, loY]]; lineTo[[loX, loY]]; }; Imager.SetStrokeWidth[dc, 1.0]; Imager.MaskStroke[dc, RectanglePath, TRUE]; }; DrawCaret: PUBLIC PROC [dc: Imager.Context, point: Point] = { height: REAL = 8.0; halfWidth: REAL = 3.0; DoDrawCaret: PROC = { t: ImagerPath.Trajectory; Imager.SetXY[dc, [point[1], point[2]]]; Imager.Trans[dc]; t _ ImagerPath.MoveTo[[-halfWidth, -height]]; t _ ImagerPath.LineTo[t, [0.0, 0.0]]; t _ ImagerPath.LineTo[t, [halfWidth, -height]]; Imager.SetStrokeWidth[dc, 1.0]; Imager.MaskStrokeTrajectory[dc, t, FALSE]; }; Imager.DoSaveAll[dc, DoDrawCaret]; }; DrawAnchor: PUBLIC PROC [dc: Imager.Context, point: Point] = { DrawFilledSquare[dc, point, 10.0]; }; DrawFilledSquare: PUBLIC PROC [dc: Imager.Context, center: Point, side: REAL] = { halfSide: REAL _ side/2.0; DoDrawFilledSquare: PROC = { Imager.SetXY[dc, [center[1], center[2]]]; Imager.Trans[dc]; Imager.MaskRectangle[dc, [- halfSide, - halfSide, side, side]]; }; Imager.DoSaveAll[dc, DoDrawFilledSquare]; }; DrawSpot: PUBLIC PROC [dc: Imager.Context, point: Point] = { DoDrawSpot: PROC = { Imager.SetXY[dc, [point[1], point[2]]]; Imager.Trans[dc]; Imager.MaskRectangle[dc, [0.0, 0.0, 1.0, 1.0]]; }; Imager.DoSaveAll[dc, DoDrawSpot]; }; DrawFilledRect: PUBLIC PROC [dc: Imager.Context, point: Point, side: REAL] = { DoDrawRect: PROC = { Imager.SetXY[dc, [point[1], point[2]]]; Imager.Trans[dc]; Imager.MaskRectangle[dc, [0.0, 0.0, side, side]]; }; Imager.DoSaveAll[dc, DoDrawRect]; }; DrawLine: PUBLIC PROC [dc: Imager.Context, line: Line] = { rect: ImagerTransformation.Rectangle _ ImagerBackdoor.GetBounds[dc]; count: NAT; ray: Ray; params: ARRAY[1..2] OF REAL; p1, p2, basePoint: Point; direction: Vector; DoDrawLine: PROC = { Imager.SetXY[dc, [p1[1], p1[2]]]; Imager.Trans[dc]; Imager.MaskVector[dc, [0.0, 0.0], [p2[1] - p1[1], p2[2] - p1[2]]]; }; p1 _ [rect.x, rect.y]; p2 _ [rect.x + rect.w, rect.y + rect.h]; basePoint _ GGLines.PointOnLine[line]; direction _ GGLines.DirectionOfLine[line]; ray _ GGLines.CreateRay[basePoint, direction]; [count, params] _ GGLines.LineRayMeetsBox[ray, p1[1], p1[2], p2[1], p2[2]]; IF count = 2 THEN { p1 _ GGLines.EvalRay[ray, params[1]]; p2 _ GGLines.EvalRay[ray, params[2]]; Imager.DoSaveAll[dc, DoDrawLine]; }; }; DrawLittleLine: PUBLIC PROC [dc: Imager.Context, line: Line, point: Point] = { <> }; DrawCircle: PUBLIC PROC [dc: Imager.Context, circle: Circle] = { leftSide, rightSide: Point; DoDrawCircle: PROC = { CirclePath: Imager.PathProc = { moveTo[[leftSide[1], leftSide[2]]]; arcTo[[rightSide[1], rightSide[2]], [ leftSide[1], leftSide[2]]]; }; Imager.SetStrokeWidth[dc, 1.0]; Imager.MaskStroke[dc, CirclePath, TRUE]; }; leftSide _ [circle.origin[1] - circle.radius, circle.origin[2]]; rightSide _ [circle.origin[1] + circle.radius, circle.origin[2]]; Imager.DoSaveAll[dc, DoDrawCircle]; }; DrawJoint: PUBLIC PROC [dc: Imager.Context, point: Point] = { DrawSquare[dc, point, GGModelTypes.jointSize]; }; DrawSelectedJoint: PUBLIC PROC [dc: Imager.Context, point: Point] = { DrawFilledSquare[dc, point, GGModelTypes.jointSize]; }; END.