amarao_san

Category:

Ну вот нельзя в математике мухлевать и всё тут

В предыдущих частях я для удобства согласился, что к «пикселу» относятся все точки, включая его границы. На самом деле это не так, и для консистентности пиксел должен включать в себя полуинтервал (т.е. одна граница открыта, вторая закрыта).

... Но срезал, ибо удобно.

Покусало. Где? При ресайзе.

Вот у нас есть простой алгоритм: есть старые пикселы, теперь у нас тот же кусок простраства порезан по новой сетке. Надо уже посчитанные точки перекинуть в соответствующие сетки (resampling). Итерируем по каждой старой точке, достаём все точки, для каждой точки известны её float-координаты, вычисляем позицию в пиксельной сетке.

Алгоритм:

let pixel_x = ((root.0 - self.window_start.0)/new_fixel_size_x).trunc() as usize;
let pixel_y = ((root.1 - self.window_start.1)/new_fixel_size_y).trunc() as usize;

Т.е. берём координату точки (для удобства рассказываю только для x, т.к. для y так же), вычитаем из неё начало окона, делим на размер нового пиксела, берём целую часть (отбрасываем дробную), считаем, что это и есть позиция x в массиве, если считать с нуля.

... И, разумеется, panic, потому что выход за пределы массива. Почему? Потому что...

Как только мы обе границы включили в пиксел, то самый правый пиксел у нас какой будет? Разумеется, line.len(), т.е. если у нас картинка 1000х1000 пикселов, то это будет 1000ый пиксел. Что и есть самая что ни на есть небанальная, но всё-таки off by one error, и выход за пределы массива.

Но, более того, эта бага касается всех пикселов. У всех правая граница будет попадать в следующий пиксел.

Потому что МАТЕМАТИКА. И что делать?

Любой линейный алгоритм приведёт к тому, что всё восстановится. Точки будут попадать в пиксле только для одной стороны пиксела.

Что делать? Проверять остаток от деления. Если он ноль, то мы на границе пиксела и точка принадлежит обоим пикселам. Так и писать «обоим». А если одного из пикселов нет (None), то и фиг с ним.

Буэ, а не математика. А знаете, что самое мерзкое? Надо обрабатывать аж три случая: вверх, вправо, и вверх-вправо.

Раст, конечно, при этом помогает как может...

match (frac_x, frac_y) {
                       (0.0, 0.0 ) => {},
                       (0.0, _) => {},
                       (_, 0.0) => {},
                       _ => {}
}

Error

default userpic

Your IP address will be recorded 

When you submit the form an invisible reCAPTCHA check will be performed.
You must follow the Privacy Policy and Google Terms of use.