<> <> <> <> <<>> DIRECTORY Imager, RatNums, EuclideanGraphs, ConvexEuclideanGraphs, ConvexCombiner, CombinePoly; CombinePolyImpl: CEDAR PROGRAM IMPORTS EuclideanGraphs, ConvexEuclideanGraphs, ConvexCombiner EXPORTS CombinePoly = BEGIN OPEN RN: RatNums, EG: EuclideanGraphs, CEG: ConvexEuclideanGraphs, CC: ConvexCombiner, CombinePoly; PointList: TYPE = LIST OF Point; -- Used to reverse order of points on Imager.Trajectory, and omit last (repeats first) point. PointGeneratorObj: PUBLIC TYPE = RECORD [ points: PointList ]; RegionGeneratorObj: PUBLIC TYPE = RECORD [ regions: CEG.RegionList ]; CreateDatabase: PUBLIC PROC [] RETURNS [dbid: DBID] ~ { EG.vertexIndex _ 1; dbid _ NIL; }; CreatePolygon: PUBLIC PROC [point1, point2: Point, clientData: REF] RETURNS [polyID: PolyID] ~ { ratPoint1: EG.Point _ EG.MakePointFromReals[point1.x, point1.y]; ratPoint2: EG.Point _ EG.MakePointFromReals[point2.x, point2.y]; entryPrior, entryNext: EG.Vertex _ NIL; [entryPrior, entryNext] _ CEG.AddVertexToPolygon [entryPrior, entryNext, ratPoint1, clientData]; [entryPrior, entryNext] _ CEG.AddVertexToPolygon [entryPrior, entryNext, ratPoint2, clientData]; RETURN[entryNext]; }; AddPointToPolygon: PUBLIC PROC [point: Point, polyid: PolyID] ~ { ratPoint: EG.Point _ EG.MakePointFromReals[point.x, point.y]; entryNext: EG.Vertex _ polyid; entryPrior: EG.Vertex _ CEG.SpecialPreviousOutlineVertex[entryNext]; thisToNext, nextToThis: EG.Adjacency; exitPrior: EG.Vertex; clientData: REF; IF polyid=NIL OR polyid.adjacentVertices=NIL THEN ERROR; -- AddPointToPolygon can only be called on a polygon that already has at least two vertices; [thisToNext, nextToThis] _ EG.FindAdjacency[entryPrior, entryNext]; clientData _ CEG.GetEdgeClientData[thisToNext]; [exitPrior, entryNext] _ CEG.AddVertexToPolygon[entryPrior, entryNext, ratPoint, clientData]; RETURN; }; PolygonIntoDatabase: PUBLIC PROC [polyID: PolyID, dbid: DBID, overlapHandler: RegionOverlapProc, glueHandler: RegionGlueProc] RETURNS[newDbid: DBID] ~ { startToEnd, endToStart: EG.Adjacency; inputClientData: REF; previous: EG.Vertex _ CEG.SpecialPreviousOutlineVertex[polyID]; [startToEnd, endToStart] _ EG.FindAdjacency[previous, polyID]; inputClientData _ CEG.GetEdgeClientData[startToEnd]; newDbid _ CC.Combiner[dbid, polyID, inputClientData, overlapHandler]; <> }; MaximalRegions: PUBLIC PROC [dbid: DBID, isA: IsAProc] RETURNS [regionGen: RegionGenerator] ~ { regionGen _ NEW[RegionGeneratorObj _ [regions: CEG.MaximalRegions[dbid, isA] ] ]; RETURN[regionGen]; }; TrajectoryToPointList: PROC [traj: Imager.Trajectory] RETURNS [list: PointList _ NIL] ~ { point: Point; WHILE traj.prev#NIL DO -- omit last point point.x _ traj.lp.x; point.y _ traj.lp.y; list _ CONS[point, list]; traj _ traj.prev; ENDLOOP; }; NextPoint: PUBLIC PROC [pointGen: PointGenerator] RETURNS [pointAndDone: PointAndDone] ~ { WHILE pointGen.points#NIL DO nextPoint: Point _ pointGen.points.first; pointGen.points _ pointGen.points.rest; RETURN[NEW[PointAndDoneRec _ [ point: nextPoint, done: FALSE ] ] ]; ENDLOOP; RETURN[NEW[PointAndDoneRec _ [ point: [0., 0.], done: TRUE ] ] ]; }; NextRegion: PUBLIC PROC [regionGen: RegionGenerator] RETURNS [outlineHolesDataAndDone: OutlineHolesDataAndDone] ~ { WHILE regionGen.regions#NIL DO nextRegion: CEG.Region _ regionGen.regions.first; regionGen.regions _ regionGen.regions.rest; RETURN[NEW[OutlineHolesDataAndDoneRec _ [ outline: NEW[PointGeneratorObj _ [points: TrajectoryToPointList[nextRegion.outline] ] ], holes: (IF nextRegion.holes=NIL THEN NIL ELSE NEW[RegionGeneratorObj _ [regions: nextRegion.holes] ] ), data: nextRegion.clientData, done: FALSE ] ] ]; ENDLOOP; RETURN[NEW[OutlineHolesDataAndDoneRec _ [ outline: NIL, holes: NIL, data: NIL, done: TRUE ] ] ]; }; END.