Название: Масштабирование с сохранением позиции курсора над объектом Отправлено: Nimbus от Октябрь 17, 2010, 11:38 Здравствуйте. Дело в том, что я раньше занимался программированием сетевых многопоточных приложений/баз данных, а тут вдруг приспичило прокачать скиллы работы с двумерной графикой. Вобщем, делаю небольшой графический редактор. И возникла необходимость масштабировать графические элементы, причём, чтобы сохранялась позиция курсора мыши над элементом, т. е. чтобы во время скейлинга объекты не "уезжали" из под курсора куда-либо.
Использую для задания позиции объектов и их масштаба объект QMatrix, который потом передаю в QPainter Код такой: Код Собственно, всё, что тут делается, это изменяет систему координат QPainter'а. То есть три поля класса xOffset, yOffset и scale объявлены как qreal. Требуется дописать код в wheelEvent для изменения xOffset и yOffset в зависимости от позиции курсора над виджетом. Исходя из формул (http://doc.trolltech.com/4.7/qmatrix.html#basic-matrix-operations), можно сказать, что scale1*x + xoffset1 = scale2*x + xoffset2 => xoffset2 = scale1*x + xoffset1 - scale2*x Следовательно код: Код должен по идее работать. Однако, когда запускаю на выполнение и пытаюсь скейлить, то создаётся впечатление, что мы приближаемся к объекту по спиралеобразной траектории и позиция над объектом курсора никак не сохраняется :( Кто уже решал подобную проблему, поделитесь советом как исправить ситуацию, пожалуйста. Название: Re: Масштабирование с сохранением позиции курсора над объектом Отправлено: marbius от Октябрь 17, 2010, 18:05 Такой вариант Вам подойдет?
Код
Код
Название: Re: Масштабирование с сохранением позиции курсора над объектом Отправлено: Nimbus от Октябрь 18, 2010, 04:22 Такой вариант Вам подойдет? Нет. Спиралеобразного эффекта нет, но и объекты "уезжают".Название: Re: Масштабирование с сохранением позиции курсора над объектом Отправлено: Igors от Октябрь 18, 2010, 09:28 Делал, но не на Qt. Смысл такой: находите относительные координаты курсора (от 0 до 1). Они не меняются при масштабировании. Расчет для x
float relative_x = (cursor_x + x_offset) / (image_width * old_scale); и получаете новый x_offset x_offset = relative_x * (image_width * new_scale) - cursor_x; Понятно image_width сокращается. И еще: здесь полагаем что сначала мы применили масштаб (scale) а потом смещение (translate) Название: Re: Масштабирование с сохранением позиции курсора над объектом Отправлено: Nimbus от Октябрь 22, 2010, 20:09 Увы, так тоже неверно. При увеличении объекты едут в верхний левый угол виджета, а при уменьшении - в правый нижний.
Название: Re: Масштабирование с сохранением позиции курсора над объектом Отправлено: Igors от Октябрь 22, 2010, 20:16 Увы, так тоже неверно. При увеличении объекты едут в верхний левый угол виджета, а при уменьшении - в правый нижний. А в каком порядке Вы вызываете трансформации для QPainter?Название: Re: Масштабирование с сохранением позиции курсора над объектом Отправлено: Nimbus от Октябрь 25, 2010, 04:31 А в каком порядке Вы вызываете трансформации для QPainter? Код в первом посте смотрите. В событии paintEventНазвание: Re: Масштабирование с сохранением позиции курсора над объектом Отправлено: Igors от Октябрь 25, 2010, 09:04 Код в первом посте смотрите. В событии paintEvent Точно, виноват :)Исходя из формул (http://doc.trolltech.com/4.7/qmatrix.html#basic-matrix-operations), можно сказать, что Здесь "х" есть начальная позиция которая переводится в позицию курсора в координатах окна, то есть:scale1*x + xoffset1 = scale2*x + xoffset2 => xoffset2 = scale1*x + xoffset1 - scale2*x scale1*x + xoffset1 = x_cursor; отсюда x = (x_cursor - xoffset1) / scale1; тогда x_offset2 = x_cursor - x*scale2; Название: Re: Масштабирование с сохранением позиции курсора над объектом Отправлено: GreatSnake от Октябрь 25, 2010, 09:15 Может пусть сам Qt будет делать позиционирование
QGraphicsView::setTransformationAnchor( QGraphicsView::AnchorUnderMouse )? Название: Re: Масштабирование с сохранением позиции курсора над объектом Отправлено: Nimbus от Ноябрь 11, 2010, 13:59 тогда x_offset2 = x_cursor - x*scale2; Ага, и если ещё развернуть формулу при scale1*x + xoffset1 = x_cursor, то мы получим формулуx_offset2 = scale1*x + xoffset1 - x*scale2 которую я уже писал в своём первом посте xoffset2 = scale1*x + xoffset1 - scale2*x и она не работает. Может пусть сам Qt будет делать позиционирование Эммм... Я рисую на виджете Т_ТQGraphicsView::setTransformationAnchor( QGraphicsView::AnchorUnderMouse )? Название: Re: Масштабирование с сохранением позиции курсора над объектом Отправлено: GreatSnake от Ноябрь 11, 2010, 14:52 Цитировать Эммм... Я рисую на виджете Т_Т Да, действительно, чего-то сразу и не приметил.Так может тогда перейти на QGraphicsView, коли уже столько времени решаете проблему? Название: Re: Масштабирование с сохранением позиции курсора над объектом Отправлено: p166 от Ноябрь 13, 2010, 14:15 Совсем недавно занимался такой же проблемой при масштабировании графиков, окончательный вариант был таким:
1. делаем масштабирование 2. центрируем изображение относительно точки масштабирования profit! Название: Re: Масштабирование с сохранением позиции курсора над объектом Отправлено: Igors от Ноябрь 13, 2010, 16:53 и она не работает. Я бы заменил object[j]->draw() на простой тест, напр рисование квадрата 10х10, левый верхний угол в точке (100, 100). По событию нажатия мыши свалил бы в консоль всю информацию: масштаб, смещения и позицию мыши. После минут 10 "анализа" формула/проблема была бы ясна. А так раз в месяц пробовать - долговато :) |