/// <summary> /// Vertical offset rectangles. /// </summary> protected void Vertical() { WrappedRectangles.Sort(YComparison); int i = 0; int n = WrappedRectangles.Count; while (i < n) { // y_i = y_{i+1} = ... = y_k int k = i; RectangleWrapper <TObject> u = WrappedRectangles[i]; for (int j = i; j < n; ++j) { ThrowIfCancellationRequested(); RectangleWrapper <TObject> v = WrappedRectangles[j]; if (NearEqual(u.CenterY, v.CenterY)) { u = v; k = j; } else { break; } } // delta = max(0, max{f.y(m,j)|i<=m<=k<j<n}) double delta = 0; for (int m = i; m <= k; ++m) { for (int j = k + 1; j < n; ++j) { ThrowIfCancellationRequested(); Vector force = Force2(WrappedRectangles[m].Rectangle, WrappedRectangles[j].Rectangle); if (force.Y > delta) { delta = force.Y; } } } for (int j = k + 1; j < n; ++j) { ThrowIfCancellationRequested(); RectangleWrapper <TObject> r = WrappedRectangles[j]; r.Rectangle.Offset(0, delta); } i = k + 1; } }
/// <summary> /// Horizontal offset rectangles. /// </summary> protected void Horizontal() { WrappedRectangles.Sort(XComparison); int i = 0; int n = WrappedRectangles.Count; while (i < n) { // x_i = x_{i+1} = ... = x_k int k = i; RectangleWrapper <TObject> u = WrappedRectangles[i]; for (int j = i + 1; j < n; ++j) { ThrowIfCancellationRequested(); RectangleWrapper <TObject> v = WrappedRectangles[j]; if (NearEqual(u.CenterX, v.CenterX)) { u = v; k = j; } else { break; } } // delta = max(0, max{f.x(m,j)|i<=m<=k<j<n}) double delta = 0; for (int m = i; m <= k; ++m) { for (int j = k + 1; j < n; ++j) { ThrowIfCancellationRequested(); Vector force = Force(WrappedRectangles[m].Rectangle, WrappedRectangles[j].Rectangle); if (force.X > delta) { delta = force.X; } } } for (int j = k + 1; j < n; ++j) { ThrowIfCancellationRequested(); RectangleWrapper <TObject> r = WrappedRectangles[j]; r.Rectangle.Offset(delta, 0); } i = k + 1; } }
protected int XComparison([NotNull] RectangleWrapper <TObject> r1, [NotNull] RectangleWrapper <TObject> r2) { double r1CenterX = r1.CenterX; double r2CenterX = r2.CenterX; if (r1CenterX < r2CenterX) { return(-1); } if (r1CenterX > r2CenterX) { return(1); } return(0); }
protected int YComparison( [NotNull] RectangleWrapper <TObject> r1, [NotNull] RectangleWrapper <TObject> r2) { double r1CenterY = r1.CenterY; double r2CenterY = r2.CenterY; if (r1CenterY < r2CenterY) { return(-1); } if (r1CenterY > r2CenterY) { return(1); } return(0); }
/// <inheritdoc cref="FSAAlgorithm{TObject,TParameters}.HorizontalImproved"/> protected new double HorizontalImproved() { WrappedRectangles.Sort(XComparison); int i = 0; int n = WrappedRectangles.Count; // Left side RectangleWrapper <TObject> leftMin = WrappedRectangles[0]; double sigma = 0; double x0 = leftMin.CenterX; var gamma = new double[WrappedRectangles.Count]; var x = new double[WrappedRectangles.Count]; while (i < n) { RectangleWrapper <TObject> u = WrappedRectangles[i]; // Rectangle with the same center than Rectangle[i] int k = i; for (int j = i + 1; j < n; ++j) { ThrowIfCancellationRequested(); RectangleWrapper <TObject> v = WrappedRectangles[j]; if (NearEqual(u.CenterX, v.CenterX)) { u = v; k = j; } else { break; } } double g = 0; for (int z = i + 1; z <= k; ++z) { ThrowIfCancellationRequested(); RectangleWrapper <TObject> v = WrappedRectangles[z]; v.Rectangle.X += (z - i) * 0.0001; } // For rectangles in [i, k], compute the left force if (u.CenterX > x0) { for (int m = i; m <= k; ++m) { double ggg = 0; for (int j = 0; j < i; ++j) { ThrowIfCancellationRequested(); Vector force = Force(WrappedRectangles[j].Rectangle, WrappedRectangles[m].Rectangle); ggg = Math.Max(force.X + gamma[j], ggg); } RectangleWrapper <TObject> v = WrappedRectangles[m]; double gg = v.Rectangle.Left + ggg < leftMin.Rectangle.Left ? sigma : ggg; g = Math.Max(g, gg); } } // Compute offset to elements in x // and redefine left side for (int m = i; m <= k; ++m) { ThrowIfCancellationRequested(); gamma[m] = g; RectangleWrapper <TObject> r = WrappedRectangles[m]; x[m] = r.Rectangle.Left + g; if (r.Rectangle.Left < leftMin.Rectangle.Left) { leftMin = r; } } // Compute the right force of rectangles in [i, k] and store the maximal one // delta = max(0, max{f.x(m,j)|i<=m<=k<j<n}) double delta = 0; for (int m = i; m <= k; ++m) { for (int j = k + 1; j < n; ++j) { ThrowIfCancellationRequested(); Vector force = Force(WrappedRectangles[m].Rectangle, WrappedRectangles[j].Rectangle); if (force.X > delta) { delta = force.X; } } } sigma += delta; i = k + 1; } double cost = 0; for (i = 0; i < n; ++i) { RectangleWrapper <TObject> r = WrappedRectangles[i]; double oldPos = r.Rectangle.Left; double newPos = x[i]; r.Rectangle.X = newPos; double diff = oldPos - newPos; cost += diff * diff; } return(cost); }
/// <summary> /// Vertical improvement. /// </summary> protected double VerticalImproved() { WrappedRectangles.Sort(YComparison); int i = 0; int n = WrappedRectangles.Count; RectangleWrapper <TObject> topMin = WrappedRectangles[0]; double sigma = 0; double y0 = topMin.CenterY; var gamma = new double[WrappedRectangles.Count]; var y = new double[WrappedRectangles.Count]; while (i < n) { RectangleWrapper <TObject> u = WrappedRectangles[i]; int k = i; for (int j = i + 1; j < n; ++j) { ThrowIfCancellationRequested(); RectangleWrapper <TObject> v = WrappedRectangles[j]; if (NearEqual(u.CenterY, v.CenterY)) { u = v; k = j; } else { break; } } double g = 0; if (u.CenterY > y0) { for (int m = i; m <= k; ++m) { double ggg = 0; for (int j = 0; j < i; ++j) { ThrowIfCancellationRequested(); Vector f = Force2(WrappedRectangles[j].Rectangle, WrappedRectangles[m].Rectangle); ggg = Math.Max(f.Y + gamma[j], ggg); } RectangleWrapper <TObject> v = WrappedRectangles[m]; double gg = v.Rectangle.Top + ggg < topMin.Rectangle.Top ? sigma : ggg; g = Math.Max(g, gg); } } for (int m = i; m <= k; ++m) { ThrowIfCancellationRequested(); gamma[m] = g; RectangleWrapper <TObject> r = WrappedRectangles[m]; y[m] = r.Rectangle.Top + g; if (r.Rectangle.Top < topMin.Rectangle.Top) { topMin = r; } } // delta = max(0, max{f.x(m,j)|i<=m<=k<j<n}) double delta = 0; for (int m = i; m <= k; ++m) { for (int j = k + 1; j < n; ++j) { ThrowIfCancellationRequested(); Vector force = Force(WrappedRectangles[m].Rectangle, WrappedRectangles[j].Rectangle); if (force.Y > delta) { delta = force.Y; } } } sigma += delta; i = k + 1; } double cost = 0; for (i = 0; i < n; ++i) { RectangleWrapper <TObject> r = WrappedRectangles[i]; double oldPos = r.Rectangle.Top; double newPos = y[i]; r.Rectangle.Y = newPos; double diff = oldPos - newPos; cost += diff * diff; } return(cost); }