2015-07-17 2 views
0

В классе Graphics2D от Java он имеет метод преобразования.Что делает метод преобразования Graphics2D?

public abstract void transform(AffineTransform Tx) 

Это описание в соответствии с документацией:

Составляет объект AffineTransform с преобразованием в этом Graphics2D по правилу последней указан-первых применяется. Если текущее преобразование - Cx, результатом композиции с Tx является новый Transform Cx '. Cx 'становится текущим преобразованием для этого Graphics2D. Преобразование точки p обновленным Transform Cx 'эквивалентно первому преобразованию p через Tx, а затем преобразованию результата в исходное Transform Cx. Другими словами, Cx '(p) = Cx (Tx (p)). При необходимости создается копия Tx, поэтому дальнейшие модификации Tx не влияют на рендеринг.

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

Так что мой вопрос:: Что делает трансформация именно так? Когда мы его используем?

Будет здорово, если кто-нибудь сможет объяснить это упрощенным образом.

+0

Перейдите по адресу http://www.oracle.com/technetwork/java/javase/downloads/ и загрузите «Демо-версии и образцы JDK». После его распаковки запустите файл .jar в каталоге 'demo/jfc/Java2D'. Он имеет обширную демонстрацию преобразований (среди прочего) с полным исходным кодом. – VGR

+0

@VGR Спасибо, я посмотрю. Но все равно будет здорово, если кто-то сможет ответить на мой вопрос. Это также принесет пользу всем будущим пользователям. – user3437460

+1

Операции перевода, масштабирования, сдвига и поворота - все удобные методы, которые изменяют преобразование. – VGR

ответ

1

Существует очень широкий спектр возможных ответов, начиная от «Он делает то, что говорит JavaDoc», чтобы полностью процитировать несколько глав the graphics programming bible. Я постараюсь дать промежуточный ответ. Это ближе к первому варианту, но некоторые ссылки приводят к информации, которая может быть немного более подробной, чем необходимо для понимания основных понятий.

Преобразование Graphics2D - это AffineTransform, в котором описывается, как объекты должны быть преобразованы до их нарисования. Такой AffineTransform представляет собой Matrix, который можно представить как нечто, которое изменяет положение всех точек нарисованных объектов. Например, это может быть rotation matrix, так что объекты будут повернуты до их рисования.

Пример: Когда вы в paintComponent методе некоторой JPanel, и получили Graphics2D, то вы можете выполнять операции рисования:

protected void paintComponent(Graphics gr) { 
    super.paintComponent(gr); 
    Graphics2D g = (Graphics2D)gr; 
    ... 

    // Draw a rectangle 
    g.drawRect(0,0,50,100); 
} 

Прямоугольник, который втягивается будет 50 пикселей в ширину и 100 пикселей.

Теперь вы можете применить новое преобразование к Graphics2D объекта перед нанесением:

protected void paintComponent(Graphics gr) { 
    super.paintComponent(gr); 
    Graphics2D g = (Graphics2D)gr; 
    ... 

    // Obtain an AffineTransform that describes a scaling 
    AffineTransform scalingTransform =  
     AffineTransform.getScaleInstance(2,2); 

    // Apply the transform to the graphics 
    g.transform(scalingTransform); 

    // Draw a rectangle. 
    g.drawRect(0,0,50,100); 
} 

Прямоугольник, который втягивается теперь будет 100 пикселей в ширину и 200 пикселей, из-за преобразования, что весы все с коэффициентом 2. Вы можете также использовали преобразование, которое выполняет поворот, с чем-то вроде

g.transform(AffineTransform.getRotateInstance(Math.toDegrees(45))); 

так, что прямоугольник будет повернут на 45 градусов.

Это в основном то, что делает метод transform, касающийся API и его эффекта.

Примечание стороны: Это правда, что rotate(...), translate(...), shear(...) и scale(...) методы Graphics2D просто удобные методы. Вместо

g.transform(AffineTransform.getRotateInstance(Math.toDegrees(45))); 

вы можете просто позвонить

g.rotate(Math.toDegrees(45)); 

для достижения того же эффекта. Метод transform очень общий, так как он может принимать произвольные матрицы преобразования, которые могли быть составлены в другом месте - например, в каком-либо другом методе, где объект Graphics2D просто недоступен.


