□ Методы заполнения фигур описаны в интерфейсе Paint. Несколько классов реализуют этот интерфейс. Класс Color реализует его сплошной (solid) заливкой, класс GradientPaint — градиентным (gradient) заполнением, при котором цвет плавно меняется от одной заданной точки к другой заданной точке, класс TexturePaint — заполнением по предварительно заданному образцу (pattern fill). Класс MultipleGradientPaint организует градиентную заливку с несколькими градиентами, причем его подкласс LinearGradientPaint делает линейную заливку, а подкласс RadialGradientPaint — радиальную заливку.
□ Буквы текста понимаются как фигуры, т. е. объекты, реализующие интерфейс Shape, и могут вычерчиваться методом draw () с использованием всех возможностей этого метода. При их вычерчивании применяется перо, все методы заполнения фигур и их преобразования.
□ Кроме имени, стиля и размера шрифт получил много дополнительных атрибутов, например преобразование координат, подчеркивание или перечеркивание текста, вывод текста справа налево. Цвет текста и его фона являются теперь атрибутами самого текста, а не графического контекста. Можно задать разную ширину символов шрифта, надстрочные и подстрочные индексы. Атрибуты устанавливаются константами класса TextAttribute.
□ Процесс визуализации (rendering) регулируется правилами (hints), определенными константами класса RenderingHints.
С такими возможностями Java 2D стала полноценной системой рисования, вывода текста и изображений. Посмотрим, как реализованы эти возможности и как ими можно
воспользоваться.
Преобразование координат
Правило преобразования координат пользователя в координаты графического устройства (transform) задается автоматически при создании графического контекста так же, как цвет и шрифт. В дальнейшем его можно изменить методом setTransform() так же, как меняется цвет или шрифт. Параметром этого метода служит объект класса AffineTransform из пакета java.awt.geom, подобно объектам класса Color или Font при задании цвета или шрифта.
Рассмотрим подробнее класс AffineTransform.
Класс
Аффинное преобразование координат задается двумя основными конструкторами класса AffineTransform:
AffineTransform(double a, double b, double c, double d, double e, double f); AffineTransform(float a, float b, float c, float d, float e, float f);
При этом точка с координатами (x, y) в пространстве пользователя перейдет в точку с координатами (a * x + c * y + e, b * x + d * y + f) в пространстве графического устройства.
Такое преобразование не искривляет плоскость — прямые линии переходят в прямые, углы между линиями сохраняются. Примерами аффинных преобразований служат повороты вокруг любой точки на любой угол, параллельные сдвиги, отражения от осей, сжатия и растяжения по осям.
Следующие два конструктора используют в качестве параметра массив из шести элементов-коэффициентов преобразования {a, b, c, d, e, f} или массив из четырех элементов {a, b, c, d}, если e = f = 0, составленный из таких же коэффициентов в том же порядке:
AffineTransform(double[] arr);
AffineTransform(float[] arr);
Пятый конструктор создает копию другого, уже имеющегося, объекта:
AffineTransform(AffineTransform at);
Шестой конструктор — конструктор по умолчанию — создает тождественное преобразование:
AffineTransform();
Эти конструкторы математически точны, но неудобны при задании конкретных преобразований. Попробуйте рассчитать коэффициенты поворота на 57° вокруг точки с координатами (20, 40) или сообразить, как будет преобразовано пространство пользователя после выполнения методов:
AffineTransform at =
new AffineTransform(-1.5, 4.45, -0.56, 34.7, 2.68, 0.01); g.setTransform(at);
Во многих случаях удобнее создать преобразование статическими методами, возвращающими объект класса AffineTransform.
□ getRotateInstance (double angle) — возвращает поворот на угол angle, заданный в радианах, вокруг начала координат. Положительное направление поворота таково, что точки оси
□ getRotateInstance (double angle, double x, double y) — такой же поворот вокруг точки с координатами (x, y) .
□ getRotateInstance (double vx, double vy) - поворот, заданный вектором с координа
тами (vx, vy). Эквивалентен методу getRotateInstance(Math.atan2(vx, vy)).
□ getRotateInstance(double vx, double vy, double x, double y) — поворот вокруг точки с координатами (x, y), заданный вектором с координатами (vx, vy). Эквивалентен методу getRotateInstance(Math.atan2(vx, vy), x, y).
□ getQuadrantRotatelnstance (int n) - поворот n раз на угол 90° вокруг начала коорди
нат. Эквивалентен методу getRotateInstance(n * Math.PI / 2.0).
□ getQuadrantRotateInstance(int n, double x, double y) — поворот n раз на угол 90° вокруг точки с координатами (x, y). Эквивалентен методу getRotateInstance(n * Math.PI / 2.0, x, y).