DIRECTORY Imager, ImagerPath, ImagerTransformation, Rope, Rosary; GGModelTypes: CEDAR DEFINITIONS = BEGIN jointSize: REAL = 6; MaxSegments: NAT = 100; Angle: TYPE = REAL; Point: TYPE = ARRAY[1..2] OF REAL; Matrix3by3: TYPE = ARRAY [1..3] OF ARRAY [1..3] OF REAL; Vector: TYPE = ARRAY[1..2] OF REAL; Edge: TYPE = REF EdgeObj; EdgeObj: TYPE = RECORD [ line: Line, -- the line which passes through the endpoints of this edge startIsFirst: BOOL, start, end: Point]; Line: TYPE = REF LineObj; LineObj: TYPE = RECORD [ theta: REAL, -- angle in (-pi..pi] d: REAL, -- distance from line to origin c: REAL, -- cos(theta). Cached for convenience. s: REAL, -- sin(theta). Cached for convenience. slope: REAL, yInt: REAL -- for historical (Solidviews) reasons ]; Circle: TYPE = REF CircleObj; CircleObj: TYPE = RECORD [ origin: Point, radius: REAL ]; Arc: TYPE = REF ArcObj; ArcObj: TYPE = RECORD [ circle: Circle, startIsFirst: BOOL, start, end: Point]; Ray: TYPE = REF RayObj; RayObj: TYPE = RECORD [ p: Point, d: Vector]; Camera: TYPE = REF CameraObj; CameraObj: TYPE = RECORD [ cameraWorld: Vector, scalar: REAL, cameraScreen: Vector ]; Scene: TYPE = REF SceneObj; SceneObj: TYPE = RECORD [ entities: LIST OF REF ANY _ NIL -- a list of clusters and outlines ]; SelectedObjectData: TYPE = RECORD [ normal: BOOL _ FALSE, copy: BOOL _ FALSE, hot: BOOL _ FALSE, active: BOOL _ FALSE ]; Cluster: TYPE = REF ClusterObj; ClusterObj: TYPE = RECORD [ children: LIST OF REF ANY, -- a list of clusters or outlines parent: Cluster, selected: SelectedObjectData, boundBox: BoundBox _ NIL ]; Outline: TYPE = REF OutlineObj; OutlineObj: TYPE = RECORD [ fillColor: Imager.Color, lineEnds: Imager.StrokeEnd, children: LIST OF Traj, parent: Cluster, boundBox: BoundBox, onOverlay: BOOL _ FALSE, whyOnOverlay: REF ANY, -- the selected piece of the outline selected: SelectedObjectData ]; Traj: TYPE = REF TrajObj; TrajObj: TYPE = RECORD [ role: FenceHoleOpen, segCount: NAT, -- the number of segments currently in this trajectory segments: Rosary.ROSARY, -- the segments themselves joints: Rosary.ROSARY, -- the segCount+1 joints at which the segments meet extraPoints: LIST OF Point, outline: Outline, -- the parent outline of this trajectory, boundBox: BoundBox, visibleJoints: BOOL _ TRUE, strokeJoint: Imager.StrokeJoint _ round, selected: SelectedObjectData ]; BoundBox: TYPE = REF BoundBoxObj; BoundBoxObj: TYPE = RECORD [loX, loY, hiX, hiY: REAL]; FenceHoleOpen: TYPE = {fence, hole, open}; TrajEnd: TYPE = {lo, hi}; Joint: TYPE = REF JointObj; JointObj: TYPE = RECORD [ point: Point, selected: SelectedObjectData, touchItem: TouchItem ]; JointPair: TYPE = RECORD [ start, end: NAT ]; Sequence: TYPE = REF SequenceObj; SequenceObj: TYPE = RECORD [ traj: Traj, all: BOOL _ FALSE, -- does this sequence represent the whole trajectory? If so parts = LIST[0, 0] and all = TRUE parts: LIST OF JointPair, selected: SelectedObjectData, boundBox: BoundBox ]; Segment: TYPE = REF SegmentObj; SegmentObj: TYPE = RECORD [ class: SegmentClass, looks: Rope.ROPE, -- may be used later for the style machinery strokeWidth: REAL _ 1.0, -- for now color: Imager.Color, -- for now lo, hi: Point, hiTan, loTan: Point _ [0,0], --[0,0] is the undefined value for the tangents. selected: SelectedObjectData, boundBox: BoundBox, touchItemList: LIST OF TouchItem, data: REF ANY ]; SegmentClass: TYPE = REF SegmentClassObj; SegmentClassObj: TYPE = RECORD [ type: ATOM, copyData: CopyDataProc, reverse: ReverseProc, transform: TransformProc, endpointMoved: EndPointMovedProc, maskStroke: MaskStrokeProc, maskStrokeTransform: MaskStrokeTransformProc, buildPath: BuildPathProc, buildPathTransform: BuildPathTransformProc, closestPoint: ClosestPointProc, closestPointAndTangent: ClosestPointAndTangentProc, boundBox: BoundBoxProc ]; CopyDataProc: TYPE = PROC [seg: Segment] RETURNS [data: REF ANY]; ReverseProc: TYPE = PROC [seg: Segment]; TransformProc: TYPE = PROC [transform: ImagerTransformation.Transformation, seg: Segment]; EndPointMovedProc: TYPE = PROC [seg: Segment, lo: BOOL, newPoint: Point]; MaskStrokeProc: TYPE = PROC [dc: Imager.Context, seg: Segment]; MaskStrokeTransformProc: TYPE = PROC [dc: Imager.Context, seg: Segment, transform: ImagerTransformation.Transformation, entire, lo, hi: BOOL]; BuildPathProc: TYPE = PROC [seg: Segment, lineTo: ImagerPath.LineToProc, curveTo: ImagerPath.CurveToProc, conicTo: ImagerPath.ConicToProc, arcTo: ImagerPath.ArcToProc]; BuildPathTransformProc: TYPE = PROC [seg: Segment, lineTo: ImagerPath.LineToProc, curveTo: ImagerPath.CurveToProc, conicTo: ImagerPath.ConicToProc, arcTo: ImagerPath.ArcToProc, transform: ImagerTransformation.Transformation, entire, lo, hi: BOOL]; ClosestPointProc: TYPE = PROC [seg: Segment, testPoint: Point, tolerance: REAL] RETURNS [point: Point, success: BOOL]; ClosestPointAndTangentProc: TYPE = PROC [seg: Segment, testPoint: Point, tolerance: REAL] RETURNS [point: Point, tangent: Vector, success: BOOL]; BoundBoxProc: TYPE = PROC [seg: Segment]; EntityGenerator: TYPE = REF EntityGeneratorObj; EntityGeneratorObj: TYPE = RECORD [ list: LIST OF REF ANY ]; TrajGenerator: TYPE = REF TrajGeneratorObj; TrajGeneratorObj: TYPE = RECORD [ list: LIST OF Traj ]; SequenceGenerator: TYPE = REF SequenceGeneratorObj; SequenceGeneratorObj: TYPE = RECORD [ list: LIST OF Sequence ]; SegmentGenerator: TYPE = REF SegmentGeneratorObj; SegmentGeneratorObj: TYPE = RECORD [ traj: Traj, toGo: NAT, index: NAT _ 0, nextParts: LIST OF JointPair ]; JointGenerator: TYPE = REF JointGeneratorObj; JointGeneratorObj: TYPE = RECORD [ traj: Traj, toGo: NAT, index: NAT, nextParts: LIST OF JointPair ]; BoundBoxGenerator: TYPE = REF BoundBoxGeneratorObj; BoundBoxGeneratorObj: TYPE = RECORD [ list: LIST OF BoundBox ]; TouchGroup: TYPE = REF TouchGroupObj; TouchGroupObj: TYPE = RECORD [ list: LIST OF TouchItem, point: Point, updated: BOOL _ FALSE ]; TouchingPartType: TYPE = {joint, segment}; TouchItem: TYPE = REF TouchItemObj; TouchItemObj: TYPE = RECORD [ group: TouchGroup, traj: Traj, touchingPartType: TouchingPartType, joint: Joint, seg: Segment, segPoint: Point ]; END. GGModelTypes.mesa Last edited by: Eric Bier on September 19, 1985 5:46:11 pm PDT Copyright c 1985 by Xerox Corporation. All rights reserved. Stone, August 5, 1985 2:13:37 pm PDT The joint size The maximum number of segments which are guaranteed to work. Very Basic Types Line equation of the form: y*cos(theta) - x*sin(theta) -d = 0, where theta is the angle which the line makes with the x axis and d is the distance from the line to the origin. Screen coordinates have the origin in the lower left hand corner of the viewer. The camera is always centered on the viewer. Hence, cameraScreen is the position of the center of the viewer. It changes whenever the viewer is resized. cameraWorld is the position of the camera in Gargoyle coordinates. I assume for now that Gargoyle coordinates have screen dots for units. If this is not true, then cameraWorld must include a scaling as well as a translation. Segments refer to joints (and other control points), and have drawing styles. Joints have a position and a continuity constraint The basic unit of a Trajectory is the Segment. We will experiment with "object style" segments to put allow the maximum flexibility for constructing pieces of trajectories. Copies the data in the "data" field of seg. This data is class-dependent. The "lo" end and "hi" end have switched roles. Update data structures as necessary. Apply the given transformation to all internal data of the segment. It is now in a new position, orientation, scaling, or skewing. Draw yourself into dc as a stroke. Assume that strokeWidth, and color are already set. Draw yourself into dc as a stroke. However, apply transform to your lower joint if lo = TRUE (and entire is FALSE), and apply transform to your higher joint if hi = TRUE (and entire is FALSE). Apply the transform to the entire trajectory if entire = TRUE. This is for rubberbanding. Assume that the Imager's current point is at your lower joint. Call the procedures given to draw yourself (moveTo is left out -- you shouldn't need it). BuildPathTransformProc is to BuildPathProc what MaskStrokeTransformProc is to MaskStrokeProc. This is for rubberbanding filled areas. Used for hit testing. Find the nearest point on seg to testPoint. If the nearest point is farther away than tolerance units, this procedure may opt to return success = FALSE. If a valid point is returned, then success = TRUE. Used for hit testing. Find the nearest point on seg to testPoint and the tangent vector (towards hi end of segment) at that point. If the nearest point is farther away than tolerance units, this procedure may opt to return success = FALSE. If a valid point and tangent are returned, then success = TRUE. Updates the geometric bounds for this segment (does not include control point size or stroke width). Generators Touching: Ê ±˜Ihead1šœ™J™>šœ Ïmœ1™™>Mšœp™pMšœžœŸ˜"MšœžœŸ˜(MšœžœŸ'˜0MšœžœŸ'˜0Mšœžœ˜ MšœžœŸ&˜1Mšœ˜—Mšœžœžœ ˜šœ žœžœ˜M˜Mšœž˜ M˜M˜—Mšœžœžœ˜šœžœžœ˜Mšœ˜Mšœžœ˜Mšœ˜M˜—Mšœžœžœ˜šœžœžœ˜M˜ M˜ —J™JšœŒÏuœa œ¡ œ1™ÏJ˜Jšœžœžœ ˜šœ žœžœ˜Jšœ œ ˜Jšœžœ˜ Jšœ œ˜J˜J˜—Jšœžœžœ ˜šœ žœžœ˜Jš œ žœžœžœžœžœŸ"˜BJ˜J˜—šœžœžœ˜#Jšœžœžœ˜Jšœžœžœ˜Jšœžœžœ˜Jšœžœž˜J˜J˜—Jšœ žœžœ ˜šœ žœžœ˜Jš œ žœžœžœžœŸ!˜Jšœ˜Jšœžœžœ˜Jšœ(˜(Jšœ˜Jšœ˜J˜—Jšœ žœžœ ˜!šœ žœžœžœ˜6J˜—Jšœžœ˜*Jšœ žœ ˜J˜Jšœžœžœ ˜šœ žœžœ˜Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜J˜—šœ žœžœ˜Jšœ ž˜J˜J˜—Jšœ žœžœ ˜!šœ žœžœ˜J˜ JšœžœžœŸ^˜qJšœžœžœ ˜Jšœ˜J˜J˜—J˜J˜J™®Jšœ žœžœ ˜šœ žœžœ˜J˜Jšœ žœŸ,˜>Jšœ žœ Ÿ ˜$JšœŸ ˜ J˜JšœŸ0˜MJšœ˜J˜Jšœžœžœ ˜!Jšœžœž˜ J˜J˜—Jšœžœžœ˜)šœžœžœ˜ Jšœžœ˜ J˜J˜J˜J˜!J˜J˜-J˜J˜+J˜J˜3J˜J˜J˜—š Ïn œžœžœžœžœžœ˜AJ™J—š¡ œžœžœ˜(J™T—š¡ œžœžœ@˜ZJ™ƒ—Jš¡œžœžœžœ˜Iš¡œžœžœ$˜?J™W—š¡œžœžœdžœ˜ŽJšœ™—š¡ œžœžœŽ˜¨J™™—š¡œžœžœÎžœ˜÷Jšœ†™†—š ¡œžœžœ-žœžœžœ˜vJšœä™ä—š ¡œžœžœ-žœžœ*žœ˜‘Jšœ²™²—š¡ œžœžœ˜)J™dJ™—J™ J™Jšœžœžœ˜/šœžœžœ˜#Jšœžœžœžœž˜J˜—J™Jšœžœžœ˜+šœžœžœ˜!Jšœžœžœ˜J˜J˜—Jšœžœžœ˜3šœžœžœ˜%Jšœžœžœ ˜J˜J˜—Jšœžœžœ˜1šœžœžœ˜$Jšœ ˜ Jšœžœ˜ Jšœžœ˜Jšœ žœžœ ˜J˜—J˜Jšœžœžœ˜-šœžœžœ˜"Jšœ ˜ Jšœžœ˜ Jšœžœ˜ Jšœ žœžœ ˜J˜J˜—Jšœžœžœ˜3šœžœžœ˜%Jšœžœžœ ˜J˜—J˜J™J™ J™Jšœ žœžœ˜%šœžœžœ˜Jšœžœžœ ˜J˜ Jšœ žœž˜J˜J˜—Jšœžœ˜*Jšœ žœžœ˜#šœžœžœ˜J˜J˜ J˜#Jšœ ˜ Jšœ ˜ J˜J˜—™J˜—Jšžœ˜—…—ü,Ë