If a line is lower (true) or upper level (false) We have to know if it's lower or upper level to decide its color.
| 506 | /// We have to know if it's lower or upper level |
| 507 | /// to decide its color. |
| 508 | bool contours::is_lower_level(size_t line_index, size_t segment_begin, |
| 509 | size_t segment_end) { |
| 510 | // The parent non-hole is not always the lower or upper level. |
| 511 | // That depends on whether the function is increasing |
| 512 | // or decreasing on that region. |
| 513 | // lower level <-> higher values on the left |
| 514 | // upper level <-> higher values on the right |
| 515 | |
| 516 | // Find limits |
| 517 | double _xmax = xmax(); |
| 518 | double _xmin = xmin(); |
| 519 | double _ymax = ymax(); |
| 520 | double _ymin = ymin(); |
| 521 | |
| 522 | // Take two points - outside the border when possible |
| 523 | double x1 = filled_lines_[line_index].first[segment_begin]; |
| 524 | double x2 = filled_lines_[line_index].first[segment_begin + 1]; |
| 525 | double y1 = filled_lines_[line_index].second[segment_begin]; |
| 526 | double y2 = filled_lines_[line_index].second[segment_begin + 1]; |
| 527 | auto is_on_border = [&]() { |
| 528 | return (x1 <= _xmin || x1 >= _xmax || x2 <= _xmin || x2 >= _xmax || |
| 529 | y1 <= _ymin || y1 >= _ymax || y2 <= _ymin || y2 >= _ymax); |
| 530 | }; |
| 531 | size_t sample_begin = segment_begin; |
| 532 | while (is_on_border() && sample_begin < segment_end - 1) { |
| 533 | ++sample_begin; |
| 534 | x1 = filled_lines_[line_index].first[sample_begin]; |
| 535 | x2 = filled_lines_[line_index].first[sample_begin + 1]; |
| 536 | y1 = filled_lines_[line_index].second[sample_begin]; |
| 537 | y2 = filled_lines_[line_index].second[sample_begin + 1]; |
| 538 | } |
| 539 | double avg_x = 0.5 * (x1 + x2); |
| 540 | double avg_y = 0.5 * (y1 + y2); |
| 541 | bool x_is_increasing = x2 > x1; |
| 542 | bool y_is_increasing = y2 > y1; |
| 543 | |
| 544 | // look for the grid position of (x > x1, y > y1) - NE |
| 545 | auto it_y = |
| 546 | std::find_if(Y_data_.begin(), Y_data_.end(), |
| 547 | [&](const auto &y_row) { return y_row[0] > avg_y; }); |
| 548 | auto it_x = std::find_if( |
| 549 | X_data_[0].begin(), X_data_[0].end(), |
| 550 | [&](const double &x_row_value) { return x_row_value > avg_x; }); |
| 551 | size_t n_row = it_y - Y_data_.begin(); |
| 552 | size_t n_col = it_x - X_data_[0].begin(); |
| 553 | |
| 554 | // look at the left |
| 555 | // If x is increasing, the left is in the north |
| 556 | // - Do nothing because we are already at a position where y > avg_y |
| 557 | // If x is not increasing, the left is in the south |
| 558 | // - Try to reduce the n_row (our current grid position is NE) |
| 559 | if (!x_is_increasing && n_row > 0) { |
| 560 | n_row--; |
| 561 | } |
| 562 | // If y is increasing, the left is in the west |
| 563 | // - Try to reduce the n_col (our current grid position is NE) |
| 564 | // If y is not increasing, the left is in the east |
| 565 | // - Do nothing because we are already at a position where x > avg_x |