/**
* Constructor given from and to ranges as [start1, end1, start2, end2,...].
- * If any end is equal to the next start, the ranges will be merged.
+ * If any end is equal to the next start, the ranges will be merged. There is
+ * no validation check that the ranges do not overlap each other.
*
* @param from
* contiguous regions as [start1, end1, start2, end2, ...]
this();
this.fromRatio = fromRatio;
this.toRatio = toRatio;
- fromLowest = from[0];
- fromHighest = from[1];
+ fromLowest = Integer.MAX_VALUE;
+ fromHighest = Integer.MIN_VALUE;
int added = 0;
for (int i = 0; i < from.length; i += 2)
{
- fromLowest = Math.min(fromLowest, from[i]);
- fromHighest = Math.max(fromHighest, from[i + 1]);
+ /*
+ * note lowest and highest values - bearing in mind the
+ * direction may be revesed
+ */
+ fromLowest = Math.min(fromLowest, Math.min(from[i], from[i + 1]));
+ fromHighest = Math.max(fromHighest, Math.max(from[i], from[i + 1]));
if (added > 0 && from[i] == fromShifts.get(added - 1)[1])
{
/*
}
}
- toLowest = to[0];
- toHighest = to[1];
+ toLowest = Integer.MAX_VALUE;
+ toHighest = Integer.MIN_VALUE;
added = 0;
for (int i = 0; i < to.length; i += 2)
{
- toLowest = Math.min(toLowest, to[i]);
- toHighest = Math.max(toHighest, to[i + 1]);
+ toLowest = Math.min(toLowest, Math.min(to[i], to[i + 1]));
+ toHighest = Math.max(toHighest, Math.max(to[i], to[i + 1]));
if (added > 0 && to[i] == toShifts.get(added - 1)[1])
{
toShifts.get(added - 1)[1] = to[i + 1];
}
/**
- * Constructor given ranges as lists of [start, end] positions
+ * Constructor given ranges as lists of [start, end] positions. There is no
+ * validation check that the ranges do not overlap each other.
*
* @param fromRange
* @param toRange
this.toRatio = toRatio;
fromLowest = Integer.MAX_VALUE;
- fromHighest = 0;
+ fromHighest = Integer.MIN_VALUE;
for (int[] range : fromRange)
{
- fromLowest = Math.min(fromLowest, range[0]);
- fromHighest = Math.max(fromHighest, range[1]);
+ fromLowest = Math.min(fromLowest, Math.min(range[0], range[1]));
+ fromHighest = Math.max(fromHighest, Math.max(range[0], range[1]));
}
toLowest = Integer.MAX_VALUE;
- toHighest = 0;
+ toHighest = Integer.MIN_VALUE;
for (int[] range : toRange)
{
- toLowest = Math.min(toLowest, range[0]);
- toHighest = Math.max(toHighest, range[1]);
+ toLowest = Math.min(toLowest, Math.min(range[0], range[1]));
+ toHighest = Math.max(toHighest, Math.max(range[0], range[1]));
}
}
sb.append(" ]");
return sb.toString();
}
+
+ /**
+ * Extend this map list by adding the given map's ranges. There is no
+ * validation check that the ranges do not overlap existing ranges (or each
+ * other), but contiguous ranges are merged.
+ *
+ * @param map
+ */
+ public void addMapList(MapList map)
+ {
+ this.fromLowest = Math.min(fromLowest, map.fromLowest);
+ this.toLowest = Math.min(toLowest, map.toLowest);
+ this.fromHighest = Math.max(fromHighest, map.fromHighest);
+ this.toHighest = Math.max(toHighest, map.toHighest);
+
+ for (int[] range : map.getFromRanges())
+ {
+ addRange(range, fromShifts);
+ }
+ for (int[] range : map.getToRanges())
+ {
+ addRange(range, toShifts);
+ }
+ }
+
+ public static void addRange(int[] range, List<int[]> addTo)
+ {
+ /*
+ * list is empty - add to it!
+ */
+ if (addTo.size() == 0)
+ {
+ addTo.add(range);
+ return;
+ }
+
+ int[] last = addTo.get(addTo.size() - 1);
+ boolean lastForward = last[1] >= last[0];
+ boolean newForward = range[1] >= range[0];
+
+ /*
+ * contiguous range in the same direction - just update endpoint
+ */
+ if (lastForward == newForward && last[1] == range[0])
+ {
+ last[1] = range[1];
+ return;
+ }
+
+ /*
+ * next range starts at +1 in forward sense - update endpoint
+ */
+ if (lastForward && newForward && range[0] == last[1] + 1)
+ {
+ last[1] = range[1];
+ return;
+ }
+
+ /*
+ * next range starts at -1 in reverse sense - update endpoint
+ */
+ if (!lastForward && !newForward && range[0] == last[1] - 1)
+ {
+ last[1] = range[1];
+ return;
+ }
+
+ /*
+ * just add the new range
+ */
+ addTo.add(range);
+ }
}