506 int16_t array_origin;
508 int16_t projection_offset;
512 int16_t best_left_x = 0;
513 int16_t best_right_x = 0;
522 FPSEGPT_IT seg_it = seg_list;
524 end = (end - start) % pitch;
527 if ((pitch - 3) / 2 < pitch_error)
528 pitch_error = (pitch - 3) / 2;
531 for (left_edge = projection_left; projection->
pile_count (left_edge) == 0
532 && left_edge < projection_right; left_edge++);
533 for (right_edge = projection_right; projection->
pile_count (right_edge) == 0
534 && right_edge > left_edge; right_edge--);
535 array_origin = left_edge - pitch;
537 std::vector<FPCUTPT> cutpts(right_edge - left_edge + pitch * 2 + 1);
539 std::vector<bool> mins(pitch_error * 2 + 1);
540 for (x = array_origin; x < left_edge; x++)
542 cutpts[x - array_origin].setup(&cutpts[0], array_origin, projection,
543 zero_count, pitch, x, 0);
544 prev_zero = left_edge - 1;
545 for (offset = 0; offset <= pitch_error; offset++, x++)
547 cutpts[x - array_origin].setup(&cutpts[0], array_origin, projection,
548 zero_count, pitch, x, offset);
552 for (offset = -pitch_error, minindex = 0; offset < pitch_error;
553 offset++, minindex++)
554 mins[minindex] = projection->
local_min (x + offset);
555 next_zero = x + zero_offset + 1;
556 for (offset = next_zero - 1; offset >= x; offset--) {
557 if (projection->
pile_count (offset) <= zero_count) {
562 while (x < right_edge - pitch_error) {
563 mins[minindex] = projection->
local_min (x + pitch_error);
565 if (minindex > pitch_error * 2)
570 if (projection->
pile_count (x) <= zero_count) {
574 for (offset = 1; offset <= pitch_error; offset++)
575 if (projection->
pile_count (x + offset) <= zero_count
576 || projection->
pile_count (x - offset) <= zero_count)
579 if (offset > pitch_error) {
580 if (x - prev_zero > zero_offset && next_zero - x > zero_offset) {
581 for (offset = 0; offset <= pitch_error; offset++) {
582 test_index = minindex + pitch_error + offset;
583 if (test_index > pitch_error * 2)
584 test_index -= pitch_error * 2 + 1;
585 if (mins[test_index])
587 test_index = minindex + pitch_error - offset;
588 if (test_index > pitch_error * 2)
589 test_index -= pitch_error * 2 + 1;
590 if (mins[test_index])
594 if (offset > pitch_error) {
600 static_cast<int16_t>(projection->
pile_count (x) / projection_scale);
601 if (projection_offset > offset)
602 offset = projection_offset;
606 if ((start == 0 && end == 0)
608 || (x - projection_left - start) % pitch <= end)
609 cutpts[x - array_origin].assign(&cutpts[0], array_origin, x,
610 faking, mid_cut, offset, projection,
611 projection_scale, zero_count, pitch,
614 cutpts[x - array_origin].assign_cheap(&cutpts[0], array_origin, x,
615 faking, mid_cut, offset,
616 projection, projection_scale,
620 if (next_zero < x || next_zero == x + zero_offset)
621 next_zero = x + zero_offset + 1;
622 if (projection->
pile_count (x + zero_offset) <= zero_count)
623 next_zero = x + zero_offset;
626 best_fake = INT16_MAX;
627 best_cost = INT32_MAX;
628 best_count = INT16_MAX;
629 while (x < right_edge + pitch) {
630 offset = x < right_edge ? right_edge - x : 0;
631 cutpts[x - array_origin].assign(&cutpts[0], array_origin, x,
632 false,
false, offset, projection,
633 projection_scale, zero_count, pitch,
635 cutpts[x - array_origin].terminal =
true;
636 if (cutpts[x - array_origin].index () +
637 cutpts[x - array_origin].fake_count <= best_count + best_fake) {
638 if (cutpts[x - array_origin].fake_count < best_fake
639 || (cutpts[x - array_origin].fake_count == best_fake
640 && cutpts[x - array_origin].cost_function () < best_cost)) {
641 best_fake = cutpts[x - array_origin].fake_count;
642 best_cost = cutpts[x - array_origin].cost_function ();
645 best_count = cutpts[x - array_origin].index ();
647 else if (cutpts[x - array_origin].fake_count == best_fake
648 && x == best_right_x + 1
649 && cutpts[x - array_origin].cost_function () == best_cost) {
658 best_end = &cutpts[(best_left_x + best_right_x) / 2 - array_origin];
667 occupation_count = -1;
669 for (x = best_end->
position () - pitch + pitch_error;
670 x < best_end->
position () - pitch_error
672 if (x < best_end->position () - pitch_error)
675 segpt =
new FPSEGPT (best_end);
676 seg_it.add_before_then_move (segpt);
679 while (best_end !=
nullptr);
680 seg_it.move_to_last ();
681 mean_sum = seg_it.data ()->
sum ();