WPF: получение новых координат после поворота - PullRequest
13 голосов
/ 24 февраля 2009

Применительно к этой программируемой игре Я сейчас строю.

альтернативный текст http://img12.imageshack.us/img12/2089/shapetransformationf.jpg

Чтобы перевести Canvas в WPF, я использую две формы: TranslateTransform (чтобы переместить его) и RotateTransform (чтобы повернуть его) [ дочерние элементы того же TransformationGroup]

Я могу легко получить координаты левого верхнего x, y холста, когда он не повернут (или повернут на 90 градусов, поскольку он будет таким же), но проблема, с которой я сталкиваюсь, заключается в получении верхнего левого угла (и других 3 балла) координаты.

Это потому, что когда применяется RotateTransform, свойства TranslateTransform 's X и Y не изменяются (и, таким образом, все еще указывают, что верхний левый угол квадрата подобен пунктирному квадрату). (с картинки)

Холст вращается из своего центра, так что это его источник.

Итак как я могу получить "новые" координаты x и y 4 точек после поворота ?

[UPDATE]

альтернативный текст http://img25.imageshack.us/img25/8676/shaperotationaltransfor.jpg

Я нашел способ найти верхний левый координаты после поворота (как вы можете видеть из нового изображения), добавив OffsetX и OffsetY от поворота к начальным координатам X и Y .

Но теперь у меня проблемы с определением остальных координат (остальные 3).

С помощью этой повернутой формы, как мне определить координаты x и y оставшихся 3 углов?

[EDIT]

Точки на втором изображении НЕ ТОЧНЫЕ И ТОЧНЫЕ ТОЧКИ . Я высказал свои соображения с оценками в голове.

[ОБНОВЛЕНИЕ] Решение:

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

Но теперь я нашел фрагмент кода (благодаря упоминанию EugeneZ о TransformBounds), который делает именно то, что я хочу:

public Rect GetBounds(FrameworkElement of, FrameworkElement from)
{
    // Might throw an exception if of and from are not in the same visual tree
    GeneralTransform transform = of.TransformToVisual(from);

    return transform.TransformBounds(new Rect(0, 0, of.ActualWidth, of.ActualHeight));
} 

Ссылка: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/86350f19-6457-470e-bde9-66e8970f7059/

Ответы [ 5 ]

15 голосов
/ 26 февраля 2009

Если я правильно понял ваш вопрос:

given:
shape has corner (x1,y1), center (xc,yc)
rotated shape has corner (x1',y1') after being rotated about center

desired:
how to map any point of the shape (x,y) -> (x',y') by that same rotation

Вот соответствующие уравнения:

(x'-xc) = Kc*(x-xc) - Ks*(y-yc)
(y'-yc) = Ks*(x-xc) + Kc*(y-yc)

, где Kc=cos(theta) и Ks=sin(theta) и theta - угол поворота против часовой стрелки. (для проверки: если theta = 0, это оставляет координаты без изменений, в противном случае, если xc = yc = 0, он отображает (1,0) в (cos (theta), sin (theta)) и (0,1) в (- sin (theta), cos (theta)). Предостережение: это для систем координат, где (x, y) = (1,1) находится в верхнем правом квадранте. Для вашего, где он находится в нижнем правом квадранте, theta будет угол поворота по часовой стрелке, а не против часовой стрелки.)

Если вы знаете координаты вашего прямоугольника, выровненного по осям x-y, xc будет просто средним значением двух x-координат, а yc будет средним значением двух y-координат. (в вашей ситуации это xc = 75, yc = 85.)

Если вы знаете тэту, у вас теперь достаточно информации для расчета новых координат. Если вы не знаете тэту, вы можете решить для Kc, Ks. Вот соответствующие расчеты для вашего примера:

(62-75) = Kc*(50-75) - Ks*(50-85)
(40-85) = Ks*(50-75) + Kc*(50-85)

-13 = -25*Kc + 35*Ks = -25*Kc + 35*Ks
-45 = -25*Ks - 35*Kc = -35*Kc - 25*Ks

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

[-25 35;-35 -25]\[-13;-45]

, чтобы в этом случае получить Kc = 1,027, Ks = 0,3622, что НЕ имеет смысла (K 2 = Kc 2 + Ks 2 равно должен равняться 1 для чистого вращения, в данном случае это K = 1,089), поэтому это не чистый поворот вокруг центра прямоугольника, как показывает ваш рисунок. И при этом это не кажется чистым вращением о происхождении. Чтобы проверить, сравните расстояния от центра вращения до и после вращения, используя теорему Пифагора, d 2 = deltax 2 + deltay 2 . (для поворота около xc = 75, yc = 85 расстояние до 43.01, расстояние до 46.84, отношение равно K = 1.089; для поворота вокруг начала расстояние до 70.71, расстояние после 73.78, соотношение 1.043. I Можно полагать, что при округлении координат до целых чисел возникнут отношения 1,01 или менее, но это явно больше, чем ошибка округления)

Так что здесь есть некоторая недостающая информация. Как вы получили цифры (62,40)?

Это основная суть математики, стоящей за вращениями, однако.

редактировать: ага, я не понял, что это были оценки. (довольно близко к реалистичности!)

7 голосов
/ 23 апреля 2009

Я использую этот метод:

Point newPoint = rotateTransform.Transform(new Point(oldX, oldY));

где rotateTransform - это экземпляр, над которым я работаю и устанавливаю Угол ... и т. Д.

3 голосов
/ 27 февраля 2009

Посмотрите на метод GeneralTransform.TransformBounds ().

1 голос
/ 24 февраля 2009

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

1 голос
/ 24 февраля 2009

Я не уверен, но это то, что вы ищете - вращение точки в декартовой системе координат: ссылка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...