Вращение и масштабирование Как сделать и то и другое и получить правильный результат?

У меня есть набор вызовов Java2D, которые рисуют векторы в графическом контексте. Я бы хотел, чтобы изображение увеличилось вдвое, а затем повернулось на 90 градусов.

Для этого я использую следующий код:

Graphics2D g2 = // ... get graphics 2d somehow ...
AffineTransform oldTransform = g2.getTransform();
AffineTransform newTransform = (AffineTransform)oldTransform.clone();
newTransform.concatenate(AffineTransform.getTranslateInstance(x1, x2));
newTransform.concatenate(AffineTransform.getScaleInstance((double)newW/(double)iconW, (double)newH/(double)iconH));
newTransform.concatenate(AffineTransform.getRotateInstance(Math.toRadians(rotationAngle), (double)iconW/2.0d, (double)iconH/2.0d));
// ... do my drawing ...

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

Есть лучший способ сделать это?


person jsight    schedule 25.03.2009    source источник


Ответы (3)


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

newTransform.concatenate(AffineTransform.getTranslateInstance(x1, x2));
newTransform.concatenate(AffineTransform.getRotateInstance(Math.toRadians(rotationAngle), (double)iconW/2.0d, (double)iconH/2.0d));
newTransform.concatenate(AffineTransform.getScaleInstance((double)newW/(double)iconW, (double)newH/(double)iconH));
person Eric Petroelje    schedule 25.03.2009
comment
Хорошо, это работает, но я этого не понимаю. Почему можно сначала применить перевод? Т.е., если translate будет первым, то оно произойдет первым. Но вращение происходит после масштабирования, даже если сначала применяется вращение? Я что-то не понимаю. - person jsight; 25.03.2009
comment
Трудно точно объяснить, почему перевод все еще будет работать правильно, но если вы посмотрите на базовую матричную математику, вы поймете, почему это имеет смысл. - person Eric Petroelje; 25.03.2009

Вращения всегда выполняются вокруг начала координат. Чтобы повернуться вокруг определенной точки, вы должны перевести точки.

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

person Ben S    schedule 25.03.2009
comment
Второй и третий аргументы getRotateInstance управляют преобразованием. Это была не та проблема. - person jsight; 25.03.2009

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

person MarkusQ    schedule 25.03.2009