Помогите понять эти уравнения? - PullRequest
0 голосов
/ 18 июля 2010

Я задал вопрос о би линейных преобразованиях и получил этот ответ:

На той самой странице, которую вы разместили, есть ссылка на источник код. Я объясню билинейное преобразование в

http://www.antigrain.com/__code/include/agg_trans_bilinear.h.html

Идея состоит в том, чтобы найти преобразование формы:

output_x = a * input_x + b * input_x * input_y + c * input_y + d
output_y = e * input_x + f * input_x * input_y + g * input_y + h

Термин "билинейный" происходит от того, что каждое из этих уравнений является линейным в любой из входных координат самостоятельно. Мы хотим решить для правильные значения a, b, c и d. Скажем, у вас есть ссылка прямоугольник r1, r2, r3, r4, который вы хотите отобразить на (0,0), (1,0), (0,1), (1,1) (или некоторая система координат изображения).

Для a, b, c, d:

0 = a * r1_x + b * r1_x * r1_y + c * r1_y + d
1 = a * r2_x + b * r2_x * r2_y + c * r2_y + d
0 = a * r3_x + b * r3_x * r3_y + c * r3_y + d
1 = a * r4_x + b * r4_x * r4_y + c * r4_y + d

Для e, f, g, h:

0 = e * r1_x + f * r1_x * r1_y + g * r1_y + h
0 = e * r2_x + f * r2_x * r2_y + g * r2_y + h
1 = e * r3_x + f * r3_x * r3_y + g * r3_y + h
1 = e * r4_x + f * r4_x * r4_y + g * r4_y + h

Вы можете решить это так, как вам больше нравится. (Если вы знакомы с матричные обозначения, это два матричных уравнения, для которых матрица то же самое, и тогда вам просто нужно найти разложение LU один раз и решить два неизвестных вектора). Коэффициенты тогда применяется для сопоставления внутренней части прямоугольника с положением в прямоугольник.


Проблема в том, что у меня есть input_x и input_y, а также r1, r2, r3, r4, но я не уверен, как добиться output_x и output_y. Как мне решить такое уравнение? Я знаком только с решением уравнений с 2 ​​переменными.

Спасибо

Ответы [ 2 ]

5 голосов
/ 18 июля 2010

Это ужасное объяснение, которое вы нашли. Надеюсь, я смогу помочь вам понять, что происходит под капотом.

То, что вы хотите сделать, это отобразить прямоугольную область (один четырехугольник) в другой (произвольной формы) четырехугольник. Давайте начнем с более простого случая: линейная интерполяция (поиск значений, которые лежат вдоль линии )

Если у вас есть линия от a до b, то вы можете найти любую точку 'c' на этой линии, используя это уравнение:

c = ((1 - p) * a) + (p * b);

Это 'смешивает' (интерполирует) значения двух позиций вдоль прямой линии между ними (линейно). Если вы используете p = 0, тогда уравнение превращается в

c = (1 * a) + (0 * b)   = a

поэтому при p = 0 уравнение дает вам точку «a».

Когда p = 1, уравнение становится:

c = (0 * a) + (1 * b)   = b

поэтому при p = 1 уравнение дает вам точку «b».

При промежуточных значениях p вы получаете точки на линии между a и b. (таким образом, при p = 0,5 вы получаете точку точно посередине между a и b)

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

for (float p = 0.0; p <= 1.0; p += 0.1)    // copy 10 pixels from line 1 to line 2
    DrawPixelOnLine2(p, GetPixelFromLine1(p));

Эти два метода будут использовать линейную интерполяцию для вычисления правильных положений для чтения и рисования пикселей, например:

int ax = 0, ay = 100, bx = 50, by = 170;   // line a-b goes from (0,100) to (50,170)

int px = ((1-p) * ax) + (p * bx);          // calc the x and y values separately
int py = ((1-p) * ay) + (p * by);

(Обратите внимание, что мне нужно использовать вычисления дважды, чтобы сделать 2D-позицию. Я мог бы интерполировать в 3D, просто добавив тот же самый agaian вычисления для координат z / bz / pz)

Итак, теперь вы можете копировать точки с одной произвольной прямой на другую.

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

Чтобы выполнить приведенное выше отображение, мы просто выполняем вычисление линейной интерполяции в двух измерениях: сначала мы интерполируем вдоль дна и вдоль вершины, чтобы найти две конечные точки линии, которая проходит вертикально через середину прямоугольника. затем мы интерполируем вдоль этой вертикальной линии, чтобы найти конечную точку в середине прямоугольника.

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

В примере, который вы нашли, автор использует четыре точки для описания формы источника (a, b, c, d) и еще четыре точки для описания формы назначения (e, f, g, h) *

Кроме того, они сделали вычисления более эффективными, решая уравнения для заполнения матрицы преобразования, которую можно умножить на точки для выполнения процесса отображения. Однако эффект такой же, как я описал выше. Надеюсь, мое объяснение немного облегчит вам «просмотр» того, что делают уравнения.

0 голосов
/ 18 июля 2010

Если вы хотите отобразить прямоугольник на другой, вам понадобится простое линейное преобразование. Для отображения точки r в точку q у вас есть:

qx = a<em>rx + b</em>ry + c
qy = d<em>rx + e</em>ry + f

Есть 6 переменных, вам нужно 6 уравнений (3 балла). Чтобы отобразить прямоугольник r на прямоугольник q:

q1x = a*r1x + b*r1y + c
q1y = d*r1x + e*r1y + f
q2x = a*r2x + b*r2y + c
q2y = d*r2x + e*r2y + f
q3x = a*r3x + b*r3y + c
q3y = d*r3x + e*r3y + f

Сверху вам нужно решить 2 системы из 3 линейных уравнений с 3 переменными в каждой. У них будет ровно 1 решение, если точки различны и не коллинеарны (в случае прямоугольных углов это выполняется).

...