Qt Graphics View: определение направления столкновения

Я пытаюсь создать игру, используя qt. У меня есть некоторые препятствия (QPixmapItem) в графическом представлении. У меня есть мяч, и я хочу, чтобы он отскакивал от препятствий. Как определить нормаль поверхности препятствия, чтобы рассчитать новое направление движения? Например:

------------------------------
    / \          |
   /   \         | 
  /     \        v
 /       \       ^
/         \      |

person user2942080    schedule 01.11.2013    source источник
comment
Возможно, вам следует взглянуть на пример столкновения мышей.   -  person thuga    schedule 01.11.2013
comment
Очевидно, что синус угла между направлением движения и границей должен быть таким же после того, как мяч отскочил от границы.   -  person vahancho    schedule 01.11.2013
comment
Я прочитал этот учебник, и он был очень полезным. Однако в этом примере мыши поворачиваются в случайном направлении, чтобы избежать столкновений, тогда как мне нужно вычислить угол, на который мяч должен двигаться после столкновения.   -  person user2942080    schedule 01.11.2013
comment
Этот вопрос не по теме, потому что это математическая задача. Также вы должны использовать существующий физический движок 2D (например, Box2d) вместо того, чтобы изобретать свой собственный.   -  person Pavel Strakhov    schedule 01.11.2013
comment
Это не математическая задача. Если бы я знал угол нормали/тангенса поверхности, вычислить направление было бы легко. Я могу только определить, произошло ли столкновение. Глядя на функции QGraphicsItem, shape() может быть полезной, но я до сих пор не понял, как это сделать.   -  person user2942080    schedule 01.11.2013


Ответы (1)


Судя по вашим комментариям, вы действительно подходите к проблеме правильно. Однако вам нужно найти решение, чтобы перебрать элементы QPainterPath и определить, какие из них на самом деле пересекаются с линией направления вашего мяча (использование QLineF для этого должно быть довольно простой задачей). Кроме того, упрощение пути уменьшит любые кривые Безье до прямых линий для упрощения вычислений (я оставлю это на ваше усмотрение, так как маловероятно, что вам придется самостоятельно выполнять вычисления Безье или, возможно, вообще). Поскольку может быть более одного пересечения, вам нужно будет определить, какая точка пересечения находится ближе всего к центру вашего мяча. Как только вы выяснили, какая точка ближе всего, используйте этот элемент в QLineF, чтобы найти его вектор нормали, а затем вы можете завершить расчет направления отскока.

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

QPainterPath path = item->shape();

path = path.simplified(); //optional if you do not want to handle curveTo elements yourself

QPainterPath::Element element;
QPainterPath::Element P1;
QPainterPath::Element P2;
QPainterPath::Element P3;
QPainterPath::Element P4;

for(int i = 0; i < path.elementCount()-1; ++i)
{
    element = path.elementAt(i);
    if(element.isMoveTo())
    {
        //Do something
    }
    else if(element.isLineTo())
    {
        //Do something with element.x and element.y
    }
    else if(element.isCurveTo())
    {
        P1 = path.elementAt(i-1); // start point
        P2 = path.elementAt(i);   // control point
        P3 = path.elementAt(i+1); // control point
        P4 = path.elementAt(i+2); // end point

        //Do something with cubic bezier points
    }
}
person redteam316    schedule 20.11.2013