Это похоже на линейное преобразование для меня. Мы это знаем, потому что любая строка в исходном графе также является строкой в преобразованном графе (это не всегда верно для демонстрации, которую вы дали, но будет верно, если вы будете следовать указаниям, которые вы указали в своем вопросе, и не допускать вогнутых вершин) , Я верю, что AS3 имеет встроенную поддержку матричных манипуляций преобразования. Если нет, вы можете реализовать их самостоятельно.
[ x' ] = [ a b ] x [ x ]
[ y' ] [ c d ] [ y ]
Это матрицы. Первый - это вектор (ваша конечная точка) и равен некоторой матрице 2x2, умноженной на вектор (ваша исходная точка)
Если вы не знакомы с умножением матрицы, это может быть упрощено:
x' = a*x + b*y
y' = c*x + b*y
Любое линейное преобразование может быть представлено такой матрицей a-b, c, и d. Выберите номера для каждого из них, и вы получите линейное преобразование. Итак, как вы находите значения a, b, c и d, которые дадут вам ваши?
Для четырех неизвестных вам нужны четыре уравнения. Если вы посмотрите на приведенные выше уравнения, вы увидите, что одна точка («вектор») и ее преобразование дадут вам два уравнения. Итак ... нам нужны два момента. Как вы увидите позже, будет полезно выбрать точки в невращаемой форме (m, 0) и (0, n) (т. Е. Один вдоль вашей оси x, а другой вдоль вашей оси y).
В вашем примере их легко найти! Это B и D (если A или C - ваше происхождение)!
Я буду использовать немного другое обозначение: «простые» для преобразованных версий точек.
B => B'
B_x => B'_x
B_y => B'_y
Если вы знаете, что раньше, и после того, как координаты B и D, вы можете найти преобразование матрицы A, B, C, D.
Настройка ваших уравнений:
B'_x = a * B_x + b * B_y
B'_y = c * B_x + d * B_y
D'_x = a * D_x + b * D_y
D'_y = c * D_x + d * D_y
Теперь, давайте скажем, что B ваша точка оси х, в форме (B_x, 0). Скажем, D - ваша точка оси y, в форме (0, D_y). Если это наоборот, переключите их. Здесь мы предполагаем, что ваше происхождение A = (0,0), как и в большинстве приложений Flash.
Настройка B_y = 0 и D_X = 0, получим:
B'_x = a * B_x + b * 0
B'_y = c * B_x + d * 0
D'_x = a * 0 + b * D_y
D'_y = c * 0 + d * D_y
Используя полномочия алгебры, мы находим:
a = B'_x/B_x
c = B'_y/B_x
b = D'_x/D_y
d = D'_y/D_y
Так, короче говоря:
Если вы знать исходные точки: (вершины на исходной оси x и y)
M = (M_x, 0)
N = (0 , N_x)
и их трансформированные/искаженные точки
M' = (M'_x, M'_y)
N' = (N'_x, N'_y)
(так что М => М 'и N => N')
затем вычислить и сохранить эти четыре переменные:
a = M'_x/M_x
b = N'_x/N_y
c = M'_y/M_x
d = N'_y/N_y
и наконец:
(x, y) => (a*x + b*y , c*x + d*y)
edit: Хорошо, я пробежал несколько из вашего преобразования с произвольным углом и понял, что я подпрыгнул до выводов, когда я предположил, что ваша трансформация была линейной. Уравнения выше будут линейными только при двух условиях:
- Вашей новая сетка формы некоторых повернута parallelogram (и вы оригинал квадрат, «нормальная» сетка)
- Положения ваших (0, 0) исходная точка не меняется.
Теперь я не уверен, какие степени свободы вы позволяете своим ручкам позиционировать, но, возможно, вы можете сдержать их, чтобы ваше сеточное пространство всегда следовало за формой повернутого параллелограмма.
Это может решить мою проблему. В ближайшее время я проверю его. Не могли бы вы разместить где-нибудь демо-приложение? – Carsten
http://rapidshare.com/files/403571153/WarpGrid.exe.html (10 загрузок разрешено) –
Это решает мою проблему. Большое спасибо! – Carsten