<> <> <> <> <> <> <<>> DIRECTORY GGBasicTypes, GGBoundBox, GGBuiltinShapes, GGModelTypes, GGOutline, GGSegment, GGSegmentTypes, GGTransform, GGSlice, GGTraj, Vectors2d, ImagerColor, RealFns, Rope; GGBuiltinShapesImpl: CEDAR PROGRAM IMPORTS GGBoundBox, GGOutline, GGSegment, GGSlice, GGTraj, GGTransform, Vectors2d, ImagerColor, RealFns EXPORTS GGBuiltinShapes = BEGIN DefaultData: TYPE = GGModelTypes.DefaultData; Outline: TYPE = GGModelTypes.Outline; Point: TYPE = GGBasicTypes.Point; Segment: TYPE = GGSegmentTypes.Segment; SegmentGenerator: TYPE = GGModelTypes.SegmentGenerator; Slice: TYPE = GGModelTypes.Slice; SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor; Traj: TYPE = GGModelTypes.Traj; Vector: TYPE = GGBasicTypes.Vector; Problem: PUBLIC SIGNAL [msg: Rope.ROPE] = CODE; PolygonInCircle: PUBLIC PROC [sideCount: NAT, origin: Point, radius: REAL, defaults: DefaultData] RETURNS [outline: Outline] = { <> traj: Traj; theta0, theta, deltaTheta, sin, cos: REAL; lastPoint, thisPoint: Point; success: BOOL; seg: Segment; deltaTheta _ 360.0/sideCount; theta0 _ -90.0 + deltaTheta/2.0; sin _ RealFns.SinDeg[theta0]; cos _ RealFns.CosDeg[theta0]; thisPoint _ Vectors2d.Add[Vectors2d.Scale[[cos, sin], radius], origin]; traj _ GGTraj.CreateTraj[thisPoint]; lastPoint _ thisPoint; FOR i: NAT IN [1..sideCount-1] DO theta _ theta0 + i*deltaTheta; sin _ RealFns.SinDeg[theta]; cos _ RealFns.CosDeg[theta]; thisPoint _ Vectors2d.Add[Vectors2d.Scale[[cos, sin], radius], origin]; seg _ GGSegment.MakeLine[lastPoint, thisPoint, NIL]; GGSegment.SetDefaults[seg, defaults]; success _ GGTraj.AddSegment[traj, hi, seg, lo]; IF NOT success THEN SIGNAL Problem[msg: "Couldn't add segment"]; lastPoint _ thisPoint; ENDLOOP; sin _ RealFns.SinDeg[theta0]; cos _ RealFns.CosDeg[theta0]; thisPoint _ Vectors2d.Add[Vectors2d.Scale[[cos, sin], radius], origin]; seg _ GGSegment.MakeLine[lastPoint, thisPoint, NIL]; GGSegment.SetDefaults[seg, defaults]; GGTraj.CloseWithSegment[traj, seg, lo]; outline _ GGOutline.CreateOutline[traj, ImagerColor.ColorFromGray[0.5]]; outline.class.setStrokeJoint[outline, outline.class.newParts[outline, NIL, topLevel].parts, defaults.strokeJoint]; outline.class.setFillColor[outline, defaults.fillColor]; }; Box: PUBLIC PROC [origin: Point, sideLength: REAL, defaults: DefaultData] RETURNS [slice: Slice] = { halfSide: REAL _ sideLength/2.0; box: GGBoundBox.BoundBox _ GGBoundBox.CreateBoundBox[origin.x-halfSide, origin.y-halfSide, origin.x+halfSide, origin.y+halfSide]; sliceD: SliceDescriptor _ GGSlice.MakeBoxSlice[box, ul, GGTransform.Identity[] ]; completeSliceD: SliceDescriptor _ sliceD.slice.class.newParts[sliceD.slice, NIL, slice]; slice _ sliceD.slice; GGSlice.SetDefaults[slice, completeSliceD.parts, defaults]; }; Circle: PUBLIC PROC [origin: Point, radius: REAL, defaults: DefaultData] RETURNS [slice: Slice] = { outerPoint: Point _ [origin.x + radius, origin.y]; sliceD: SliceDescriptor _ GGSlice.MakeCircleSlice[origin, outerPoint]; completeSliceD: SliceDescriptor _ sliceD.slice.class.newParts[sliceD.slice, NIL, slice]; slice _ sliceD.slice; GGSlice.SetDefaults[slice, completeSliceD.parts, defaults]; }; <> <> <<>> <<};>> <<>> KnotchedLine: PUBLIC PROC [p0, p1: Point, segmentCount: NAT] RETURNS [outline: Outline] = { <> delta: Vector; lastPoint, thisPoint: Point; traj: Traj; seg: Segment; success: BOOL; delta _ Vectors2d.Scale[Vectors2d.Sub[p1, p0], 1.0/segmentCount]; lastPoint _ p0; traj _ GGTraj.CreateTraj[lastPoint]; THROUGH [1..segmentCount-1] DO thisPoint _ Vectors2d.Add[lastPoint, delta]; seg _ GGSegment.MakeLine[lastPoint, thisPoint, NIL]; success _ GGTraj.AddSegment[traj, hi, seg, lo]; IF NOT success THEN SIGNAL Problem[msg: "Couldn't add segment"]; lastPoint _ thisPoint; ENDLOOP; thisPoint _ p1; seg _ GGSegment.MakeLine[lastPoint, thisPoint, NIL]; success _ GGTraj.AddSegment[traj, hi, seg, lo]; IF NOT success THEN SIGNAL Problem[msg: "Couldn't add segment"]; outline _ GGOutline.CreateOutline[traj, ImagerColor.ColorFromGray[0.5]]; }; <<>> END.