WPF: получение новых координат после поворота

Что касается этой игры программирования, которую я сейчас создаю.

alt text http://img12.imageshack.us/img12/2089/shapetransformationf.jpg

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

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

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

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

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

[ОБНОВЛЕНИЕ]

alt text http://img25.imageshack.us/img25/8676/shaperotationaltransfor.jpg

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

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

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

[EDIT]

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

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

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

Но теперь я нашел фрагмент кода (спасибо упоминанию 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/

Ответ 1

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

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) находится в правом верхнем квадранте. Для вас, где он находится в правом нижнем квадранте, тета будет угол поворота по часовой стрелке, а не вращение против часовой стрелки.)

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

Если вы знаете theta, теперь у вас есть достаточно информации для расчета новых координат. Если вы не знаете тета, вы можете решить для 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. могли полагать, что отношения 1,01 или менее будут возникать из округления округления до целых чисел, но это явно больше, чем ошибка округления)

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

Однако основной смысл математики за поворотами.

edit: aha, я не понимал, что они были оценками. (довольно близко к тому, чтобы быть реалистичным, хотя!)

Ответ 2

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

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

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

Ответ 3

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

Ответ 4

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

Ответ 5

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