# HG changeset patch # User insilmaril # Date 1251124747 0 # Node ID d85834ad8c541d04048b2bccd6172edb08db1d85 # Parent 78ba80b54bc4ced34f0acc7909bf1c1d46c06754 Fixed collision methods, segfault for wrong flagname diff -r 78ba80b54bc4 -r d85834ad8c54 branchobj.cpp --- a/branchobj.cpp Tue Aug 18 12:39:07 2009 +0000 +++ b/branchobj.cpp Mon Aug 24 14:39:07 2009 +0000 @@ -147,7 +147,7 @@ if (parObj->getTreeItem()->depth()==0) { // new parent is a mapcenter - QPointF p= normalise ( QPointF (m.x() - o->getChildPos().x(), + QPointF p= normalize ( QPointF (m.x() - o->getChildPos().x(), m.y() - o->getChildPos().y() )); if (p.x()<0) p.setX( p.x()-bbox.width() ); move2RelPos (p); diff -r 78ba80b54bc4 -r d85834ad8c54 geometry.cpp --- a/geometry.cpp Tue Aug 18 12:39:07 2009 +0000 +++ b/geometry.cpp Mon Aug 24 14:39:07 2009 +0000 @@ -1,11 +1,12 @@ #include "geometry.h" #include <math.h> -#include <iostream> #include "misc.h" +#include <iostream> using namespace std; + QRectF addBBox(QRectF r1, QRectF r2) { // Find smallest QRectF containing given rectangles @@ -45,6 +46,50 @@ return false; } +ConvexPolygon::ConvexPolygon () +{ +} + +ConvexPolygon::ConvexPolygon (QPolygonF p):QPolygonF (p) +{ +} + +void ConvexPolygon::calcCentroid() +{ + // Calculate area and centroid + // http://en.wikipedia.org/wiki/Centroid + qreal cx,cy,p; + cx=cy=0; + _area=0; + + append (at(0)); + for (int i=0;i<size()-1;i++) + { + p=at(i).x() * at(i+1).y() - at(i+1).x() * at(i).y(); + _area+=p; + cx+=(at(i).x()+at(i+1).x()) * p; + cy+=(at(i).y()+at(i+1).y()) * p; + } + pop_back(); + // area is negative if vertices ordered counterclockwise + // (in mirrored graphicsview!) + _area=_area/2; + p=_area*6; + _centroid.setX (cx/p); + _centroid.setY (cy/p); +} + +QPointF ConvexPolygon::centroid() const +{ + return _centroid; +} + +qreal ConvexPolygon::weight() const +{ + return _area; +} + +//! Normalize vector QPointF normalize (const QPointF &p) { if (p==QPointF(0,0)) return p; @@ -52,38 +97,47 @@ return QPointF (p.x()/l,p.y()/l); } -// Dot product of two vectors +//! Dot product of two vectors qreal dotProduct (const QPointF &a, const QPointF &b) { return a.x()*b.x() + a.y()*b.y(); } -/* Calculate the projection of a polygon on an axis - and returns it as a [min, max] interval -*/ -void ProjectPolygon(QPointF axis, QPolygonF polygon, qreal &min, qreal &max) +QPointF scale (const QPointF &v,const qreal &f) +{ + return QPointF (v.x()*f,v.y()*f); +} + +QPointF invert (const QPointF &v) +{ + return QPointF (-v.x(),-v.y()); +} + +/*! Calculate the projection of a polygon on an axis + and returns it as a [min, max] interval */ + +void projectPolygon(QPointF axis, QPolygonF polygon, qreal &min, qreal &max) { // To project a point on an axis use the dot product + //cout << "Projecting on "<< axis<<endl; qreal d = dotProduct(axis,polygon.at(0)); min = d; max = d; - for (int i = 0; i < polygon.size(); i++) { + for (int i = 0; i < polygon.size(); i++) + { d= dotProduct (polygon.at(i),axis); if (d < min) min = d; else - { if (d> max) max = d; - } + // cout << "p="<<polygon.at(i)<<" d="<<d<<" (min, max)=("<<min<<","<<max<<")\n"; } } -/* Calculate the signed distance between [minA, maxA] and [minB, maxB] - The distance will be negative if the intervals overlap -*/ - +// Calculate the signed distance between [minA, maxA] and [minB, maxB] +// The distance will be negative if the intervals overlap qreal intervalDistance(qreal minA, qreal maxA, qreal minB, qreal maxB) { if (minA < minB) { @@ -92,14 +146,16 @@ return minA - maxB; } } -/* + +/*! Check if polygon A is going to collide with polygon B. The last parameter is the *relative* velocity of the polygons (i.e. velocityA - velocityB) +*/ -*/ -PolygonCollisionResult PolygonCollision(QPolygonF polygonA, - QPolygonF polygonB, QPointF velocity) { +PolygonCollisionResult polygonCollision(QPolygonF polygonA, + QPolygonF polygonB, QPointF velocity) +{ PolygonCollisionResult result; result.intersect = true; result.willIntersect = true; @@ -110,22 +166,23 @@ QPointF translationAxis; QPointF edge; +/* cout << "\nA: "; for (int k=0; k<edgeCountA;k++) cout <<polygonA.at(k); cout << "\nB: "; for (int k=0; k<edgeCountB;k++) cout <<polygonB.at(k); - + cout <<endl; +*/ // Loop through all the edges of both polygons - int i=0; - int j=0; - while (i<edgeCountA && j<edgeCountB) + for (int i=0;i<edgeCountA + edgeCountB;i++) { if (i< edgeCountA) { - if (i<edgeCountA - 1) + // Loop through polygon A + if (i<edgeCountA-1) edge = QPointF ( polygonA.at(i+1).x()-polygonA.at(i).x(), polygonA.at(i+1).y()-polygonA.at(i).y()); @@ -133,23 +190,21 @@ edge = QPointF ( polygonA.at(0).x()-polygonA.at(i).x(), polygonA.at(0).y()-polygonA.at(i).y()); - i++; } else { - if (i < edgeCountB -1) + // Loop through polygon B + if (i < edgeCountA +edgeCountB -1 ) edge = QPointF ( - polygonB.at(j+1).x() - polygonA.at(i).x(), - polygonB.at(j+1).y() - polygonA.at(i).y()); + polygonB.at(i-edgeCountA+1).x() - polygonB.at(i-edgeCountA).x(), + polygonB.at(i-edgeCountA+1).y() - polygonB.at(i-edgeCountA).y()); else edge = QPointF ( - polygonB.at(0).x() - polygonA.at(i).x(), - polygonB.at(0).y() - polygonA.at(i).y()); - j++; + polygonB.at(0).x() - polygonB.at(i-edgeCountA).x(), + polygonB.at(0).y() - polygonB.at(i-edgeCountA).y()); } // ===== 1. Find if the polygons are currently intersecting ===== - // Find the axis perpendicular to the current edge QPointF axis (-edge.y(), edge.x()); @@ -158,17 +213,15 @@ // Find the projection of the polygon on the current axis qreal minA = 0; qreal minB = 0; qreal maxA = 0; qreal maxB = 0; - ProjectPolygon(axis, polygonA, minA, maxA); - ProjectPolygon(axis, polygonB, minB, maxB); + projectPolygon(axis, polygonA, minA, maxA); + projectPolygon(axis, polygonB, minB, maxB); // Check if the polygon projections are currentlty intersecting - if (intervalDistance(minA, maxA, minB, maxB) > 0) - result.intersect = false; - else - result.intersect = true; + qreal d = intervalDistance(minA, maxA, minB, maxB); + if (d > 0) result.intersect = false; - // ===== 2. Now find if the polygons *will* intersect ===== + // ===== 2. Now find if the polygons *will* intersect ===== // Project the velocity on the current axis @@ -181,30 +234,25 @@ minA += velocityProjection; else maxA += velocityProjection; - // Do the same test as above for the new projection - qreal d = intervalDistance(minA, maxA, minB, maxB); - if (d > 0) result.willIntersect = false; + // d = intervalDistance(minA, maxA, minB, maxB); + //if (d > 0) result.willIntersect = false; /* - */ cout <<" "; - cout <<"minA="<<minA<<" "; - cout <<"maxA="<<maxA<<" "; - cout <<"minB="<<minB<<" "; - cout <<"maxB="<<maxB<<" "; + cout << "edge="<<edge<<" "; + cout <<"axis="<<axis<<" "; + cout <<"dA=("<<minA<<","<<maxA<<") dB=("<<minB<<","<<maxB<<")"; cout <<" d="<<d<<" "; - cout <<"minD="<<minIntervalDistance<<" "; - cout <<"axis="<<axis<<" "; + //cout <<"minD="<<minIntervalDistance<<" "; cout <<"int="<<result.intersect<<" "; - cout <<"wint="<<result.willIntersect<<" "; + //cout <<"wint="<<result.willIntersect<<" "; //cout <<"velProj="<<velocityProjection<<" "; cout <<endl; - - + */ - if (result.intersect || result.willIntersect) + if (result.intersect )// || result.willIntersect) { // Check if the current interval distance is the minimum one. If so // store the interval distance and the current distance. This will @@ -213,13 +261,13 @@ if (d<0) d=-d; if (d < minIntervalDistance) { minIntervalDistance = d; - translationAxis = axis; - cout << "tAxix="<<translationAxis<<endl; + //translationAxis = axis; + //cout << "tAxix="<<translationAxis<<endl; //QPointF t = polygonA.Center - polygonB.Center; - QPointF t = polygonA.at(0) - polygonB.at(0); - if (dotProduct(t,translationAxis) < 0) - translationAxis = -translationAxis; + //QPointF t = polygonA.at(0) - polygonB.at(0); + //if (dotProduct(t,translationAxis) < 0) + // translationAxis = -translationAxis; } } } diff -r 78ba80b54bc4 -r d85834ad8c54 geometry.h --- a/geometry.h Tue Aug 18 12:39:07 2009 +0000 +++ b/geometry.h Mon Aug 24 14:39:07 2009 +0000 @@ -1,18 +1,32 @@ -#ifndef GEOMETRY_H -#define GEOMETRY_H +#ifndef GEOMETRY +#define GEOMETRY -#include <QPointF> -#include <QRectF> #include <QPolygonF> QRectF addBBox(QRectF r1, QRectF r2); bool isInBox(const QPointF &p, const QRectF &box); +class ConvexPolygon:public QPolygonF +{ +public: + ConvexPolygon (); + ConvexPolygon (QPolygonF p); + void calcCentroid() ; + QPointF centroid() const; + qreal weight() const; +private: + QPointF _centroid; + qreal _area; +}; + QPointF normalize (const QPointF &p); qreal dotProduct (const QPointF &a, const QPointF &b); +QPointF scale (const QPointF &v,const qreal &f); +QPointF invert (const QPointF &v); + class PolygonCollisionResult { public: // Are the polygons going to intersect forward in time? @@ -26,9 +40,10 @@ }; -void ProjectPolygon(QPointF axis, QPolygonF polygon, qreal &min, qreal &max) ; +void projectPolygon(QPointF axis, QPolygonF polygon, qreal &min, qreal &max) ; + qreal intervalDistance(qreal minA, qreal maxA, qreal minB, qreal maxB); -PolygonCollisionResult PolygonCollision(QPolygonF polygonA, +PolygonCollisionResult polygonCollision(QPolygonF polygonA, QPolygonF polygonB, QPointF velocity); -#endif +#endif \ No newline at end of file diff -r 78ba80b54bc4 -r d85834ad8c54 mainwindow.cpp --- a/mainwindow.cpp Tue Aug 18 12:39:07 2009 +0000 +++ b/mainwindow.cpp Mon Aug 24 14:39:07 2009 +0000 @@ -1231,7 +1231,7 @@ // Original: xsldbg_output.png flag->load(flagsPath+"flag-info.png"); - setupFlag (flag,tb,"inflag",tr("Info","Standardflag")); + setupFlag (flag,tb,"info",tr("Info","Standardflag")); // Original khelpcenter.png flag->load(flagsPath+"flag-lifebelt.png"); diff -r 78ba80b54bc4 -r d85834ad8c54 misc.cpp --- a/misc.cpp Tue Aug 18 12:39:07 2009 +0000 +++ b/misc.cpp Mon Aug 24 14:39:07 2009 +0000 @@ -49,40 +49,6 @@ } } -QPointF normalise(const QPointF &p) -{ - // Calculate normalised position (fixed length) - - qreal px=p.x(); - qreal py=p.y(); - qreal x; - qreal y; - qreal r=150; - - if (px==0) - { - x=0; - if (py>=0) - y=r; - else - y=-r; - } else - { - qreal sign; - qreal a; - if (px>0) - sign=1; - else - sign=-1; - - a=atan (py / px); - x=cos (a) * r *sign; - y=sin (a) * r *sign; - } - return QPoint ((int) (x),(int) (y)); -} - - qreal max(qreal a, qreal b) { if (a>b) diff -r 78ba80b54bc4 -r d85834ad8c54 misc.h --- a/misc.h Tue Aug 18 12:39:07 2009 +0000 +++ b/misc.h Mon Aug 24 14:39:07 2009 +0000 @@ -14,9 +14,6 @@ extern ostream &operator<< (ostream &stream, QPoint const &p); extern ostream &operator<< (ostream &stream, QPointF const &p); qreal getAngle(const QPointF &); -QPointF normalise (const QPointF &); qreal max (qreal,qreal); -class BranchObj; -class MapEditor; #endif diff -r 78ba80b54bc4 -r d85834ad8c54 treemodel.cpp --- a/treemodel.cpp Tue Aug 18 12:39:07 2009 +0000 +++ b/treemodel.cpp Mon Aug 24 14:39:07 2009 +0000 @@ -66,14 +66,14 @@ TreeItem *parentItem; if (!parent.isValid()) - { //FIXME-1 + { //FIXME-3 left here for testing only, seems to work now... parentItem = rootItem; /* cout << "TM::index() no parent?! xxx\n"; cout << " row="<<row<<" col="<<column<<endl; cout << " parent.internal="<< parent.internalPointer()<<endl; */ - //return QModelIndex(); //FIXME-0 this line is new (testing) + //return QModelIndex(); //FIXME-3 this line is new (testing) // Somehow index is requested where parentIndex is invalid. // what's happening here...? // Check if Qt examples also return index of rootIem then... diff -r 78ba80b54bc4 -r d85834ad8c54 version.h --- a/version.h Tue Aug 18 12:39:07 2009 +0000 +++ b/version.h Mon Aug 24 14:39:07 2009 +0000 @@ -7,7 +7,7 @@ #define __VYM_VERSION "1.13.0" //#define __VYM_CODENAME "Codename: RC-1" #define __VYM_CODENAME "Codename: development version, not for production!" -#define __VYM_BUILD_DATE "2009-08-08" +#define __VYM_BUILD_DATE "2009-08-24" bool checkVersion(const QString &);