{
int minindex;
int test_index;
double best_cost;
double mean_sum;
FPSEGPT_IT seg_it = seg_list;
end = (end - start) % pitch;
if (pitch < 3)
pitch = 3;
if ((pitch - 3) / 2 < pitch_error)
pitch_error = (pitch - 3) / 2;
for (left_edge = projection_left; projection->
pile_count (left_edge) == 0
&& left_edge < projection_right; left_edge++);
for (right_edge = projection_right; projection->
pile_count (right_edge) == 0
&& right_edge > left_edge; right_edge--);
array_origin = left_edge - pitch;
for (x = array_origin; x < left_edge; x++)
cutpts[x - array_origin].setup (cutpts, array_origin, projection, zero_count, pitch, x, 0);
prev_zero = left_edge - 1;
for (offset = 0; offset <= pitch_error; offset++, x++)
cutpts[x - array_origin].setup (cutpts, array_origin, projection, zero_count, pitch, x, offset);
for (offset = -pitch_error, minindex = 0; offset < pitch_error;
offset++, minindex++)
mins[minindex] = projection->
local_min (x + offset);
next_zero = x + zero_offset + 1;
for (offset = next_zero - 1; offset >= x; offset--) {
if (projection->
pile_count (offset) <= zero_count) {
next_zero = offset;
break;
}
}
while (x < right_edge - pitch_error) {
mins[minindex] = projection->
local_min (x + pitch_error);
minindex++;
if (minindex > pitch_error * 2)
minindex = 0;
offset = 0;
prev_zero = x;
}
else {
for (offset = 1; offset <= pitch_error; offset++)
if (projection->
pile_count (x + offset) <= zero_count
|| projection->
pile_count (x - offset) <= zero_count)
break;
}
if (offset > pitch_error) {
if (x - prev_zero > zero_offset && next_zero - x > zero_offset) {
for (offset = 0; offset <= pitch_error; offset++) {
test_index = minindex + pitch_error + offset;
if (test_index > pitch_error * 2)
test_index -= pitch_error * 2 + 1;
if (mins[test_index])
break;
test_index = minindex + pitch_error - offset;
if (test_index > pitch_error * 2)
test_index -= pitch_error * 2 + 1;
if (mins[test_index])
break;
}
}
if (offset > pitch_error) {
}
else {
projection_offset =
if (projection_offset > offset)
offset = projection_offset;
}
}
if ((start == 0 && end == 0)
|| (x - projection_left - start) % pitch <= end)
cutpts[x - array_origin].
assign (cutpts, array_origin, x,
faking, mid_cut, offset, projection,
projection_scale, zero_count, pitch,
pitch_error);
else
cutpts[x - array_origin].
assign_cheap (cutpts, array_origin, x,
faking, mid_cut, offset,
projection, projection_scale,
zero_count, pitch,
pitch_error);
x++;
if (next_zero < x || next_zero == x + zero_offset)
next_zero = x + zero_offset + 1;
if (projection->
pile_count (x + zero_offset) <= zero_count)
next_zero = x + zero_offset;
}
while (x < right_edge + pitch) {
offset = x < right_edge ? right_edge - x : 0;
cutpts[x - array_origin].
assign (cutpts, array_origin, x,
projection_scale, zero_count, pitch,
pitch_error);
if (cutpts[x - array_origin].index () +
cutpts[x - array_origin].fake_count <= best_count + best_fake) {
if (cutpts[x - array_origin].fake_count < best_fake
|| (cutpts[x - array_origin].fake_count == best_fake
&& cutpts[x - array_origin].cost_function () < best_cost)) {
best_left_x = x;
best_right_x = x;
best_count = cutpts[x - array_origin].
index ();
}
else if (cutpts[x - array_origin].fake_count == best_fake
&& x == best_right_x + 1
&& cutpts[x - array_origin].cost_function () == best_cost) {
best_right_x = x;
}
}
x++;
}
best_end = &cutpts[(best_left_x + best_right_x) / 2 - array_origin];
occupation_count = -1;
do {
for (x = best_end->
position () - pitch + pitch_error;
if (x < best_end->position () - pitch_error)
occupation_count++;
seg_it.add_before_then_move (segpt);
}
while (best_end !=
NULL);
seg_it.move_to_last ();
mean_sum = seg_it.data ()->
sum ();
mean_sum = mean_sum * mean_sum / best_count;
if (seg_it.data ()->squares () - mean_sum < 0)
tprintf (
"Impossible sqsum=%g, mean=%g, total=%d\n",
seg_it.data ()->squares (), seg_it.data ()->sum (), best_count);
return seg_it.data ()->squares () - mean_sum;
}