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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Пересечение QGraphicsItem`ов  (Прочитано 8691 раз)
Max Payne
Гость
« : Апрель 06, 2011, 01:13 »

Есть набор QGraphicsItem`ов на сцене и прямая один конец которой вращается вокруг другого, как луч раара, при этом пересекаясь с другими элементами. Подскажите как можно найти точку пересечения елементов с прямой, не проверяя при этом каждую точку прямой на то принадлежит она элементу с которым пересекается... Заранее спасибо
Записан
Mikhail
Программист
*****
Offline Offline

Сообщений: 587


Просмотр профиля
« Ответ #1 : Апрель 06, 2011, 07:34 »

Используй
bool QGraphicsItem::collidesWithItem ( const QGraphicsItem * other, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape ) const
и
QList<QGraphicsItem *> QGraphicsItem::collidingItems ( Qt::ItemSelectionMode mode = Qt::IntersectsItemShape ) const

Твоя линия должна быть QGraphicsLineItem или наследована от него.
Записан
Max Payne
Гость
« Ответ #2 : Апрель 06, 2011, 08:03 »

Так я могу определить столкновение, но как определить точку, в которой линия коснулась к другому айтему?
Записан
Max Payne
Гость
« Ответ #3 : Апрель 08, 2011, 12:44 »

Никто не сталкивался с такой проблемой? Нид хелп, подскажите, кто делал что то подобное.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Апрель 08, 2011, 13:07 »

Так я могу определить столкновение, но как определить точку, в которой линия коснулась к другому айтему?
Если это есть в Qt - хорошо, но почему "и это" должно здесь быть?  Улыбающийся Собственно Вас "точка" не интересует, надо определить "угол радара" при котором будет касание. Напр

Радар стоит в точке (0, 0) угол отсчитывается против часовой стрелки. Айтем круг с центром в точке (sx, sy) и радиусом R. Тогда

Код
C++ (Qt)
float distance = sqrt(sx * sx + sy * sy);
if (distance >= R) return; // радар внутри круга  
 
float delta_angle = asin(R / distance);
float mid_angle = atan2(sy, sx);
float angle1 = mid_angle - delta_angle;  // первый угол (в радианах)
float angle2 = mid_angle + delta_angle;  // второй
 
Для айтема "полигон" еще проще. Ну и чего ждем?
Записан
madRoger
Гость
« Ответ #5 : Апрель 08, 2011, 13:42 »

Если все-таки нужна точка пересечения, можно попробовать перейти от QGraphicsItem к QRegion и воспользоваться методом QRegion::intersected для определения общей части двух объектов. При минимальном шаге радара эта общая часть будет стремиться к точке.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Апрель 08, 2011, 13:51 »

Если все-таки нужна точка пересечения, можно попробовать перейти от QGraphicsItem к QRegion и воспользоваться методом QRegion::intersected для определения общей части двух объектов. При минимальном шаге радара эта общая часть будет стремиться к точке.
Если все-таки нужна, то проще найти ее по теореме Пифагора. Для примера выше

Код
C++ (Qt)
float dist2 = distance * cos(delta_angle);
inters_x = dist2 * cos(angle1);
inters_y = dist2 * sin(angle1);
 

Записан
Max Payne
Гость
« Ответ #7 : Апрель 17, 2011, 10:06 »

Цитировать
Радар стоит в точке (0, 0) угол отсчитывается против часовой стрелки. Айтем круг с центром в точке (sx, sy) и радиусом R. Тогда

Код
C++ (Qt)
float distance = sqrt(sx * sx + sy * sy);
if (distance >= R) return; // радар внутри круга 
 
float delta_angle = asin(R / distance);
float mid_angle = atan2(sy, sx);
float angle1 = mid_angle - delta_angle;  // первый угол (в радианах)
float angle2 = mid_angle + delta_angle;  // второй
 
Для айтема "полигон" еще проще. Ну и чего ждем?

Во-первых, айтем это многоугольник , при чем не правильный и даже имея QPainterPath, нужно перебирать все его отрезки
и каждый проверять на пересечение с линией.

Я пробовал вот так:
Код:
QPointF Arthur::intersectPoint(QGraphicsItem *it)
{
    bool first = true;
    QPointF t1, t2, t3;
    QPainterPath h = it->shape();
    for (int i = 1; i< h.elementCount(); i++)
    {
        if (!first)
        {
            t1 = h.elementAt(i);
            continue;
        }
        t2 = h.elementAt(i);

        QLineF l1 (it->mapToScene(t1),it->mapToScene(t2));
        if(Linne->intersect(l1, &t3) == 2)
        {
            break;
        }
        t1 = t2;
    }
   
    sc->addRect(t3.x(),t3.y(),150,150,QPen(),QBrush(QColor(Qt::red))); // Этот QRect рисует черт знает где , а не в точке пересечения...
   
}

Функция QLineF::intersect(QLineF&, *QPointF) точку возвращать должна в координатах сцены?
Народ нид хелп, подскажите хоть в какую сторону копать ...
Записан
Max Payne
Гость
« Ответ #8 : Апрель 17, 2011, 10:08 »

У меня линия движется ( вращается вокруг стационарной точки) это не влияет точку возвращаемую QLineF::intersect(QLineF&, *QPointF) ?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Апрель 17, 2011, 10:20 »

Во-первых, айтем это многоугольник , при чем не правильный и даже имея QPainterPath, нужно перебирать все его отрезки
и каждый проверять на пересечение с линией.
Школьный курс геометрии здесь гораздо более полезен чем "изыскивание нужных ф-ций/классов"  Улыбающийся
Зачем перебирать отрезки? Для полигона касание луча всегда будет хотя бы в одной из точек, их и перебирайте
Код
C++ (Qt)
float angle = atan2(point.y, point.x);
 
Так находите 2 точки что соответствуют минимальному и максимальному углам. Потом надо только проверить какая ближайшая - ну разберетесь
Записан
Max Payne
Гость
« Ответ #10 : Апрель 17, 2011, 10:28 »

Обьясните пожалуйста я не понял Вас... У меня есть QPainterPath который был трансформирован (поворот смещение и т.д.) Я могу перебирать поочереди все отрезки и проверять их на пересечение, иначе ни как, я не знаю как он трансформирован, и в какую сторону был повернут, я могу лишь найти центр его boundingRect(), и все...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Апрель 17, 2011, 10:48 »

Обьясните пожалуйста я не понял Вас... У меня есть QPainterPath который был трансформирован (поворот смещение и т.д.) Я могу перебирать поочереди все отрезки и проверять их на пересечение, иначе ни как, я не знаю как он трансформирован, и в какую сторону был повернут, я могу лишь найти центр его boundingRect(), и все...
Ну Вы же точки извлекаете и переводите в координаты сцены - ну и находите 2 точки с минимальным/максимальным углом, отрезки-то Вам зачем? Не забудьте вычесть координаты центра радара если он не в точке (0, 0)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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