2011-01-31 3 views
5

Я никоим образом не исповедую себя гением, когда речь заходит о программировании, и моя текущая проблема меня озадачила.Расчет матрицы двумерного преобразования из исходной и результирующей 2D-матрицы

Я нашел этот вопрос Trying to derive a 2D transformation matrix using only the images, который, кажется, по крайней мере частично ответить на мой вопрос, но изображение, которое должно показать решение больше не доступны: S

Я работаю в C# и не использовать WPF, как никогда ни мой ввод или вывод должен отображаться графически.

В моей программе у меня есть 2 quadrilaterals, позволяет называть их входным и выходным четырехсторонним.

Входной квадрант имеет координаты (2,1), (2,3), (4,4), (3,1) слева внизу по часовой стрелке.

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

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

Я не слишком жарко на Матрицах, но я хочу узнать, если указано в правильном направлении.

Большое спасибо

Джош

+1

Я не думаю, что здесь слишком много участия в матрице; вы просите изоморфную функцию проецировать одну точку внутри четырехугольника на точку во втором четырехугольниках. Это не должно быть слишком сложно ... вам просто нужно выяснить, как точки в первом и втором многоугольниках сопоставляются друг с другом. –

+0

Вы также можете проверить http://math.stackexchange.com/questions/13404/mapping-irregular-quadrilateral-to-a-rectangle –

ответ

2

Быстрый google или хоп, пропустить и найти Google this. Я думаю, что это определенно решит вашу проблему.

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

Проводка алгоритма здесь для потомков:

Пусть p00, p10, p11 и p01 быть вершины первого четырехугольника , перечисленных в порядке против часовой стрелки.

Пусть q00, q10, q11 и q01 - это вершины второго четырехугольника, перечисленные в против часовой стрелки.

Определить Р10 = P10-P00, P11 = P11-P00, P01 = P01-P00, В10 = Q10-Q00, Q11 = Q11-Q00 и Q01 = Q01 -Q00.

Вычислите a и b так, чтобы Q11 = aQ10 + bQ01.

Это набор двух линейных уравнений с двумя неизвестными.

Аналогичным образом вычислите c и d так, чтобы P11 = cP10 + dP01.

Оказывается, что а> = 0, Ь> = 0, а + Ь> 1, с> = 0, д> = 0, и с + D> 1.

Любая точка р в четырехугольник может быть записан как p = (1-xy) p00 + xp10 + yp01 где x = 0, y = 0, (1 - d) x + c (y - 1) = 0 и d (x - 1) + (1 - c) y = 0.

Любая точка q в четырехугольника может быть записана как q = (1-uv) q00 + uq10 + vq01 где u = 0, v = 0, (1 - b) u + a (v -1) = 0 и b (u - 1) + (1 - a) v = 0.

Перспективное отображение, связывающее (u, v) с (x, y), равно u = m0x n0 + n1x + n2y и v = m1y n0 + n1x + n2y где m0 = ad (1 - c - d), m1 = bc (1 - c - d), n0 = cd (1 - a - b), n1 = d (a - c + bc - ad) и n2 = c (b - d - bc + ad).

Эффективно р-четырехугольник отображается на «стандарт» один, < (0, 0), (1, 0), (0, 1), (в, г)>

и д -quadrilateral отображается на < (0, 0), (1, 0), (0, 1), (a, b)>.

Отображение (x, y) to (u, v) связывает эти два.

Вы можете проверить, что

• (х, у) = (0, 0) отображается (и, v) = (0, 0)

• (х, у) = (1, 0) отображается в (U, V) = (1, 0)

• (х, у) = (0, 1) преобразуется в (U, V) = (0, 1)

• (х, у) = (в, г) отображается на (U, V) = (а, б)

Я дам другой ответ, который описывает, как я разрешу пример в комментариях - этот ответ становится слишком длинным.

+0

Это блестящий Кирк, большое спасибо за то, что поделились своими знаниями. –

+0

Отличный материал, Кирк. –

+0

Хорошо, ребята, я реализовал это в коде так же хорошо, как знаю, и, похоже, он не работает для меня. В настоящее время я использую пример приложения, в котором я вручную определяю все координаты и используя простые преобразования, я не получаю результаты, которые мне нужны. Если, например, я использую квадрат 10x10 от 0,0 для начального значения и квадрат 20x20 также от 0,0, когда я вводил координаты 5,5 как X и Y для начальной, я должен получить 10, 10 в результате, на данный момент я получаю 5,5. Когда я это делаю, значения A, B, C, D равны 1, когда я чувствую, что их не должно быть. Кто-нибудь знает, где я ошибся? –

2

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

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

Обратите внимание, что следующие лишь некоторые мысли. На самом деле я этого не делал. Я предполагаю, что у вас есть два набора точек: A и B, и вы точно знаете, что B является результатом применения некоторого преобразования к A.

Задача тривиальна, если единственным разрешенным преобразованием является перевод. В этом случае вы можете просто взять расстояние между нижними левыми точками. То есть, если исходными точками являются A[0] по A[3], а новые пункты: B[0] - B[3], то преобразование - это просто перевод X, Y: ((B[0].X - A[0].X), (B[0].Y - A[0].Y)).

