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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Попадание точки в коридор  (Прочитано 8777 раз)
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« : Май 25, 2016, 11:55 »

Доброго дня! Вопрос такого плана, можно ли как-то средствами Qt хитро определить попадает ли красная точка в зеленый коридор?
Рисование осуществляется:
Код:
painter.setPen(QPen(colorAlpha,curWidth,pStyle,Qt::FlatCap));
painter.setCompositionMode(mode);
painter.drawPolyline(points);

Координаты желтых точек известны, может возможно как-то получить координаты синих, зная толщину линии? а затем засунуть их в QPolygon в правильном порядке, а там уже алгоритм попадания точки в полигон известен. Рисуется все на QWidget, средствами QPainter! Модуль рисования большой и уже реализован, поэтому конкретного переделывания не хотелось бы, скажем на QGraphicsScene, но возможно сценой можно как-то посчитать в фоне это, либо на крайняк математически как это можно рассчитать.. Возникла мысль обрабатывать цвет пикселя, но коридор может быть не видим, а обработка все равно должна вестись..так что скорее всего нет. В общем какие будут мысли?)
« Последнее редактирование: Май 25, 2016, 13:52 от Vladimir » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #1 : Май 25, 2016, 12:18 »

Код
C++ (Qt)
void CalcBluePt( const QPolygonF & poly, int index, int lineWidth, QPointF bluePt[2] )
{
 QVector2D dir;
 const QPointF & base = poly[index];
 if (index > 0)
   dir += QVector2D(base - poly[index - 1]).normalized():
 if (index < poly.size() - 1)
   dir += QVector2D(poly[index + 1] - base).normalized():
 dir.normalize();
 dir *= lineWidth;
 QPointF ofs(-dir.y(), dir.x());
 bluePt[0] = base + ofs;
 bluePt[1] = base - ofs;
}
Писал прямо здесь, возможны ошибки синнтаксиса
Записан
Swa
Самовар
**
Offline Offline

Сообщений: 170


Просмотр профиля
« Ответ #2 : Май 25, 2016, 12:27 »

По желтым точкам строим список линий QList<QLine>, из красной точки (R) опускаем перпендикуляр на каждый отрезок и получаем точку (P) на отрезке. Если точка P не найдена, то этот отрезок отбрасываем. Дальше, если расстояние между R и P меньше половины толщины коридора (curWidth/2) то красная точка находится внутри.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Май 25, 2016, 12:41 »

По желтым точкам строим список линий QList<QLine>, из красной точки (R) опускаем перпендикуляр на каждый отрезок и получаем точку (P) на отрезке. Если точка P не найдена, то этот отрезок отбрасываем.
На "стыках" есть точки которые не проецируются ни на один из отрезков (точнее проекция оказывается за пределами отрезка).

Поэтому наверное все-таки средствами Qt, построить QPainterPath
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #4 : Май 25, 2016, 12:44 »

Код
C++ (Qt)
void CalcBluePt( const QPolygonF & poly, int index, int lineWidth, QPointF bluePt[2] )
{
 QVector2D dir;
 const QPointF & base = poly[index];
 if (index > 0)
   dir += QVector2D(base - poly[index - 1]).normalized():
 if (index < poly.size() - 1)
   dir += QVector2D(poly[index + 1] - base).normalized():
 dir.normalize();
 dir *= lineWidth;
 QPointF ofs(-dir.y(), dir.x());
 bluePt[0] = base + ofs;
 bluePt[1] = base - ofs;
}
Писал прямо здесь, возможны ошибки синнтаксиса

Круто! Вопросик по параметрам ф-ции const QPolygonF & poly - это выходной полигон описывающий линию заданной толщины?;  int index - это индекс чего?; QPointF bluePt[2] - это координаты синих точек? так я же их не знаю, как мне их на вход подать?

Или же эта ф-ция возвращает координаты синих точек, получая на вход координаты желтых точек и толщину линии??
« Последнее редактирование: Май 25, 2016, 12:54 от Vladimir » Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #5 : Май 25, 2016, 13:50 »

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

Igors, спасибо большое!!!
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Май 25, 2016, 16:00 »

Все разобрался!! Есть в такой реализации своя особенность (см. картинку),
Ну вообще-то неточность/ошибка, а не "особенность" Улыбающийся Надо еще поделить на косинус
Код
C++ (Qt)
void CalcBluePt( const QPolygonF & poly, int index, qreal halfWidth, QPointF bluePt[2] )
{
 QVector2D dir, dir1, dir2;
 const QPointF & base = poly[index];
 qreal dot = 1.0;
 if (index == 0)  
   dir = QVector2D(poly[index + 1] - base).normalized();
 else
   if (index == poly.size() - 1)
     dir = QVector2D(base - poly[index - 1]).normalized();
   else {
     dir1 = QVector2D(poly[index + 1] - base).normalized();
     dir2 = QVector2D(base - poly[index - 1]).normalized();
     dir = (dir1 + dir2).normalized();
     dot = QVector2D::dotProduct(dir, dir2);
   }
 dir *= halfWidth / dot;
 QPointF ofs(-dir.y(), dir.x());
 bluePt[0] = base + ofs;
 bluePt[1] = base - ofs;
}
 
Так правда не выходит "скошенный уголок", там получится больше кода

А QPainterPath смотрели? По смыслу он самое экономичное решение (по крайней мере по объему кода)
« Последнее редактирование: Май 26, 2016, 11:27 от Igors » Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #7 : Май 25, 2016, 16:29 »

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

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Май 25, 2016, 17:22 »

.. второй вариант, кстати, не работает.. получается что-то типо (см. картинку) Улыбающийся
Да, тут я маленько насвистел  Улыбающийся подправил
Записан
Vladimir
Крякер
****
Offline Offline

Сообщений: 305



Просмотр профиля
« Ответ #9 : Май 26, 2016, 09:59 »

Как говорится идеальный - враг хорошего)  Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Май 26, 2016, 11:30 »

Ничего, еще подправим (ошибка была с normalized).
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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