Fixed collision methods, segfault for wrong flagname
authorinsilmaril
Mon, 24 Aug 2009 14:39:07 +0000
changeset 789d85834ad8c54
parent 788 78ba80b54bc4
child 790 133e2ed6b9c5
Fixed collision methods, segfault for wrong flagname
branchobj.cpp
geometry.cpp
geometry.h
mainwindow.cpp
misc.cpp
misc.h
treemodel.cpp
version.h
     1.1 --- a/branchobj.cpp	Tue Aug 18 12:39:07 2009 +0000
     1.2 +++ b/branchobj.cpp	Mon Aug 24 14:39:07 2009 +0000
     1.3 @@ -147,7 +147,7 @@
     1.4  	if (parObj->getTreeItem()->depth()==0)	
     1.5  	{	// new parent is a mapcenter
     1.6  
     1.7 -		QPointF p= normalise ( QPointF (m.x() - o->getChildPos().x(),
     1.8 +		QPointF p= normalize ( QPointF (m.x() - o->getChildPos().x(),
     1.9  									  m.y() - o->getChildPos().y() ));
    1.10  		if (p.x()<0) p.setX( p.x()-bbox.width() );
    1.11  		move2RelPos (p);
     2.1 --- a/geometry.cpp	Tue Aug 18 12:39:07 2009 +0000
     2.2 +++ b/geometry.cpp	Mon Aug 24 14:39:07 2009 +0000
     2.3 @@ -1,11 +1,12 @@
     2.4  #include "geometry.h"
     2.5  
     2.6  #include <math.h>
     2.7 -#include <iostream>
     2.8  #include "misc.h"
     2.9  
    2.10 +#include <iostream>
    2.11  using namespace std;
    2.12  
    2.13 +
    2.14  QRectF addBBox(QRectF r1, QRectF r2)
    2.15  {	
    2.16  	// Find smallest QRectF containing given rectangles
    2.17 @@ -45,6 +46,50 @@
    2.18      return false;	
    2.19  }
    2.20  
    2.21 +ConvexPolygon::ConvexPolygon ()
    2.22 +{
    2.23 +}
    2.24 +
    2.25 +ConvexPolygon::ConvexPolygon (QPolygonF p):QPolygonF (p)
    2.26 +{
    2.27 +}
    2.28 +
    2.29 +void ConvexPolygon::calcCentroid() 
    2.30 +{
    2.31 +	// Calculate area and centroid
    2.32 +	// http://en.wikipedia.org/wiki/Centroid
    2.33 +	qreal cx,cy,p;
    2.34 +	cx=cy=0;
    2.35 +	_area=0;
    2.36 +
    2.37 +	append (at(0));
    2.38 +	for (int i=0;i<size()-1;i++)
    2.39 +	{
    2.40 +		p=at(i).x() * at(i+1).y() - at(i+1).x() * at(i).y();
    2.41 +		_area+=p;
    2.42 +		cx+=(at(i).x()+at(i+1).x()) * p;
    2.43 +		cy+=(at(i).y()+at(i+1).y()) * p;
    2.44 +	}	
    2.45 +	pop_back();
    2.46 +	// area is negative if vertices ordered counterclockwise
    2.47 +	// (in mirrored graphicsview!)
    2.48 +	_area=_area/2;	
    2.49 +	p=_area*6;
    2.50 +	_centroid.setX (cx/p);
    2.51 +	_centroid.setY (cy/p);
    2.52 +}
    2.53 +
    2.54 +QPointF ConvexPolygon::centroid() const
    2.55 +{
    2.56 +	return _centroid;
    2.57 +}
    2.58 +
    2.59 +qreal ConvexPolygon::weight() const
    2.60 +{
    2.61 +	return _area;
    2.62 +}
    2.63 +
    2.64 +//! Normalize vector
    2.65  QPointF normalize (const QPointF &p)
    2.66  {
    2.67  	if (p==QPointF(0,0)) return p;
    2.68 @@ -52,38 +97,47 @@
    2.69  	return QPointF (p.x()/l,p.y()/l);
    2.70  }
    2.71  
    2.72 -// Dot product of two vectors
    2.73 +//! Dot product of two vectors
    2.74  qreal dotProduct (const QPointF &a, const QPointF &b)
    2.75  {
    2.76  	return a.x()*b.x() + a.y()*b.y();
    2.77  }
    2.78  
    2.79  
    2.80 -/* Calculate the projection of a polygon on an axis
    2.81 -   and returns it as a [min, max] interval
    2.82 -*/
    2.83 -void ProjectPolygon(QPointF axis, QPolygonF polygon, qreal &min, qreal &max) 
    2.84 +QPointF scale (const QPointF &v,const qreal &f)
    2.85 +{
    2.86 +	return QPointF (v.x()*f,v.y()*f);
    2.87 +}
    2.88 +
    2.89 +QPointF invert (const QPointF &v)
    2.90 +{
    2.91 +	return QPointF (-v.x(),-v.y());
    2.92 +}
    2.93 +
    2.94 +/*! Calculate the projection of a polygon on an axis
    2.95 +    and returns it as a [min, max] interval  */
    2.96 +
    2.97 +void projectPolygon(QPointF axis, QPolygonF polygon, qreal &min, qreal &max) 
    2.98  {
    2.99      // To project a point on an axis use the dot product
   2.100  
   2.101 +	//cout << "Projecting on "<< axis<<endl;
   2.102      qreal d = dotProduct(axis,polygon.at(0));
   2.103      min = d;
   2.104      max = d;
   2.105 -    for (int i = 0; i < polygon.size(); i++) {
   2.106 +    for (int i = 0; i < polygon.size(); i++) 
   2.107 +	{
   2.108          d= dotProduct (polygon.at(i),axis);
   2.109          if (d < min) 
   2.110              min = d;
   2.111          else 
   2.112 -		{
   2.113              if (d> max) max = d;
   2.114 -        }
   2.115 +	//	cout << "p="<<polygon.at(i)<<"  d="<<d<<"  (min, max)=("<<min<<","<<max<<")\n";	
   2.116      }
   2.117  }
   2.118  
   2.119 -/* Calculate the signed distance between [minA, maxA] and [minB, maxB]
   2.120 -   The distance will be negative if the intervals overlap
   2.121 -*/
   2.122 -
   2.123 +// Calculate the signed distance between [minA, maxA] and [minB, maxB]
   2.124 +// The distance will be negative if the intervals overlap
   2.125  
   2.126  qreal intervalDistance(qreal minA, qreal maxA, qreal minB, qreal maxB) {
   2.127      if (minA < minB) {
   2.128 @@ -92,14 +146,16 @@
   2.129          return minA - maxB;
   2.130      }
   2.131  }
   2.132 -/*
   2.133 +
   2.134 +/*!
   2.135   Check if polygon A is going to collide with polygon B.
   2.136   The last parameter is the *relative* velocity 
   2.137   of the polygons (i.e. velocityA - velocityB)
   2.138 +*/
   2.139  
   2.140 -*/
   2.141 -PolygonCollisionResult PolygonCollision(QPolygonF polygonA, 
   2.142 -                              QPolygonF polygonB, QPointF velocity) {
   2.143 +PolygonCollisionResult polygonCollision(QPolygonF polygonA, 
   2.144 +                              QPolygonF polygonB, QPointF velocity) 
   2.145 +{
   2.146      PolygonCollisionResult result;
   2.147      result.intersect = true;
   2.148      result.willIntersect = true;
   2.149 @@ -110,22 +166,23 @@
   2.150      QPointF translationAxis;
   2.151      QPointF edge;
   2.152  
   2.153 +/*
   2.154  	cout << "\nA: ";
   2.155  	for (int k=0; k<edgeCountA;k++)
   2.156  		cout <<polygonA.at(k);
   2.157  	cout << "\nB: ";
   2.158  	for (int k=0; k<edgeCountB;k++)
   2.159  		cout <<polygonB.at(k);
   2.160 -		
   2.161 +	cout <<endl;	
   2.162 +*/		
   2.163  		
   2.164      // Loop through all the edges of both polygons
   2.165 -	int i=0;
   2.166 -	int j=0;
   2.167 -	while (i<edgeCountA && j<edgeCountB)
   2.168 +	for (int i=0;i<edgeCountA + edgeCountB;i++)
   2.169  	{
   2.170          if (i< edgeCountA) 
   2.171  		{
   2.172 -			if (i<edgeCountA - 1)
   2.173 +			// Loop through polygon A
   2.174 +			if (i<edgeCountA-1)
   2.175  				edge = QPointF (
   2.176  					polygonA.at(i+1).x()-polygonA.at(i).x(), 
   2.177  					polygonA.at(i+1).y()-polygonA.at(i).y());
   2.178 @@ -133,23 +190,21 @@
   2.179  				edge = QPointF (
   2.180  					polygonA.at(0).x()-polygonA.at(i).x(), 
   2.181  					polygonA.at(0).y()-polygonA.at(i).y());
   2.182 -			i++;		
   2.183          } else 
   2.184  		{
   2.185 -			if (i < edgeCountB -1)
   2.186 +			// Loop through polygon B
   2.187 +			if (i < edgeCountA +edgeCountB -1 )
   2.188  				edge = QPointF (
   2.189 -					polygonB.at(j+1).x() - polygonA.at(i).x(), 
   2.190 -					polygonB.at(j+1).y() - polygonA.at(i).y());
   2.191 +					polygonB.at(i-edgeCountA+1).x() - polygonB.at(i-edgeCountA).x(), 
   2.192 +					polygonB.at(i-edgeCountA+1).y() - polygonB.at(i-edgeCountA).y());
   2.193  			else	
   2.194  				edge = QPointF (
   2.195 -					polygonB.at(0).x() - polygonA.at(i).x(), 
   2.196 -					polygonB.at(0).y() - polygonA.at(i).y());
   2.197 -			j++;
   2.198 +					polygonB.at(0).x() - polygonB.at(i-edgeCountA).x(), 
   2.199 +					polygonB.at(0).y() - polygonB.at(i-edgeCountA).y());
   2.200  		}
   2.201  
   2.202          // ===== 1. Find if the polygons are currently intersecting =====
   2.203  
   2.204 -
   2.205          // Find the axis perpendicular to the current edge
   2.206  
   2.207          QPointF axis (-edge.y(), edge.x());
   2.208 @@ -158,17 +213,15 @@
   2.209          // Find the projection of the polygon on the current axis
   2.210  
   2.211          qreal minA = 0; qreal minB = 0; qreal maxA = 0; qreal maxB = 0;
   2.212 -        ProjectPolygon(axis, polygonA, minA, maxA);
   2.213 -        ProjectPolygon(axis, polygonB, minB, maxB);
   2.214 +        projectPolygon(axis, polygonA, minA, maxA);
   2.215 +        projectPolygon(axis, polygonB, minB, maxB);
   2.216  
   2.217          // Check if the polygon projections are currentlty intersecting
   2.218  
   2.219 -        if (intervalDistance(minA, maxA, minB, maxB) > 0)
   2.220 -            result.intersect = false;
   2.221 -		else	
   2.222 -            result.intersect = true;
   2.223 +        qreal d = intervalDistance(minA, maxA, minB, maxB);
   2.224 +        if (d > 0) result.intersect = false;
   2.225  
   2.226 -        // ===== 2. Now find if the polygons *will* intersect =====
   2.227 +       // ===== 2. Now find if the polygons *will* intersect =====
   2.228  
   2.229  
   2.230          // Project the velocity on the current axis
   2.231 @@ -181,30 +234,25 @@
   2.232              minA += velocityProjection;
   2.233          else 
   2.234              maxA += velocityProjection;
   2.235 -        
   2.236  
   2.237          // Do the same test as above for the new projection
   2.238  
   2.239 -        qreal d = intervalDistance(minA, maxA, minB, maxB);
   2.240 -        if (d > 0) result.willIntersect = false;
   2.241 +        // d = intervalDistance(minA, maxA, minB, maxB);
   2.242 +        //if (d > 0) result.willIntersect = false;
   2.243  		/*
   2.244 -		*/
   2.245  		cout <<"   ";
   2.246 -		cout <<"minA="<<minA<<"  ";
   2.247 -		cout <<"maxA="<<maxA<<"  ";
   2.248 -		cout <<"minB="<<minB<<"  ";
   2.249 -		cout <<"maxB="<<maxB<<"  ";
   2.250 +		cout << "edge="<<edge<<"  ";
   2.251 +		cout <<"axis="<<axis<<"  ";
   2.252 +		cout <<"dA=("<<minA<<","<<maxA<<")  dB=("<<minB<<","<<maxB<<")";
   2.253  		cout <<"  d="<<d<<"   ";
   2.254 -		cout <<"minD="<<minIntervalDistance<<"  ";
   2.255 -		cout <<"axis="<<axis<<"  ";
   2.256 +		//cout <<"minD="<<minIntervalDistance<<"  ";
   2.257  		cout <<"int="<<result.intersect<<"  ";
   2.258 -		cout <<"wint="<<result.willIntersect<<"  ";
   2.259 +		//cout <<"wint="<<result.willIntersect<<"  ";
   2.260  		//cout <<"velProj="<<velocityProjection<<"  ";
   2.261  		cout <<endl;
   2.262 -
   2.263 -
   2.264 +		*/
   2.265  	
   2.266 -        if (result.intersect || result.willIntersect) 
   2.267 +        if (result.intersect )// || result.willIntersect) 
   2.268  		{
   2.269  			// Check if the current interval distance is the minimum one. If so
   2.270  			// store the interval distance and the current distance.  This will
   2.271 @@ -213,13 +261,13 @@
   2.272  			if (d<0) d=-d;
   2.273  			if (d < minIntervalDistance) {
   2.274  				minIntervalDistance = d;
   2.275 -				translationAxis = axis;
   2.276 -				cout << "tAxix="<<translationAxis<<endl;
   2.277 +				//translationAxis = axis;
   2.278 +				//cout << "tAxix="<<translationAxis<<endl;
   2.279  
   2.280  				//QPointF t = polygonA.Center - polygonB.Center;
   2.281 -				QPointF t = polygonA.at(0) - polygonB.at(0);
   2.282 -				if (dotProduct(t,translationAxis) < 0)
   2.283 -					translationAxis = -translationAxis;
   2.284 +				//QPointF t = polygonA.at(0) - polygonB.at(0);
   2.285 +				//if (dotProduct(t,translationAxis) < 0)
   2.286 +				//	translationAxis = -translationAxis;
   2.287  			}
   2.288  		}
   2.289      }
     3.1 --- a/geometry.h	Tue Aug 18 12:39:07 2009 +0000
     3.2 +++ b/geometry.h	Mon Aug 24 14:39:07 2009 +0000
     3.3 @@ -1,18 +1,32 @@
     3.4 -#ifndef GEOMETRY_H
     3.5 -#define GEOMETRY_H
     3.6 +#ifndef GEOMETRY
     3.7 +#define GEOMETRY
     3.8  
     3.9 -#include <QPointF>
    3.10 -#include <QRectF>
    3.11  #include <QPolygonF>
    3.12  
    3.13  QRectF addBBox(QRectF r1, QRectF r2);
    3.14  bool isInBox(const QPointF &p, const QRectF &box);
    3.15  
    3.16 +class ConvexPolygon:public QPolygonF
    3.17 +{
    3.18 +public:
    3.19 +	ConvexPolygon ();
    3.20 +	ConvexPolygon (QPolygonF p);
    3.21 +	void calcCentroid() ;
    3.22 +	QPointF centroid() const;
    3.23 +	qreal weight() const;
    3.24 +private:
    3.25 +	QPointF _centroid;
    3.26 +	qreal _area;
    3.27 +};
    3.28 +
    3.29  QPointF normalize (const QPointF &p);
    3.30  
    3.31  
    3.32  qreal dotProduct (const QPointF &a, const QPointF &b);
    3.33  
    3.34 +QPointF scale  (const QPointF &v,const qreal &f);
    3.35 +QPointF invert (const QPointF &v);
    3.36 +
    3.37  class PolygonCollisionResult {
    3.38  public:
    3.39      // Are the polygons going to intersect forward in time?
    3.40 @@ -26,9 +40,10 @@
    3.41  };
    3.42  
    3.43  
    3.44 -void ProjectPolygon(QPointF axis, QPolygonF polygon, qreal &min, qreal &max) ;
    3.45 +void projectPolygon(QPointF axis, QPolygonF polygon, qreal &min, qreal &max) ;
    3.46 +
    3.47  qreal intervalDistance(qreal minA, qreal maxA, qreal minB, qreal maxB);
    3.48 -PolygonCollisionResult PolygonCollision(QPolygonF polygonA, 
    3.49 +PolygonCollisionResult polygonCollision(QPolygonF polygonA, 
    3.50                                QPolygonF polygonB, QPointF velocity);
    3.51  
    3.52 -#endif
    3.53 +#endif
    3.54 \ No newline at end of file
     4.1 --- a/mainwindow.cpp	Tue Aug 18 12:39:07 2009 +0000
     4.2 +++ b/mainwindow.cpp	Mon Aug 24 14:39:07 2009 +0000
     4.3 @@ -1231,7 +1231,7 @@
     4.4  	
     4.5  	// Original: xsldbg_output.png
     4.6  	flag->load(flagsPath+"flag-info.png");
     4.7 -	setupFlag (flag,tb,"inflag",tr("Info","Standardflag"));
     4.8 +	setupFlag (flag,tb,"info",tr("Info","Standardflag"));
     4.9  
    4.10  	// Original khelpcenter.png
    4.11  	flag->load(flagsPath+"flag-lifebelt.png");
     5.1 --- a/misc.cpp	Tue Aug 18 12:39:07 2009 +0000
     5.2 +++ b/misc.cpp	Mon Aug 24 14:39:07 2009 +0000
     5.3 @@ -49,40 +49,6 @@
     5.4  	}	
     5.5  }
     5.6  
     5.7 -QPointF normalise(const QPointF &p)
     5.8 -{	
     5.9 -	// Calculate normalised position (fixed length) 
    5.10 -
    5.11 -	qreal px=p.x();
    5.12 -	qreal py=p.y();
    5.13 -	qreal x;
    5.14 -	qreal y;
    5.15 -	qreal r=150;
    5.16 -
    5.17 -	if (px==0)
    5.18 -	{
    5.19 -		x=0;
    5.20 -		if (py>=0)
    5.21 -			y=r;
    5.22 -		else
    5.23 -			y=-r;
    5.24 -	} else
    5.25 -	{
    5.26 -		qreal sign;
    5.27 -		qreal a;
    5.28 -		if (px>0) 
    5.29 -			sign=1; 
    5.30 -		else 
    5.31 -			sign=-1;
    5.32 -		
    5.33 -		a=atan (py / px);
    5.34 -		x=cos (a) * r *sign;
    5.35 -		y=sin (a) * r *sign;
    5.36 -	}	
    5.37 -	return QPoint ((int) (x),(int) (y));
    5.38 -}
    5.39 -
    5.40 -
    5.41  qreal max(qreal a, qreal b)
    5.42  {
    5.43  	if (a>b)
     6.1 --- a/misc.h	Tue Aug 18 12:39:07 2009 +0000
     6.2 +++ b/misc.h	Mon Aug 24 14:39:07 2009 +0000
     6.3 @@ -14,9 +14,6 @@
     6.4  extern ostream &operator<< (ostream &stream, QPoint const &p);
     6.5  extern ostream &operator<< (ostream &stream, QPointF const &p);
     6.6  qreal getAngle(const QPointF &);
     6.7 -QPointF normalise (const QPointF &);
     6.8  qreal max (qreal,qreal);
     6.9 -class BranchObj;
    6.10 -class MapEditor;
    6.11  
    6.12  #endif
     7.1 --- a/treemodel.cpp	Tue Aug 18 12:39:07 2009 +0000
     7.2 +++ b/treemodel.cpp	Mon Aug 24 14:39:07 2009 +0000
     7.3 @@ -66,14 +66,14 @@
     7.4      TreeItem *parentItem;
     7.5  
     7.6      if (!parent.isValid())
     7.7 -	{	//FIXME-1
     7.8 +	{	//FIXME-3 left here for testing only, seems to work now...
     7.9          parentItem = rootItem;
    7.10  		/*
    7.11  		cout << "TM::index()  no parent?! xxx\n";
    7.12  		cout << "   row="<<row<<"  col="<<column<<endl;
    7.13  		cout << "   parent.internal="<< parent.internalPointer()<<endl;
    7.14  		*/
    7.15 -		//return QModelIndex();	//FIXME-0 this line is new (testing)
    7.16 +		//return QModelIndex();	//FIXME-3 this line is new (testing)
    7.17  		// Somehow index is requested where parentIndex is invalid.
    7.18  		// what's happening here...?
    7.19  		// Check if Qt examples also return index of rootIem then...
     8.1 --- a/version.h	Tue Aug 18 12:39:07 2009 +0000
     8.2 +++ b/version.h	Mon Aug 24 14:39:07 2009 +0000
     8.3 @@ -7,7 +7,7 @@
     8.4  #define __VYM_VERSION "1.13.0"
     8.5  //#define __VYM_CODENAME "Codename: RC-1"
     8.6  #define __VYM_CODENAME "Codename: development version, not for production!"
     8.7 -#define __VYM_BUILD_DATE "2009-08-08"
     8.8 +#define __VYM_BUILD_DATE "2009-08-24"
     8.9  
    8.10  
    8.11  bool checkVersion(const QString &);