Когда вы вычисляете новые измерения, вы выполняете вычисление с плавающей запятой и затем округляете до ближайшего целого числа:
int widthNew = round(width * factor);
(Вам не нужны приведения: factor
- это float
и результат умножения целого числа на float
также является float
; widthNew
является целым числом, поэтому результат float
должен быть преобразован в целое число.)
Потому что при округлении ваш эффективный коэффициент масштабирования (назовем его factor_eff
) может отличаться от номинального factor
:
float factor_eff = (float) widthNew / width;
В вашем случае:
factor == 1.025656;
width == 4;
widthNew == round(1.025656 * 4) == round(4.102624) == 4;
factor_eff = 4.0 / 4 == 1.0;
Но вы делаете свое вычисления индекса со старым коэффициентом:
int zNew = floor(z / factor);
(Опять же, вам не нужен приведение.) Для ваших четырех z индексов это даст:
z == 0; zNew == floor(0 / 1.025656) == floor(0.0) == 0; // ok
z == 1; zNew == floor(1 / 1.025656) ~~ floor(0.9749858) == 0; // ! should be 1
z == 2; zNew == floor(2 / 1.025656) ~~ floor(1.9499715) == 1; // ! should be 2
z == 3; zNew == floor(3 / 1.025656) ~~ floor(2.9249573) == 2; // ! should be 3
Вы можете исправить коэффициент с плавающей точкой, но я думаю, что лучше (и быстрее) вычислить ваши новые индексы с целочисленным арифметическим c:
int zNew = z * width / widthNew;
int yNew = y * height / heightNew;
Сначала убедитесь, что вы выполняете умножение. Этот метод должен быть безопасным для размеров до 46 000.