Если вам интересно, что делает метод внутренне: Это на самом деле довольно просто. Он просто выполняет Matrix Multiplication. Он умножает AffineTransform, который содержится в Graphics2D с AffineTransform, который передается методу transform.

Умножение таких матриц преобразования можно представить как применение соответствующих преобразований, в обратном порядке:

AffineTransform scalingByFactor2 = 
    AffineTransform.getScaleInstance(2,2); 

AffineTransform rotationBy45degrees = 
    AffineTransform.getRotateInstance(Math.toDegrees(45)); 

g.transform(rotationBy45degrees); 
g.transform(scalingByFactor2); 
g.drawRect(0,0,50,100); 

В результате прямоугольник будет обращено, то есть

  1. Первый, масштабированный в 2 раза по оси x и y
  2. затем повернулся на 45 градусов

Таким образом, результатом будет больший поворотный прямоугольник.

Если бы вы применили операции, как этот

g.transform(scalingByFactor2); 
g.transform(rotationBy45degrees); 

, то прямоугольник будет выглядеть как большой, алмазоподобный-образный объект.

Редактировать в ответ на комментарии:

Причина, почему объекты, как представляется, отличается тем, что преобразования применяются независимо друг от друга. То есть они применяются к объектам, которые уже могут быть преобразованы другими преобразованиями. Я думаю, что пример прямоугольника (или квадрата) может быть достаточно интуитивным здесь:

TransformationOrder

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


Там были некоторые предположения о разнице между transform и методом setTransform. И как MadProgrammer наконец указал:

Метод transform объединяет текущее преобразование графического объекта с новым (то есть: он умножает матрицы). Вы можете использовать его для «составления» нескольких преобразований, как показано примерами вращения и масштабирования выше.

В отличие от этого, метод Graphics2D#setTransform служит совершенно другой цели, а документация содержит соответствующее предупреждение:

ВНИМАНИЕ: Этот метод должен никогда использоваться, чтобы применить новые преобразования координат сверху из существующего преобразования

Он должен быть использован только для восстановления оригинала преобразование графики, после последовательности transform вызовов, как показано в примере JavaDoc.

+0

Хорошо объяснил. Я приму свой ответ. Спасибо за подробное объяснение :) – user3437460

+0

Можете ли вы объяснить, почему другой порядок трансформации (т. Е. Вращать, а затем масштабировать по шкале, а затем вращать) порождать разные результаты? Надеюсь, вы можете ответить на этот вопрос :) – user3437460

+0

@ user3437460 Я добавил раздел, объясняющий это более подробно – Marco13

0

Этот метод используется для изменения способа отображения объекта Graphics2D перед его визуализацией в пространстве устройства, например, на экране или на листе бумаги. Например, вы можете использовать его для выполнения таких действий, как масштабирование, поворот и сдвиг изображения в ответ на пользователя, нажимая кнопки Scale/Rotate/Shear в вашем приложении.

Объект Graphics2D рождается с полем для отслеживания преобразования, которое представляет собой приближение «пространства устройства» (например, 1920 x 1080), в которое будет отображаться объект. Это преобразование вычисляется и применяется во время выполнения на объект таким образом, что он делает правильно в наличии экрана недвижимости (или страничный принтер или дисплей проектор и т.п.)

Применяя метод transform(AffineTransform Tx), вы сообщая системе, что вы хотите изменить, как будет выглядеть объект Graphics2D, когда он будет окончательно отображен; например, масштабирование или поворот объекта. Что говорит документация, так это то, что ваше новое преобразование будет применено к объекту Graphics2D до, его исходное преобразование применяется для установки его на дисплей, прикрепленный к устройству, на котором работает JVM; все это происходит до рендеринга.

+0

Итак, в каких конкретных сценариях мы используем 'transform()' и как 'transform()' влияет на текущий объект AffineTransform (поле g2d)? – user3437460

+0

Не существует метода Graphics2D.transform(). Если вы имеете в виду метод, о котором вы изначально спросили, вы должны использовать его (например) для масштабирования изображения в ответ на пользователя, нажимая кнопку «Масштаб» или автоматически масштабируя его вверх или вниз, чтобы подготовить его для печати. –

+0

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

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