|
6 | 6 | #include <cmath>
|
7 | 7 | #include <iostream>
|
8 | 8 | #include <algorithm>
|
9 |
| -#include <optional> |
10 | 9 |
|
11 | 10 | #include "packingsolver/irregular/instance.hpp"
|
12 | 11 |
|
@@ -81,7 +80,29 @@ class GeneralizedTrapezoid
|
81 | 80 | */
|
82 | 81 | inline bool left_side_decreasing_not_vertical() const
|
83 | 82 | {
|
84 |
| - return right_side_increasing_not_vertical(); |
| 83 | + if (y_top() == y_bottom()) |
| 84 | + return false; |
| 85 | + return true; |
| 86 | + } |
| 87 | + |
| 88 | + /** |
| 89 | + * Return true if the left side is increasing and not vertical. |
| 90 | + */ |
| 91 | + inline bool left_side_increasing_not_vertical() const |
| 92 | + { |
| 93 | + if (y_top() == y_bottom()) |
| 94 | + return false; |
| 95 | + return true; |
| 96 | + } |
| 97 | + |
| 98 | + /** |
| 99 | + * Return true if the right side is decreasing and not vertical. |
| 100 | + */ |
| 101 | + inline bool right_side_decreasing_not_vertical() const |
| 102 | + { |
| 103 | + if (y_top() == y_bottom()) |
| 104 | + return false; |
| 105 | + return true; |
85 | 106 | }
|
86 | 107 |
|
87 | 108 | /** Return true if a_left == 0. */
|
@@ -150,19 +171,19 @@ class GeneralizedTrapezoid
|
150 | 171 | /** Get the height of the generalized trapezoid. */
|
151 | 172 | inline LengthDbl height() const { return y_top_ - y_bottom_; }
|
152 | 173 |
|
153 |
| - /** Get the bottom width of the generalized trapezoid. */ |
154 |
| - inline LengthDbl width_bottom() const { return x_bottom_right_ - x_bottom_left_; } |
155 |
| - |
156 |
| - /** Get the top width of the generalized trapezoid. */ |
| 174 | + /** Get the width of the top side of the trapezoid. */ |
157 | 175 | inline LengthDbl width_top() const { return x_top_right_ - x_top_left_; }
|
158 | 176 |
|
| 177 | + /** Get the width of the bottom side of the trapezoid. */ |
| 178 | + inline LengthDbl width_bottom() const { return x_bottom_right_ - x_bottom_left_; } |
| 179 | + |
159 | 180 | /** Get the greatest x of the generalized trapezoid. */
|
160 | 181 | inline LengthDbl x_max() const { return std::max(x_bottom_right_, x_top_right_); }
|
161 | 182 |
|
162 | 183 | /** Get the smallest x of the generalized trapezoid. */
|
163 | 184 | inline LengthDbl x_min() const { return std::min(x_bottom_left_, x_top_left_); }
|
164 | 185 |
|
165 |
| - /** Get the area of the generalized trapezoid. */ |
| 186 | + /** Get the area of the trapezoid. */ |
166 | 187 | inline AreaDbl area() const
|
167 | 188 | {
|
168 | 189 | return (width_top() + width_bottom()) / 2 * height();
|
@@ -360,13 +381,14 @@ class GeneralizedTrapezoid
|
360 | 381 | LengthDbl b_left = trapezoid.y_bottom() - a_left * trapezoid.x_bottom_left();
|
361 | 382 | double a2 = a - a_left;
|
362 | 383 | double b2 = b - b_left;
|
| 384 | + LengthDbl x, y; |
363 | 385 | if (trapezoid.a_left() == 0) {
|
364 | 386 | x = trapezoid.x_top_left();
|
365 | 387 | y = a * x + b;
|
366 | 388 | } else if (std::abs(a2) <= 1e-9) {
|
367 | 389 | return false;
|
368 | 390 | } else {
|
369 |
| - LengthDbl x = b2 / a2; |
| 391 | + x = b2 / a2; |
370 | 392 | y = a * x + b;
|
371 | 393 | }
|
372 | 394 | if (!strictly_lesser(y, trapezoid.y_bottom())
|
@@ -500,6 +522,53 @@ class GeneralizedTrapezoid
|
500 | 522 | return shape;
|
501 | 523 | }
|
502 | 524 |
|
| 525 | + /** |
| 526 | + * Check if the top of the trapezoid is covered |
| 527 | + */ |
| 528 | + inline bool top_covered() const |
| 529 | + { |
| 530 | + return false; // Default implementation, should be overridden if needed |
| 531 | + } |
| 532 | + |
| 533 | + /** |
| 534 | + * Extend the trapezoid to the left |
| 535 | + */ |
| 536 | + inline GeneralizedTrapezoid extend_left(LengthDbl extend_distance) const |
| 537 | + { |
| 538 | + return GeneralizedTrapezoid( |
| 539 | + y_bottom(), |
| 540 | + y_top(), |
| 541 | + x_bottom_left() - extend_distance, |
| 542 | + x_bottom_right(), |
| 543 | + x_top_left() - extend_distance, |
| 544 | + x_top_right()); |
| 545 | + } |
| 546 | + |
| 547 | + /** |
| 548 | + * Compute by how much the generalized trapezoid must be shifted to the top right |
| 549 | + */ |
| 550 | + inline LengthDbl compute_top_right_shift(const GeneralizedTrapezoid& trapezoid, double threshold = 0.0) const |
| 551 | + { |
| 552 | + // Default implementation, returns threshold value - should be properly implemented if needed |
| 553 | + return threshold; |
| 554 | + } |
| 555 | + |
| 556 | + /** Get the area above a given height */ |
| 557 | + inline AreaDbl area(LengthDbl height) const |
| 558 | + { |
| 559 | + if (height <= y_bottom()) |
| 560 | + return area(); |
| 561 | + if (height >= y_top()) |
| 562 | + return 0.0; |
| 563 | + |
| 564 | + // Calculate partial area |
| 565 | + LengthDbl partial_height = y_top() - height; |
| 566 | + LengthDbl width_at_height = x_right(height) - x_left(height); |
| 567 | + LengthDbl width_at_top = width_top(); |
| 568 | + |
| 569 | + return partial_height * (width_at_height + width_at_top) / 2.0; |
| 570 | + } |
| 571 | + |
503 | 572 | private:
|
504 | 573 |
|
505 | 574 | /** Y-coordinate of the bottom side. */
|
|
0 commit comments