ShapeList.java
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 package org.gecode.gist;
00024
00025 import java.util.*;
00026
00027
00028 public class ShapeList {
00029
00030
00031 private ArrayList shapes;
00032
00033
00034
00035 private int minimalSeparation;
00036
00037
00038 private boolean needsMerge;
00039
00040
00041 private Shape mergedShape;
00042
00043
00044 private ArrayList offsetList;
00045
00046
00047 public ShapeList(int theMinimalSeparation) {
00048 this.minimalSeparation = theMinimalSeparation;
00049 this.shapes = new ArrayList();
00050 this.needsMerge = false;
00051 }
00052
00053 public ShapeList(Collection theShapes, int theMinimalSeparation) {
00054 this.minimalSeparation = theMinimalSeparation;
00055 this.shapes = new ArrayList();
00056 Iterator theShapesIterator = theShapes.iterator();
00057 while (theShapesIterator.hasNext()) {
00058 Shape nextShape = (Shape) theShapesIterator.next();
00059 shapes.add(nextShape);
00060 }
00061 this.needsMerge = true;
00062 }
00063
00064
00065 public void add(Shape theShape) {
00066 shapes.add(theShape);
00067 needsMerge = true;
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077 private int getAlpha(Shape shape1, Shape shape2) {
00078 int alpha = minimalSeparation;
00079 int extentR = 0;
00080 int extentL = 0;
00081 Iterator extentIterator1 = shape1.iterator();
00082 Iterator extentIterator2 = shape2.iterator();
00083 while (extentIterator1.hasNext() && extentIterator2.hasNext()) {
00084 extentR += ((Extent) extentIterator1.next()).extentR;
00085 extentL += ((Extent) extentIterator2.next()).extentL;
00086 alpha = Math.max(alpha, extentR - extentL + minimalSeparation);
00087 }
00088 return alpha;
00089 }
00090
00091
00092
00093
00094 private static Shape merge(Shape shape1, Shape shape2, int alpha) {
00095 if (shape1.depth() == 0) {
00096 return shape2;
00097 } else if (shape2.depth() == 0) {
00098 return shape1;
00099 } else {
00100 Shape result = new Shape();
00101 Iterator extentIterator1 = shape1.iterator();
00102 Iterator extentIterator2 = shape2.iterator();
00103 Extent currentExtent1 = (Extent) extentIterator1.next();
00104 Extent currentExtent2 = (Extent) extentIterator2.next();
00105
00106
00107
00108 int topmostL = currentExtent1.extentL;
00109 int topmostR = currentExtent2.extentR;
00110 Extent topmostExtent = new Extent(topmostL, topmostR);
00111 topmostExtent.extend(0, alpha);
00112 result.add(topmostExtent);
00113
00114
00115
00116
00117
00118
00119 int backoffTo1 =
00120 currentExtent1.extentR - alpha - currentExtent2.extentR;
00121 int backoffTo2 =
00122 currentExtent2.extentL + alpha - currentExtent1.extentL;
00123 while (extentIterator1.hasNext() && extentIterator2.hasNext()) {
00124 currentExtent1 = (Extent) extentIterator1.next();
00125 currentExtent2 = (Extent) extentIterator2.next();
00126 int newExtentL = currentExtent1.extentL;
00127 int newExtentR = currentExtent2.extentR;
00128 Extent newExtent = new Extent(newExtentL, newExtentR);
00129 result.add(newExtent);
00130 backoffTo1 += currentExtent1.extentR - currentExtent2.extentR;
00131 backoffTo2 += currentExtent2.extentL - currentExtent1.extentL;
00132 }
00133
00134
00135
00136 if (extentIterator1.hasNext()) {
00137 currentExtent1 = (Extent) extentIterator1.next();
00138 int newExtentL = currentExtent1.extentL;
00139 int newExtentR = currentExtent1.extentR;
00140 Extent newExtent = new Extent(newExtentL, newExtentR);
00141 newExtent.extend(0, backoffTo1);
00142 result.add(newExtent);
00143 while (extentIterator1.hasNext()) {
00144 currentExtent1 = (Extent) extentIterator1.next();
00145 result.add(currentExtent1);
00146 }
00147 }
00148
00149
00150
00151 if (extentIterator2.hasNext()) {
00152 currentExtent2 = (Extent) extentIterator2.next();
00153 int newExtentL = currentExtent2.extentL;
00154 int newExtentR = currentExtent2.extentR;
00155 Extent newExtent = new Extent(newExtentL, newExtentR);
00156 newExtent.extend(backoffTo2, 0);
00157 result.add(newExtent);
00158 while (extentIterator2.hasNext()) {
00159 currentExtent2 = (Extent) extentIterator2.next();
00160 result.add(currentExtent2);
00161 }
00162 }
00163
00164 return result;
00165 }
00166 }
00167
00168
00169
00170
00171
00172
00173
00174 private void merge() {
00175 int numberOfShapes = shapes.size();
00176 if (numberOfShapes == 1) {
00177 mergedShape = (Shape) shapes.get(0);
00178 offsetList = new ArrayList();
00179 offsetList.add(new Integer(0));
00180 } else {
00181
00182
00183
00184
00185
00186
00187 int[] alphaL = new int[numberOfShapes];
00188 int[] alphaR = new int[numberOfShapes];
00189
00190
00191 int width = 0;
00192
00193 Shape currentShapeL = (Shape) shapes.get(0);
00194 Shape currentShapeR = (Shape) shapes.get(numberOfShapes - 1);
00195 for (int i = 1; i < numberOfShapes; i++) {
00196
00197
00198
00199
00200
00201
00202 Shape nextShapeL = (Shape) shapes.get(i);
00203 int nextAlphaL = getAlpha(currentShapeL, nextShapeL);
00204 currentShapeL = merge(currentShapeL, nextShapeL, nextAlphaL);
00205 alphaL[i] = nextAlphaL - width;
00206 width = nextAlphaL;
00207
00208
00209
00210 Shape nextShapeR = (Shape) shapes.get(numberOfShapes - 1 - i);
00211 int nextAlphaR = getAlpha(nextShapeR, currentShapeR);
00212 currentShapeR = merge(nextShapeR, currentShapeR, nextAlphaR);
00213 alphaR[numberOfShapes - i] = nextAlphaR;
00214 }
00215
00216
00217
00218 mergedShape = currentShapeR;
00219
00220
00221
00222
00223
00224 int halfWidth = width / 2;
00225 mergedShape.move(- halfWidth);
00226
00227
00228
00229
00230
00231
00232
00233 int offset = - halfWidth;
00234 offsetList = new ArrayList(numberOfShapes);
00235 offsetList.add(new Integer(offset));
00236 for (int i = 1; i < numberOfShapes; i++) {
00237 offset += (alphaL[i] + alphaR[i]) / 2;
00238 offsetList.add(new Integer(offset));
00239 }
00240 }
00241 needsMerge = false;
00242 }
00243
00244
00245 public Shape getMergedShape() {
00246 if (needsMerge) {
00247 merge();
00248 }
00249 return mergedShape;
00250 }
00251
00252
00253 public Iterator offsetIterator() {
00254 if (needsMerge) {
00255 merge();
00256 }
00257 return offsetList.iterator();
00258 }
00259
00260 }