insilmaril@650: #include "geometry.h" insilmaril@650: insilmaril@656: #include insilmaril@662: #include "misc.h" insilmaril@656: insilmaril@792: #include insilmaril@792: insilmaril@789: #include insilmaril@662: using namespace std; insilmaril@650: insilmaril@789: insilmaril@650: QRectF addBBox(QRectF r1, QRectF r2) insilmaril@650: { insilmaril@650: // Find smallest QRectF containing given rectangles insilmaril@650: insilmaril@650: QRectF n; insilmaril@650: // Set left border insilmaril@650: if (r1.left() <= r2.left() ) insilmaril@650: n.setLeft(r1.left() ); insilmaril@650: else insilmaril@650: n.setLeft(r2.left() ); insilmaril@650: insilmaril@650: // Set top border insilmaril@650: if (r1.top() <= r2.top() ) insilmaril@650: n.setTop(r1.top() ); insilmaril@650: else insilmaril@650: n.setTop(r2.top() ); insilmaril@650: insilmaril@650: // Set right border insilmaril@650: if (r1.right() <= r2.right() ) insilmaril@650: n.setRight(r2.right() ); insilmaril@650: else insilmaril@650: n.setRight(r1.right() ); insilmaril@650: insilmaril@650: // Set bottom insilmaril@650: if (r1.bottom() <= r2.bottom() ) insilmaril@650: n.setBottom(r2.bottom() ); insilmaril@650: else insilmaril@650: n.setBottom(r1.bottom() ); insilmaril@650: return n; insilmaril@650: } insilmaril@650: insilmaril@754: bool isInBox(const QPointF &p, const QRectF &box) insilmaril@650: { insilmaril@650: if (p.x() >= box.left() && p.x() <= box.right() insilmaril@650: && p.y() <= box.bottom() && p.y() >= box.top() ) insilmaril@650: return true; insilmaril@650: return false; insilmaril@650: } insilmaril@656: insilmaril@792: Vector::Vector ():QPointF () insilmaril@792: { insilmaril@792: } insilmaril@792: insilmaril@792: Vector::Vector (const QPointF &p):QPointF (p) insilmaril@792: { insilmaril@792: } insilmaril@792: insilmaril@792: Vector::Vector (qreal x, qreal y):QPointF (x,y) insilmaril@792: { insilmaril@792: } insilmaril@792: insilmaril@792: //! Normalize vector insilmaril@792: void Vector::normalize () insilmaril@792: { insilmaril@792: if (x()==0 && y()==0) return; insilmaril@792: qreal l=sqrt ( x()*x() + y()*y() ); insilmaril@792: setX (x()/l); insilmaril@792: setY (y()/l); insilmaril@792: } insilmaril@792: insilmaril@792: //! Dot product of two vectors insilmaril@792: qreal Vector::dotProduct (const QPointF &b) insilmaril@792: { insilmaril@792: return x()*b.x() + y()*b.y(); insilmaril@792: } insilmaril@792: insilmaril@792: insilmaril@792: void Vector::scale (const qreal &f) insilmaril@792: { insilmaril@792: setX (x()*f); insilmaril@792: setY (y()*f); insilmaril@792: } insilmaril@792: insilmaril@792: void Vector::invert () insilmaril@792: { insilmaril@792: setX (-x()); insilmaril@792: setY (-y()); insilmaril@792: } insilmaril@792: insilmaril@798: QPointF Vector::toQPointF () insilmaril@798: { insilmaril@798: return QPointF (x(),y()); insilmaril@798: } insilmaril@798: insilmaril@792: /*! Calculate the projection of a polygon on an axis insilmaril@792: and returns it as a [min, max] interval */ insilmaril@789: ConvexPolygon::ConvexPolygon () insilmaril@789: { insilmaril@789: } insilmaril@789: insilmaril@789: ConvexPolygon::ConvexPolygon (QPolygonF p):QPolygonF (p) insilmaril@789: { insilmaril@789: } insilmaril@789: insilmaril@789: void ConvexPolygon::calcCentroid() insilmaril@789: { insilmaril@789: // Calculate area and centroid insilmaril@789: // http://en.wikipedia.org/wiki/Centroid insilmaril@789: qreal cx,cy,p; insilmaril@789: cx=cy=0; insilmaril@789: _area=0; insilmaril@789: insilmaril@789: append (at(0)); insilmaril@789: for (int i=0;i max) max = d; insilmaril@789: // cout << "p="< 0) result.intersect = false; insilmaril@656: insilmaril@789: // ===== 2. Now find if the polygons *will* intersect ===== insilmaril@656: insilmaril@656: insilmaril@656: // Project the velocity on the current axis insilmaril@656: insilmaril@792: qreal velocityProjection = axis.dotProduct(velocity); insilmaril@656: insilmaril@656: // Get the projection of polygon A during the movement insilmaril@656: insilmaril@662: if (velocityProjection < 0) insilmaril@656: minA += velocityProjection; insilmaril@662: else insilmaril@656: maxA += velocityProjection; insilmaril@656: insilmaril@656: // Do the same test as above for the new projection insilmaril@656: insilmaril@789: // d = intervalDistance(minA, maxA, minB, maxB); insilmaril@789: //if (d > 0) result.willIntersect = false; insilmaril@662: /* insilmaril@662: cout <<" "; insilmaril@789: cout << "edge="<