<> <> <> <> <> DIRECTORY ImagerTransformation, Pipal, PipalInt, PipalReal; PipalRealInline: CEDAR DEFINITIONS IMPORTS ImagerTransformation = BEGIN <> Number: TYPE = PipalReal.Number; Vector: TYPE = PipalReal.Vector; Position: TYPE = PipalReal.Position; Size: TYPE = PipalReal.Size; Interval: TYPE = PipalReal.Interval; Rectangle: TYPE = PipalReal.Rectangle; Transformation: TYPE = PipalReal.Transformation; <> <> Add: PROC [v1, v2: Vector] RETURNS [Vector] = INLINE { RETURN [[v1.x+v2.x, v1.y+v2.y]] }; <<>> Sub: PROC [v1, v2: Vector] RETURNS [Vector] = INLINE { RETURN [[v1.x-v2.x, v1.y-v2.y]] }; <<>> Min: PROC [v1, v2: Vector] RETURNS [Vector] = INLINE { RETURN [[MIN [v1.x, v2.x], MIN [v1.y, v2.y]]] }; <<>> Max: PROC [v1, v2: Vector] RETURNS [Vector] = INLINE { RETURN [[MAX [v1.x, v2.x], MAX [v1.y, v2.y]]] }; <<>> Neg: PROC [v: Vector] RETURNS [Vector] = INLINE { RETURN [[-v.x, -v.y]] }; <<>> <> IsDegeneratedSize: PROC [s: Size] RETURNS [BOOL] = INLINE { RETURN [s.x<0 OR s.y<0] }; <<>> IsEmptySize: PROC [s: Size] RETURNS [BOOL] = INLINE { RETURN [s.x<=0 OR s.y<=0] }; <<>> <> IntersectionIntervals: PROC [i1, i2: Interval] RETURNS [interv: Interval] = INLINE {interv.base _ MAX [i1.base, i2.base]; interv.size _ MIN [i1.base+i1.size, i2.base+i2.size] - interv.base }; UnionIntervals: PROC [i1, i2: Interval] RETURNS [interv: Interval] = INLINE {interv.base _ MIN [i1.base, i2.base]; interv.size _ MAX [i1.base+i1.size, i2.base+i2.size] - interv.base }; DoIntervalsIntersect: PROC [i1, i2: Interval] RETURNS [BOOL] = INLINE { RETURN [i1.base<=i2.base+i2.size AND i2.base<=i1.base+i1.size] }; IsInsideInterval: PROC [container, candidate: Interval] RETURNS [BOOL] = INLINE { delta: Number _ candidate.base - container.base; RETURN [delta>=0 AND delta+candidate.size<=container.size] }; IsInsideIntervalNumber: PROC [container: Interval, candidate: Number] RETURNS [BOOL] = INLINE { delta: Number _ candidate - container.base; RETURN [delta>=0 AND delta<=container.size] }; <> <> Translate: PROC [r: Rectangle, v: Vector] RETURNS [Rectangle] = INLINE { RETURN [[PipalRealInline.Add[r.base, v], r.size]] }; <<>> <> IsDegeneratedRectangle: PROC [r: Rectangle] RETURNS [BOOL] = INLINE { RETURN [IsDegeneratedSize[r.size]] }; IsEmptyRectangle: PROC [r: Rectangle] RETURNS [BOOL] = INLINE { RETURN [PipalRealInline.IsEmptySize[r.size]] }; DoRectanglesIntersect: PROC [r1, r2: Rectangle] RETURNS [BOOL] = INLINE {RETURN [ PipalRealInline.DoIntervalsIntersect[[r1.base.x, r1.size.x], [r2.base.x, r2.size.x]] AND PipalRealInline.DoIntervalsIntersect[[r1.base.y, r1.size.y], [r2.base.y, r2.size.y]]] }; IsInsideRectangle: PROC [container, candidate: Rectangle] RETURNS [BOOL] = INLINE {RETURN [ PipalRealInline.IsInsideInterval[[container.base.x, container.size.x], [candidate.base.x, candidate.size.x]] AND PipalRealInline.IsInsideInterval[[container.base.y, container.size.y], [candidate.base.y, candidate.size.y]]] }; <<>> IsInsidePoint: PROC [container: Rectangle, candidate: Position] RETURNS [BOOL] = INLINE {RETURN [ PipalRealInline.IsInsideIntervalNumber[[container.base.x, container.size.x], candidate.x] AND PipalRealInline.IsInsideIntervalNumber[[container.base.y, container.size.y], candidate.y]] }; <> Extremity: PROC [r: Rectangle] RETURNS [Position] = INLINE { RETURN [[r.base.x + r.size.x, r.base.y + r.size.y]] }; <> IntToRealVector: PROC [v: PipalInt.Vector] RETURNS [Vector] = INLINE {RETURN [[v.x, v.y]]}; IntToRealRectangle: PROC [r: PipalInt.Rectangle] RETURNS [Rectangle] = INLINE {RETURN [[PipalRealInline.IntToRealVector[r.base], PipalRealInline.IntToRealVector[r.size]]]}; IntToRealTransformation: PROC [t: PipalInt.Transformation] RETURNS [Transformation] = INLINE {RETURN [SELECT t.orientation FROM identity => ImagerTransformation.Create[1, 0, t.translation.x, 0, 1, t.translation.y], mirrorX => ImagerTransformation.Create[-1, 0, t.translation.x, 0, 1, t.translation.y], rotate90 => ImagerTransformation.Create[0, -1, t.translation.x, 1, 0, t.translation.y], rotate90X => ImagerTransformation.Create[0, 1, t.translation.x, 1, 0, t.translation.y], rotate180 => ImagerTransformation.Create[-1, 0, t.translation.x, 0, -1, t.translation.y], rotate180X => ImagerTransformation.Create[1, 0, t.translation.x, 0, -1, t.translation.y], rotate270 => ImagerTransformation.Create[0, 1, t.translation.x, -1, 0, t.translation.y], rotate270X => ImagerTransformation.Create[0, -1, t.translation.x, -1, 0, t.translation.y], ENDCASE => ERROR ]}; END. <<>>