Pattern lastNormalized = null;
Set<IPoint> shiftsOfEqualSegments = new HashSet<IPoint>();
for (Pattern ptn : patterns) {
Pattern normalized;
List<Pattern> minkowskiIncrement;
IPoint rectEndOrStart;
if (!isRectangularOrVerySmall(ptn)) {
// surely not a segment: avoiding slow calls of coordMin, coordMax, shift methods
// and providing a correct, non-shifted pattern for the quick algorithm
rectEndOrStart = IPoint.origin(ptn.dimCount());
normalized = ptn;
minkowskiIncrement = null;
} else {
Point preciseRectEndOrStart = negativeSegments ? ptn.coordMax() : ptn.coordMin();
assert preciseRectEndOrStart.isInteger();
// - this method is called only in union-decomposition mode,
// which is not used for non-integer or (N+1)-dimensional patterns
rectEndOrStart = preciseRectEndOrStart.toRoundedPoint();
normalized = ptn.shift(rectEndOrStart.symmetric().toPoint());
// normalized segment has origin at the left or right end:
// so minkowskiIncrement will consists of little positive / negative points
// that provide good (small) leftward / rightward shifts
minkowskiIncrement = lastNormalized == null ?
null :
minkowskiSubtractSegment(normalized, lastNormalized);
}
boolean equalSegments = minkowskiIncrement != null && minkowskiIncrement.size() == 1
&& minkowskiIncrement.get(0).isSurelyOriginPoint();
if (minkowskiIncrement == null || !equalSegments) {
// If minkowskiIncrement!=null, "normalized" and "lastNormalized" are segments along the same axis
// (equal segments if minkowskiIncrement.size()==1 && minkowskiIncrement.get(0).isOriginPoint().
// If minkowskiIncrement==null, then
// either "lastNormalized" is not a segment and should be saved in result (if !=null),
// or we should save the accumulated set of shifted copies of "lastNormalized" segment.
if (lastNormalized != null) {
result.add(new MinkowskiPair(
lastNormalized, // - main pattern, probably segment
shiftsOfEqualSegments,
minkowskiIncrement));
shiftsOfEqualSegments.clear();
}
}
shiftsOfEqualSegments.add(rectEndOrStart);
lastNormalized = normalized;
}
if (lastNormalized != null) {
result.add(new MinkowskiPair(
lastNormalized,
shiftsOfEqualSegments,
null));
}
for (int k = 0, n = result.size(); k < n; k++) {
MinkowskiPair pair = result.get(k);
List<Pattern> incrementFromPrevious = k == 0 ? null : result.get(k - 1).incrementToNext;
if (incrementFromPrevious == null && pair.incrementToNext == null) {
// isolated pattern, in particular, not a segment
if (pair.shifts.pointCount() == 1) {
// so, there is no sense to store the shift and the basic pattern separately
IPoint shift = pair.shifts.roundedPoints().iterator().next();
if (!shift.isOrigin()) {
pair = new MinkowskiPair(
pair.main.shift(shift.toPoint()),
Collections.singleton(IPoint.origin(shift.coordCount())),
null);
}
}
}
pair.incrementFromPrevious = incrementFromPrevious;