Если масштабирование разрешено также, вы можете изобразить перевод, а затем масштабирование. Хотя для упрощения сначала нужно перевести на начало координат. Фактически, большая часть этого упрощается, если вы сначала переводите на начало координат.

Если вращение разрешено, все становится немного сложнее. Учитывая quadrilaterals, сначала вы должны повернуть вещь так, чтобы точки находились в той же ориентации, что и оригинал. Это потребует, чтобы вы вычислили расстояния между точками и использовали коэффициенты, чтобы выяснить, какая точка находится в нижнем левом углу. Затем поверните в нужное место.

Случай вращения, масштабирования и перевода должен быть прост.

Срезание немного сложнее. Вы должны уметь обнаружить срезание, но у меня нет хорошей идеи, как определить количество сдвига. Я думаю, однако, что если вы решите случай rotate/scale/translate, то решение сдвига станет по крайней мере немного более очевидным.

+0

Мне нравится первая половина вашего ответа. Мое чтение вопроса состояло в том, что второй набор координат мог бы быть * любым * набором координат; повернутые, масштабированные, срезанные все на столе. Не будет никакого «реального» вращения (более 90 градусов), потому что это только два четырехугольника, определяемые нижним левым углу. –

+0

@Kirk: Возможно, вы захотите проверить значение «четырехугольник». Это всего лишь 4-сторонняя форма. Таким образом, * может быть вещественным вращением. –

+0

Не совсем честно предположить, что я не знаю смысла четырехугольника, не так ли? Моя точка зрения заключалась в том, что для двух квадритералей, как определенных * исключительно * на 4 координатах, и где координаты упорядочены по часовой стрелке от «нижнего левого», как вы можете определить любое «вращение»? Если бы вы знали, какой угол из Q1 сопоставлен с каким углом в Q2, то вы можете иметь «поворот», но когда у вас нет этой информации, тогда поворот является нерелевантной концепцией. –

1

Чтобы решить примерный случай - перенос точки (5,5) из квадрата (0,0) - (10,10) на квадрат (0,0) - (20,20) - вы находитесь на правильный трек, но либо слишком рано или потерялся. Алгоритм не самый простой, но он вполне применим, как только вы поймете, куда идете.

При использовании «квадратов», перпендикулярных к x & y осей, тогда да a = b = c = d = 1.

Назовем точки вашего квада p1, p2, p3 и p4. Теперь рассмотрим a как описание отношения между p2 и p3 (относительно p1) и b как описание аналогичной взаимосвязи между p4 и p3 (относительно p1). Очень упрощенно, вы хотите работать a и b где

  • й координата p1 + a * length of side p1-p2 = координата х р3 и
  • координаты у Р1 + b * length of side p1-p4 = координата р3.

i.e., начиная с левого нижнего положения, сколько множества нижних краев необходимо добавить, чтобы перейти к координате x верхнего правого угла и аналогично для координаты y. Хотя это глоток, когда вы имеете дело с квадратом, правильный результат здесь определенно 1 и 1. Как только вы удаляетесь от перпендикулярных квадратов, это не так просто, но это легко визуализировать.

Когда вы решить эту проблему

  • p =(1-x-y)p00 + xp10 + yp01, где
  • x >= 0
  • y >= 0
  • (1 - d)x + c(y - 1) = 0
  • d(x - 1)+(1 - c)y = 0

, используя точку (5,5), вы получите значение x = 1/2, y = 1/2. Обратите внимание, что это не координаты x и y вашей точки. Вместо этого они представляют, где будет стоять ваша точка, если четырехугольник будет проецирован на квадрат размера (1,1). В этом случае они означают, что ваша точка расположена на 1/2 пути поперек (по горизонтали) и 1/2 пути вверх (по вертикали) вашего многоугольника - т. Е. Находится посередине.

Подключите свои значения a,b,c,d,x и y к большому уравнению (следуя ссылке, вместо того, чтобы читать ее здесь!), вы также получаете (u, v) = (1/2, 1/2), где u & v представляют ту же концепцию выше, но на втором квадрате. Это правильно, потому что ожидаемая точка должна находиться в середине второго многоугольника.

Наконец, когда вы подключите ваш u, v в уравнение

  • q =(1-u-v)q00 + uq10 + vq01

вы получите точку д = (10,10), которая является то, что вы ожидали.

Не знаю & не думал о решении одновременных уравнений в коде, я уверен, что есть способ, но это может быть не просто, но, к сожалению, мне придется оставить его вам. Я только что сделал это на листе бумаги, и все это получилось; однако моя математика немного ржаветь сделать что-то большее, чем более тривиальный пример.

+0

Привет Кирк, я думаю, что я заблудился и рано остановился из-за этого факта. Я увижу, как реализовать этот код позже сегодня, когда мой мозг работает немного лучше. –

+0

@Josh Я рекомендую вам сначала запустить его на бумаге, чтобы вы видели, как это работает; затем попробуйте выполнить его в коде. –

+0

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

Смежные вопросы