Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Афинные преобразования 
V
    Опции темы
IDVsbruck
Дата 28.1.2007, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 778
Регистрация: 12.11.2006

Репутация: нет
Всего: 22



Решение моей задачи напоминает мне сборку пазла из однополюсно заряженных магнитов ... еще чуть-чуть и сложится ... но в последний момент не складывается.

Задача тривиальная: надо задать текст, повернуть на определенный угол и сместить на определенное расстояние.
Допустим (для простоты) надо подписать часовые метки на часах.

Код

String[] romeDigits = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII"};
double width = 400, height = 400, radius = 350;

BufferedImage buffer = new BufferedImage((int) Math.round(width), (int) Math.round(height), BufferedImage.TYPE_BYTE_GRAY);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Graphics g = ge.createGraphics(buffer);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

Font  font = new Font("Arial", Font.PLAIN, 30);

for (int i = 0; i < 12; i++) {
    //задаем текст вывода
    String symbol = romeDigits[i];
    //контекст
    FontRenderContext frc = g2.getFontRenderContext();
    //контур выводимого текста
    TextLayout tl = new TextLayout(symbol, font, frc);
    //создаем АП для поворота
    AffineTransform tx = new AffineTransform();
    double angle = Math.toRadians((i + 1) * 30 + 90);
    //поворачиваем каждый следущий на 30°
    tx.rotate(angle - Math.PI/2);
    //фигура для вывода
    Shape shape = tl.getOutline(tx);
    //создаем АП для переноса
    AffineTransform txc = new AffineTransform();
    //переносим на свое место
    txc.translate(width/2 - radius * Math.cos(angle), height/2 - radius * Math.sin(angle);
    g2.setTransform(txc);
    g2.fill(shape);
}
//дальше вывод в файл изображения


Возможно, код не совсем рабочий, потому как сваян тут, потому что я свою задачу постарался свести к минимуму (к примитивному примеру), но суть от этого не меняется.

Вопросы следующие:
1. Можно ли сделать вращение и перенос не двумя, а одним афинным преобразованием?
2. (самое важное!) Все эти преобразования работают с текстом, заданным неким прямоугольником, беря за точку приложения левую среднюю точку этого прямоугольника - (0; textLayout.getBounds().getHeight()/2). В результате этого при выводе текста все числа становятся смещенными по часовой стрелке относительно правильных позиций - соответственно, строка "I" меньше всех, а "VIII" больше всех. Что надо сделать, чтобы правильно отобразить текст?

Дополнительно:
почему если применять простое афинное преобразование tx.translate(100, 0) - работает, а tx.translate(99, 0) - нет; tx.translate(5, 0) работает, а tx.translate(10, 0) - нет? 

Спасибо большое за любой дельный совет - голова уже идет набекрень.

Это сообщение отредактировал(а) IDVsbruck - 29.1.2007, 12:33
PM MAIL   Вверх
w1nd
Дата 28.1.2007, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 23
Всего: 54



Цитата(IDVsbruck @  28.1.2007,  18:14 Найти цитируемый пост)
Можно ли сделать вращение и перенос не двумя, а одним афинным преобразованием?

Невозможно.

Цитата(IDVsbruck @  28.1.2007,  18:14 Найти цитируемый пост)
Все эти преобразования работают с текстом, заданным неким прямоугольником, беря за точку приложения левую среднюю точку этого прямоугольника - (0; textLayout.getBounds().getHeight()/2). В результате этого при выводе текста все числа становятся смещенными по часовой стрелке относительно правильных позиций - соответственно, строка "I" меньше всех, а "VIII" больше всех. Что надо сделать, чтобы правильно отобразить текст?

Вы можете задавать точку, относительно которой будет выполнен поворот. См. javadoc по AffineTransform.getRotateInstance(double, double, double). Насчет остального... возмите лист бумаги и напишите на нем что-нибудь. Затем поверните smile Что вас не устраивает-то?


--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
IDVsbruck
Дата 29.1.2007, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 778
Регистрация: 12.11.2006

Репутация: нет
Всего: 22



Да, все же, наверное, я просто запутался ... утро вечера мудренее ... smile

Для правильной установки по центру надо сделать после
     tx.rotate(angle - Math.PI/2);
выражение
     tx.translate(-tl.getBounds().getWidth()/2, 0);
И все! Все показывается отлично.
Спасибо.

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.0657 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.