<> <> <> <> <> <<>> DIRECTORY GGBasicTypes, GGModelTypes, GGInterfaceTypes, GGSegmentTypes, Imager; <<>> <> <> <> <<1) Selection. In this case we are not interested in the exact point which GGGravity but only in the name of the object deemed to be close. For selection, the environment consists only of visible objects in the Gargoyle scene.>> <<2) Caret placement. We may wish to place the caret on a visible object or on an interesting alignment line. In this case, we care both about the nearest object (e.g. so we can record a touching relationship) and the new point. The environment will consist both of visible objects and of special alignment lines.>> <<3) Intelligent dragging. For each vertex or edge of the objects being dragged, we can perform the gravity mapping, looking for directions in which to move the draggee. This will require arbitrating between multiple attractions. Otherwise, this is like caret placement.>> <<4) Interactive rotation. Some of the alignments of interest during interactive rotation are point alignments. For these GGGravity works as for intelligent dragging. Also, GGGravity can be used in reverse: The environment can be built from the moving object. The test points are present in the scene.>> <> <> <> <> <> <> <> <> <<>> GGGravity: CEDAR DEFINITIONS = BEGIN AlignmentObject: TYPE = GGModelTypes.AlignmentObject; Angle: TYPE = GGBasicTypes.Angle; BoundBox: TYPE = GGModelTypes.BoundBox; Caret: TYPE = GGInterfaceTypes.Caret; Circle: TYPE = GGBasicTypes.Circle; Edge: TYPE = GGBasicTypes.Edge; FeatureData: TYPE = GGInterfaceTypes.FeatureData; GGData: TYPE = GGInterfaceTypes.GGData; Line: TYPE = GGBasicTypes.Line; AlignBag: TYPE = GGInterfaceTypes.AlignBag; Outline: TYPE = GGModelTypes.Outline; Point: TYPE = GGBasicTypes.Point; Segment: TYPE = GGSegmentTypes.Segment; Slice: TYPE = GGModelTypes.Slice; SliceParts: TYPE = GGModelTypes.SliceParts; Traj: TYPE = GGModelTypes.Traj; TriggerBag: TYPE = GGInterfaceTypes.TriggerBag; Vector: TYPE = GGBasicTypes.Vector; <> FeatureFromOutline: PROC [outline: Outline, parts: SliceParts _ NIL] RETURNS [feature: FeatureData]; FeatureFromSlice: PROC [slice: Slice, parts: SliceParts _ NIL] RETURNS [feature: FeatureData]; FeatureFromAnchor: PROC [anchor: Caret] RETURNS [feature: FeatureData]; <<>> <> JointAddSlopeLine: PROC [degrees: REAL, direction: Vector, point: Point, objectBag: AlignBag] RETURNS [feature: FeatureData]; <> JointAddCircle: PROC [radius: REAL, point: Point, objectBag: AlignBag] RETURNS [feature: FeatureData]; <> SegmentAddTwoAngleLines: PROC [degrees: REAL, segNum: NAT, lo, hi: Point, objectBag: AlignBag] RETURNS [line1, line2: FeatureData]; <> SegmentAddDistanceLines: PROC [distance: REAL, segNum: NAT, lo, hi: Point, objectBag: AlignBag] RETURNS [line1, line2: FeatureData]; <> SegmentAddMidpoint: PROC [segNum: NAT, lo, hi: Point, objectBag: AlignBag] RETURNS [feature: FeatureData]; <> <<>> <> DrawFeatureList: PROC [dc: Imager.Context, alignObjects: LIST OF FeatureData, ggData: GGData]; DrawAlignBagRegardless: PROC [dc: Imager.Context, objectBag: AlignBag, ggData: GGData]; <> <<>> <> <<>> UniMap: PROC [testPoint: Point, criticalR: REAL, currentObjects: AlignBag, activeObjects: TriggerBag, ggData: GGData, intersections: BOOL] RETURNS [resultPoint: Point, feature: FeatureData, hitData: REF ANY]; <> <<>> <> <<>> <> <> <> <> <> <> <<];>> <> <> <> <<>> PointFilterProc: TYPE = PROC [Point] RETURNS [LIST OF AlignmentObject]; SegmentFilterProc: TYPE = PROC [lo, hi: Point] RETURNS [LIST OF AlignmentObject]; PointAddSlopeLine: PROC [point: Point] RETURNS [line: LIST OF AlignmentObject]; PointAddCircle: PROC [point: Point] RETURNS [circle: LIST OF AlignmentObject]; SegmentAddAngleLines: PROC [segNum: NAT, lo, hi: Point] RETURNS [lines: LIST OF AlignmentObject]; SegmentAddDistLines: PROC [segNum: NAT, lo, hi: Point] RETURNS [lines: LIST OF AlignmentObject]; NewGravityPool: PROC [] RETURNS [REF]; -- stored in GGData; temporary storage pool used by GGGravityImpl END.