Russian Qt Forum
Ноябрь 26, 2024, 04:11 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: QPolygonF - сжатие (inflate)  (Прочитано 26421 раз)
alexis031182
Гость
« : Март 03, 2013, 20:08 »

Здравствуйте.

Подскажите пожалуйста, каким образом можно получить уменьшенный полигон, "сжав" исходный? Масштабирование (scale) тут не подходит. Картинку для понимания сути приложил.

Кое как реализовал через QLineF::normalVector(), но во многих полигонах у меня получаются "петли", от которых не могу никак избавиться (на второй картинке вложения).
Записан
kamre
Частый гость
***
Offline Offline

Сообщений: 233


Просмотр профиля
« Ответ #1 : Март 03, 2013, 21:11 »

Функциональность называется offset. В Qt такой точно нет, нужно брать откуда-то или самому реализовывать. Правда для реализации оффсета от кубической безье (а внутри QPainterPath только такие могут быть кроме отрезков) придется постараться, т.к. этот оффсет уже не будет сам по себе кривой безье.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Март 03, 2013, 21:21 »

Эта операция называлась "эквидистанта" в старом AutoCAD Улыбающийся Да, она  нелинейна и масштабом не делается. Нужно самому считать точки. Данные

QPointF old_Pt  - точка полигонв
QPointF  dir - единичный вектор направления  (внутрь/наружу)
qreal delta - величина сжатия
qreal angle - угол изгиба полигона в точке pt (в радианах)

Тогда новая точка

QPointF new_Pt = old_Pt + dir * (delta / sin((M_PI - angle) / 2));
Записан
alexis031182
Гость
« Ответ #3 : Март 03, 2013, 21:27 »

Про название - буду знать, спасибо. Мне высокая точность повторения полигона-оригинала не нужна, просто хотел избавиться от "петель". У некоторых полигонов имеются довольно узкие "отростки" (вот как на втором рисунке), и из-за них получаю вот такие "лассо", которые портят конечный результат. Надо как-то анализировать ширину таких узких мест, а я совсем не силён в геометрии.

В инете подсказывают, что, например, CGAL решает эту проблему, но из-за одного только этого неудобства отдельную библиотеку цеплять совсем не хочется. Подумал, что может кто писал свой самопальный алгоритм или натравит на путь истинный, чтобы решить проблему средствами Qt.
Записан
alexis031182
Гость
« Ответ #4 : Март 03, 2013, 21:29 »

Эта операция называлась "эквидистанта" в старом AutoCAD Улыбающийся Да, она  нелинейна и масштабом не делается. Нужно самому считать точки.
...
Ого! Спасибо большое, попробую. Это явно лучше, чем то, что я понаписал ))
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Март 03, 2013, 21:42 »

В инете подсказывают, что, например, CGAL решает эту проблему, но из-за одного только этого неудобства отдельную библиотеку цеплять совсем не хочется. Подумал, что может кто писал свой самопальный алгоритм ..
Та какая там либа, тем более CGAL (которому нужен дуст)Непонимающий  Тут просто теорема Пифагора - и все дела. На всякий случай сообщаю как взять угол

Код
C++ (Qt)
qreal PolyAngle( const QPolygonF & poly, int index )
{
int count = poly.size();
assert(count > 2);
const QPointF & nxt = poly[(index + 1) % count];
const QPointF & prv = poly[(index - 1 + count) % count];
QVector2D v1 = QVector2D(poly[index] - prv).normalized();
QVector2D v2 = QVector2D(nxt - poly[index]).normalized();
return acos(QVector2D ::dotProduct(v1, v2));
}
Хреново у них операции с векторами сделаны, получается длинно и мутно. 
Записан
alexis031182
Гость
« Ответ #6 : Март 03, 2013, 21:57 »

Та какая там либа, тем более CGAL (которому нужен дуст)Непонимающий  Тут просто теорема Пифагора - и все дела.
Мне, к сожалению, не так всё очевидно.

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

Цитировать
Хреново у них операции с векторами сделаны, получается длинно и мутно. 
Это в Qt или в CGAL?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Март 03, 2013, 22:04 »

Мне, к сожалению, не так всё очевидно.
А это прямой результат бесконечного использования готовых тулзов Улыбающийся Такие задачи решаются рисованием чертежа на бумажке - лучше покрупнее

Это в Qt или в CGAL?
В Qt
Записан
alexis031182
Гость
« Ответ #8 : Март 03, 2013, 22:20 »

А это прямой результат бесконечного использования готовых тулзов Улыбающийся Такие задачи решаются рисованием чертежа на бумажке - лучше покрупнее
Рисовал. И в общем-то решил с оговорками. Ну и конечно не столь лаконично. Третий день сижу Улыбающийся Ну а что касаемо готовых тулзов, то не всегда есть время разбираться во всём досконально. Естественно, многое используешь не глядя. В этом есть плюс того, что сильно экономится время. Хотя безусловно, когда припрёт, тут уж "хошь не хошь".
Записан
alexis031182
Гость
« Ответ #9 : Март 03, 2013, 23:55 »

Igors, а как вычислить dir? Я видимо что-то не правильно делаю. Контуры сжатого полигона разъезжаются.

Цитировать
QPointF  dir - единичный вектор направления  (внутрь/наружу)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Март 04, 2013, 10:05 »

Igors, а как вычислить dir? Я видимо что-то не правильно делаю. Контуры сжатого полигона разъезжаются.
dir получается поворотом одного из отрезков (примыкающих к точке) на тот же угол. Давайте сделаем проще: скиньте болваночку - просто окно и в нем исходный полигон, а я добавлю остальное
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #11 : Март 04, 2013, 10:13 »

Ууу.. Чёт как то сложно всё тут у вас для простого масштабирования.. Всякие скалярные произведения, acos и т.д..
Должно быть проще)
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
kamre
Частый гость
***
Offline Offline

Сообщений: 233


Просмотр профиля
« Ответ #12 : Март 04, 2013, 10:17 »

для простого масштабирования..
А где здесь "простое масштабирование"?
Записан
alexis031182
Гость
« Ответ #13 : Март 04, 2013, 11:31 »

dir получается поворотом одного из отрезков (примыкающих к точке) на тот же угол.
Да, вроде так и делал.

Давайте сделаем проще: скиньте болваночку - просто окно и в нем исходный полигон, а я добавлю остальное
Приложил.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Март 04, 2013, 11:50 »

Приложил.
Пока разберусь куда там вставлять - проще самому простой проект сделать  Улыбающийся  Attach
Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.116 секунд. Запросов: 23.