□ getScaleInstance (double sx, double sy) — изменяет масштаб по оси
□ getShareInstance (double shx, double shy) — преобразует каждую точку (x, y) в точку (x + shx * y, shy * x + y).
□ getTranslateInstance (double tx, double ty) — сдвигает каждую точку (x, y) в точку (x + tx, y + ty).
Метод createInverse () возвращает преобразование, обратное текущему преобразованию.
После создания преобразования его можно изменить методами:
setTransform(AffineTransform at);
setTransform(double a, double b, double c, double d, double e, double f); setToIdentity(); setToRotation(double angle);
setToRotation(double angle, double x, double y); setToRotation(double vx, double vy);
setToRotation(double vx, double vy, double x, double y); setToQuadrantRotation(int n);
setToQuadrantRotation(int n, double x, double y); setToScale(double sx, double sy); setToShare(double shx, double shy); setToTranslate(double tx, double ty);
сделав текущим преобразование, заданное одним из этих методов.
Преобразования, заданные методами:
concatenate(AffineTransform at); rotate(double angle);
rotate(double angle, double x, double y); rotate(double vx, double vy);
rotate(double vx, double vy, double x, double y); quadrantRotate(int n);
quadrantRotate(int n, double x, double y); scale(double sx, double sy); shear(double shx, double shy); translate(double tx, double ty);
выполняются перед текущим преобразованием, образуя композицию преобразований.
Преобразование, заданное методом preConcatenate(AffineTransform at), напротив, осуществляется после текущего преобразования.
Прочие методы класса AffineTransform производят преобразования различных фигур в пространстве пользователя.
Пора привести пример. Добавим в начало метода paint (), показанного в листинге 9.2, строку импорта
import java.awt.geom.*;
и четыре оператора, как записано в листинге 9.3.
// Начало листинга 9.2... public void paint(Graphics gr){
Graphics2D g = (Graphics2D)gr;
AffineTransform at =
AffineTransform.getRotateInstance(-Math.PI/4.0, 250.0, 150.0); at.concatenate(
new AffineTransform(0.5, 0.0, 0.0, 0.5, 100.0, 60.0)); g.setTransform(at);
Dimension d = getSize();
// Продолжение листинга 9.2
Метод paint () начинается с получения экземпляра g класса Graphics2D простым приведением аргумента gr к типу GraphicsiD. Затем. методом getRotateInstance () определяется поворот на 45° против часовой стрелки вокруг точки (250.0, 150.0). Это преобразование — экземпляр at класса AffineTransform. Метод concatenate (), выполняемый объектом at, добавляет к этому преобразованию сжатие в два раза по обеим осям координат и перенос начала координат в точку (100.0, 60.0). Наконец, композиция этих преобразований устанавливается как текущее преобразование объекта g методом setTrans form ().
Преобразование выполняется в следующем порядке. Сначала пространство пользователя сжимается в два раза вдоль обеих осей, затем начало координат пользователя — левый верхний угол — переносится в точку (100.0, 60.0) пространства графического устройства. Потом картинка поворачивается на угол 45° против часовой стрелки вокруг точки (250.0, 150.0).
Результат этих преобразований показан на рис. 9.3.
Рис. 9.3. Преобразование координат |
4. Напишите полную программу по листингу 9.3 и выполните ее несколько раз, меняя коэффициенты преобразований.
Рисование фигур средствами Java 2D
Характеристики пера для рисования фигур описаны в интерфейсе Stroke. В Java 2D есть пока только один класс, реализующий этот интерфейс, класс BasicStroke.
Класс
Конструкторы класса BasicStroke определяют характеристики пера. Основной конструктор,
BasicStroke(float width, int cap, int join, float miter, float[] dash, float dashBegin);
задает:
□ толщину пера width в пикселах;
□ оформление конца линии cap; это одна из констант:
• cap_round — закругленный конец линии;
• cap_square — квадратный конец линии;
• cap_butt — оформление отсутствует;
□ способ сопряжения линий j oin; это одна из констант:
• join_round — линии сопрягаются дугой окружности;
• join_bevel — линии сопрягаются отрезком прямой, перпендикулярным биссектрисе угла между линиями;
• join_miter — линии просто стыкуются;
□ расстояние между линиями miter, начиная с которого применяется сопряжение
join_miter;
□ длину штрихов и промежутков между штрихами — массив dash; элементы массива с четными индексами задают длину штриха в пикселах, элементы с нечетными индексами — длину промежутка; массив перебирается циклически;
□ индекс dashBegin, начиная с которого перебираются элементы массива dash. Остальные конструкторы задают некоторые характеристики по умолчанию:
□ BasicStroke(float width, int cap, int join, float miter) — сплошная линия;
□ BasicStroke (float width, int cap, int join) — сплошная линия с сопряжением JOIN_ROUND или JOIN_BEVEL; для сопряжения JOIN_MITER задается значение miter = 10. of;