Существует очень широкий спектр возможных ответов, начиная от «Он делает то, что говорит 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);
В результате прямоугольник будет обращено, то есть
- Первый, масштабированный в 2 раза по оси x и y
- затем повернулся на 45 градусов
Таким образом, результатом будет больший поворотный прямоугольник.
Если бы вы применили операции, как этот
g.transform(scalingByFactor2);
g.transform(rotationBy45degrees);
, то прямоугольник будет выглядеть как большой, алмазоподобный-образный объект.
Редактировать в ответ на комментарии:
Причина, почему объекты, как представляется, отличается тем, что преобразования применяются независимо друг от друга. То есть они применяются к объектам, которые уже могут быть преобразованы другими преобразованиями. Я думаю, что пример прямоугольника (или квадрата) может быть достаточно интуитивным здесь:
Это в основном так же, как в обычной живописи или рисования программ, где применяются одно преобразование к объекту, а затем другой, и порядок преобразований влияет на результат.
Там были некоторые предположения о разнице между transform
и методом setTransform
. И как MadProgrammer наконец указал:
Метод transform
объединяет текущее преобразование графического объекта с новым (то есть: он умножает матрицы). Вы можете использовать его для «составления» нескольких преобразований, как показано примерами вращения и масштабирования выше.
В отличие от этого, метод Graphics2D#setTransform
служит совершенно другой цели, а документация содержит соответствующее предупреждение:
ВНИМАНИЕ: Этот метод должен никогда использоваться, чтобы применить новые преобразования координат сверху из существующего преобразования
Он должен быть использован только для восстановления оригинала преобразование графики, после последовательности transform
вызовов, как показано в примере JavaDoc.
Перейдите по адресу http://www.oracle.com/technetwork/java/javase/downloads/ и загрузите «Демо-версии и образцы JDK». После его распаковки запустите файл .jar в каталоге 'demo/jfc/Java2D'. Он имеет обширную демонстрацию преобразований (среди прочего) с полным исходным кодом. – VGR
@VGR Спасибо, я посмотрю. Но все равно будет здорово, если кто-то сможет ответить на мой вопрос. Это также принесет пользу всем будущим пользователям. – user3437460
Операции перевода, масштабирования, сдвига и поворота - все удобные методы, которые изменяют преобразование. – VGR