# HG changeset patch # User insilmaril # Date 1252412139 0 # Node ID 7d67be709091158d00c2f68dc5863892602d991a # Parent f1006de05c5453d4d6706c498ca17f6cb38f6cb5 First results in moving colliding MapCenters apart diff -r f1006de05c54 -r 7d67be709091 branchobj.cpp --- a/branchobj.cpp Mon Sep 07 15:36:57 2009 +0000 +++ b/branchobj.cpp Tue Sep 08 12:15:39 2009 +0000 @@ -143,7 +143,9 @@ if (parObj->getTreeItem()->depth()==0) { // new parent is a mapcenter - QPointF p= normalize ( QPointF (m.x() - o->getChildPos().x(), + //FIXME-2 rewrite to us new normalize QPointF p= normalize ( QPointF (m.x() - o->getChildPos().x(), + // m.y() - o->getChildPos().y() )); + QPointF p= ( 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 f1006de05c54 -r 7d67be709091 branchobj.h --- a/branchobj.h Mon Sep 07 15:36:57 2009 +0000 +++ b/branchobj.h Tue Sep 08 12:15:39 2009 +0000 @@ -6,7 +6,6 @@ #include "ornamentedobj.h" #include "xlinkobj.h" - bool isAbove(BranchObj*,BranchObj*); /*! \brief A branch visible in the map */ diff -r f1006de05c54 -r 7d67be709091 geometry.cpp --- a/geometry.cpp Mon Sep 07 15:36:57 2009 +0000 +++ b/geometry.cpp Tue Sep 08 12:15:39 2009 +0000 @@ -3,6 +3,8 @@ #include <math.h> #include "misc.h" +#include <QString> + #include <iostream> using namespace std; @@ -46,6 +48,48 @@ return false; } +Vector::Vector ():QPointF () +{ +} + +Vector::Vector (const QPointF &p):QPointF (p) +{ +} + +Vector::Vector (qreal x, qreal y):QPointF (x,y) +{ +} + +//! Normalize vector +void Vector::normalize () +{ + if (x()==0 && y()==0) return; + qreal l=sqrt ( x()*x() + y()*y() ); + setX (x()/l); + setY (y()/l); +} + +//! Dot product of two vectors +qreal Vector::dotProduct (const QPointF &b) +{ + return x()*b.x() + y()*b.y(); +} + + +void Vector::scale (const qreal &f) +{ + setX (x()*f); + setY (y()*f); +} + +void Vector::invert () +{ + setX (-x()); + setY (-y()); +} + +/*! Calculate the projection of a polygon on an axis + and returns it as a [min, max] interval */ ConvexPolygon::ConvexPolygon () { } @@ -89,45 +133,43 @@ return _area; } -//! Normalize vector -QPointF normalize (const QPointF &p) +std::string ConvexPolygon::toStdString() { - if (p==QPointF(0,0)) return p; - qreal l=sqrt ( p.x()*p.x() + p.y()*p.y() ); - return QPointF (p.x()/l,p.y()/l); + QString s ("("); + for (int i=0;i<size();++i) + { + s+=QString("(%1,%2)").arg(at(i).x()).arg(at(i).y()); + if (i<size()-1) s+=","; + } + s+=")"; + return s.toStdString(); } -//! Dot product of two vectors -qreal dotProduct (const QPointF &a, const QPointF &b) +Vector ConvexPolygon::at(const int &i) const { - return a.x()*b.x() + a.y()*b.y(); + return Vector (QPolygonF::at(i).x(),QPolygonF::at(i).y()); } +void ConvexPolygon::translate ( const Vector & offset ) +{ translate (offset.x(),offset.y());} -QPointF scale (const QPointF &v,const qreal &f) +void ConvexPolygon::translate ( qreal dx, qreal dy ) { - return QPointF (v.x()*f,v.y()*f); + QPolygonF::translate (dx,dy); + _centroid=_centroid+QPointF (dx,dy); } -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) +void projectPolygon(Vector axis, ConvexPolygon 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)); + qreal d = axis.dotProduct(polygon.at(0)); min = d; max = d; for (int i = 0; i < polygon.size(); i++) { - d= dotProduct (polygon.at(i),axis); + d= polygon.at(i).dotProduct (axis); if (d < min) min = d; else @@ -153,8 +195,8 @@ of the polygons (i.e. velocityA - velocityB) */ -PolygonCollisionResult polygonCollision(QPolygonF polygonA, - QPolygonF polygonB, QPointF velocity) +PolygonCollisionResult polygonCollision(ConvexPolygon polygonA, + ConvexPolygon polygonB, Vector velocity) { PolygonCollisionResult result; result.intersect = true; @@ -207,8 +249,8 @@ // Find the axis perpendicular to the current edge - QPointF axis (-edge.y(), edge.x()); - axis=normalize(axis); + Vector axis (-edge.y(), edge.x()); + axis.normalize(); // Find the projection of the polygon on the current axis @@ -226,7 +268,7 @@ // Project the velocity on the current axis - qreal velocityProjection = dotProduct(axis,velocity); + qreal velocityProjection = axis.dotProduct(velocity); // Get the projection of polygon A during the movement diff -r f1006de05c54 -r 7d67be709091 geometry.h --- a/geometry.h Mon Sep 07 15:36:57 2009 +0000 +++ b/geometry.h Tue Sep 08 12:15:39 2009 +0000 @@ -6,6 +6,23 @@ QRectF addBBox(QRectF r1, QRectF r2); bool isInBox(const QPointF &p, const QRectF &box); + +class Vector:public QPointF +{ +public: + Vector (); + Vector (const QPointF &p); + Vector (qreal x, qreal y); + + friend inline bool operator==(const Vector &v1, const Vector &v2 ) + { return v1.x()==v2.x() && v1.y()==v2.y(); } + + virtual void normalize (); + virtual qreal dotProduct (const QPointF &b); + virtual void scale (const qreal &f); + virtual void invert (); +}; + class ConvexPolygon:public QPolygonF { public: @@ -14,19 +31,15 @@ void calcCentroid() ; QPointF centroid() const; qreal weight() const; + std::string toStdString (); + Vector at (const int &i) const ; + virtual void translate ( const Vector &offset ); + virtual void translate ( qreal dx, qreal dy ); private: - QPointF _centroid; + Vector _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? @@ -40,10 +53,10 @@ }; -void projectPolygon(QPointF axis, QPolygonF polygon, qreal &min, qreal &max) ; +void projectPolygon(Vector axis, ConvexPolygon polygon, qreal &min, qreal &max) ; qreal intervalDistance(qreal minA, qreal maxA, qreal minB, qreal maxB); -PolygonCollisionResult polygonCollision(QPolygonF polygonA, - QPolygonF polygonB, QPointF velocity); +PolygonCollisionResult polygonCollision(ConvexPolygon polygonA, + ConvexPolygon polygonB, Vector velocity); #endif \ No newline at end of file diff -r f1006de05c54 -r 7d67be709091 mainwindow.cpp --- a/mainwindow.cpp Mon Sep 07 15:36:57 2009 +0000 +++ b/mainwindow.cpp Tue Sep 08 12:15:39 2009 +0000 @@ -3595,7 +3595,7 @@ void Main::testFunction2() { if (!currentMapEditor()) return; - currentMapEditor()->setFocus(); + currentMapEditor()->testFunction2(); } void Main::testCommand() diff -r f1006de05c54 -r 7d67be709091 mapeditor.cpp --- a/mapeditor.cpp Mon Sep 07 15:36:57 2009 +0000 +++ b/mapeditor.cpp Tue Sep 08 12:15:39 2009 +0000 @@ -7,6 +7,7 @@ #include <QObject> #include "branchitem.h" +#include "geometry.h" #include "mainwindow.h" #include "misc.h" #include "warningdialog.h" @@ -545,10 +546,6 @@ } cout <<" hidemode="<<hidemode<<endl; */ -} - -void MapEditor::testFunction2() -{ /* // Toggle hidemode @@ -557,6 +554,73 @@ else setHideTmpMode (HideExport); */ + +} + +void MapEditor::testFunction2() +{ + // Create list with all bounding polygons + QList <MapObj*> mapobjects; + QList <ConvexPolygon> polys; + QList <Vector> vectors; + QList <Vector> orgpos; + BranchItem *bi; + BranchObj *bo; + TreeItem *ri=model->getRootItem(); + for (int i=0;i<ri->branchCount();++i) + { + bi=ri->getBranchNum (i); + bo=(BranchObj*)bi->getLMO(); + if (bo) + { + mapobjects.append (bo); + polys.append(bo->getBoundingPolygon()); + polys[i].calcCentroid(); + vectors.append (QPointF(0,0)); + orgpos.append (polys[i].at(0)); + } + } + + // Iterate moving bounding polygons until we have no more collisions + int collisions=1; + while (collisions>0) + { + collisions=0; + for (int i=0; i<polys.size()-1; ++i) + { + for (int j=i+1; j<polys.size();++j) + { + if (polygonCollision (polys.at(i),polys.at(j), QPointF(0,0)).intersect ) + { + collisions++; + Vector v=polys.at(j).centroid()-polys.at(i).centroid(); + // Move also away if centroids are identical + if (v.isNull()) + { + v.setX (rand()%200 -100); + v.setY (rand()%200 -100); + } + v.normalize(); + cout << "v="<<v<<endl; + v.scale (2); + vectors[j]=v; + vectors[i]=v; + vectors[i].invert(); + } + } + } + for (int i=0;i<vectors.size();i++) + polys[i].translate (vectors[i]); + //cout << "Collisions: "<<collisions<<endl; + } + + // Finally move the real objects and update + for (int i=0;i<polys.size();i++) + { + Vector v=polys[i].at(0)-orgpos[i]; + mapobjects[i]->moveBy(v.x(),v.y() ); + } + model->reposition(); } BranchItem* MapEditor::getBranchDirectAbove (BranchItem *bi) @@ -1050,8 +1114,8 @@ if ( e->modifiers()==Qt::ShiftModifier && dsti && dsti != seli->parent() ) { // Also save the move which was done so far - QString pold=qpointfToString(movingObj_orgRelPos); - QString pnow=qpointfToString(fio->getRelPos()); + QString pold=qpointFToString(movingObj_orgRelPos); + QString pnow=qpointFToString(fio->getRelPos()); model->saveState( seli, "moveRel "+pold, @@ -1205,8 +1269,8 @@ if(fio) { // Moved FloatObj. Maybe we need to reposition - QString pold=qpointfToString(movingObj_orgRelPos); - QString pnow=qpointfToString(fio->getRelPos()); + QString pold=qpointFToString(movingObj_orgRelPos); + QString pnow=qpointFToString(fio->getRelPos()); model->saveState( seli, "moveRel "+pold, @@ -1225,8 +1289,8 @@ { if (movingObj_orgPos != bi->getBranchObj()->getAbsPos()) // FIXME-3 check getBO here... { - QString pold=qpointfToString(movingObj_orgPos); - QString pnow=qpointfToString(bi->getBranchObj()->getAbsPos()); // FIXME-3 check getBO here... + QString pold=qpointFToString(movingObj_orgPos); + QString pnow=qpointFToString(bi->getBranchObj()->getAbsPos()); // FIXME-3 check getBO here... model->saveState( bi, @@ -1311,9 +1375,9 @@ QPointF rp(lmosel->getRelPos()); if (rp != movingObj_orgRelPos) { - QString ps=qpointfToString(rp); + QString ps=qpointFToString(rp); model->saveState( - model->getSelectString(lmosel), "moveRel "+qpointfToString(movingObj_orgRelPos), + model->getSelectString(lmosel), "moveRel "+qpointFToString(movingObj_orgRelPos), preSelStr, "moveRel "+ps, QString("Move %1 to relative position %2").arg(model->getObjectName(lmosel)).arg(ps)); } diff -r f1006de05c54 -r 7d67be709091 mapobj.cpp --- a/mapobj.cpp Mon Sep 07 15:36:57 2009 +0000 +++ b/mapobj.cpp Tue Sep 08 12:15:39 2009 +0000 @@ -90,7 +90,7 @@ QString MapObj::getPos() { - return qpointfToString(absPos); + return qpointFToString(absPos); } void MapObj::move (double x, double y) @@ -120,6 +120,13 @@ return bbox; } +ConvexPolygon MapObj::getBoundingPolygon() +{ + QPolygonF p; + p<<bbox.topLeft()<<bbox.topRight()<<bbox.bottomRight()<<bbox.bottomLeft(); + return p; +} + QRectF MapObj::getClickBox() { return clickBox; diff -r f1006de05c54 -r 7d67be709091 mapobj.h --- a/mapobj.h Mon Sep 07 15:36:57 2009 +0000 +++ b/mapobj.h Tue Sep 08 12:15:39 2009 +0000 @@ -16,6 +16,7 @@ #define Z_TEXT 100 #define Z_LINEEDIT 110 +class ConvexPolygon; class TreeItem; @@ -40,26 +41,27 @@ virtual qreal width(); virtual qreal height(); virtual QPointF getAbsPos(); - virtual QString getPos(); // Return position as string (x,y) - virtual void move (double x,double y); // move to absolute Position + virtual QString getPos(); //! Return position as string (x,y) + virtual void move (double x,double y); //! move to absolute Position virtual void move (QPointF p); - virtual void moveBy (double x,double y); // move to relative Position - virtual QRectF getBBox(); // returns bounding box - virtual QRectF getClickBox(); // returns box to click + virtual void moveBy (double x,double y); //! move to relative Position + virtual QRectF getBBox(); //! returns bounding box + virtual ConvexPolygon getBoundingPolygon(); //! return bounding convex polygon + virtual QRectF getClickBox(); //! returns box to click virtual bool isInClickBox (const QPointF &p); //! Checks if p is in clickBox - virtual QSizeF getSize(); // returns size of bounding box + virtual QSizeF getSize(); //! returns size of bounding box virtual bool isVisibleObj(); virtual void setVisibility(bool); virtual void positionBBox()=0; virtual void calcBBoxSize()=0; protected: QGraphicsScene* scene; - QRectF bbox; // bounding box of MO itself - QRectF clickBox; // area where mouseclicks are found - QPointF absPos; // Position on canvas + QRectF bbox; // bounding box of MO itself + QRectF clickBox; // area where mouseclicks are found + QPointF absPos; // Position on canvas bool visible; - TreeItem *treeItem; // Crossrefence to treemodel + TreeItem *treeItem; //! Crossrefence to treemodel }; diff -r f1006de05c54 -r 7d67be709091 misc.cpp --- a/misc.cpp Mon Sep 07 15:36:57 2009 +0000 +++ b/misc.cpp Tue Sep 08 12:15:39 2009 +0000 @@ -1,20 +1,21 @@ #include <math.h> #include <qregexp.h> -#include <qpoint.h> +//#include <qpoint.h> #include <stdlib.h> #include "misc.h" +#include "geometry.h" + QString qpointToString (const QPoint &p) -{ - return "(" + QString("%1").arg(p.x()) +","+ QString ("%1").arg (p.y()) +")"; -} +{ return "(" + QString("%1").arg(p.x()) +","+ QString ("%1").arg (p.y()) +")"; } -QString qpointfToString (const QPointF &p) -{ - return "(" + QString("%1").arg(p.x()) +","+ QString ("%1").arg (p.y()) +")"; -} +QString qpointFToString (const QPointF &p) +{ return "(" + QString("%1").arg(p.x()) +","+ QString ("%1").arg (p.y()) +")"; } + +QString VectorToString (const Vector &p) +{ return "(" + QString("%1").arg(p.x()) +","+ QString ("%1").arg (p.y()) +")"; } ostream &operator<< (ostream &stream, QPoint const &p) { @@ -28,6 +29,12 @@ return stream; } +ostream &operator<< (ostream &stream, Vector const &p) +{ + stream << "("<<p.x()<<","<<p.y()<<")"; + return stream; +} + qreal getAngle(const QPointF &p) { // Calculate angle of vector to y-axis diff -r f1006de05c54 -r 7d67be709091 misc.h --- a/misc.h Mon Sep 07 15:36:57 2009 +0000 +++ b/misc.h Tue Sep 08 12:15:39 2009 +0000 @@ -1,18 +1,23 @@ #ifndef MISC_H #define MISC_H -#include <qpoint.h> -#include <qdir.h> #include <iostream> - using namespace std; +class QString; +class QPoint; +class QPointF; +class Vector; ///////////////////////////////////////////////////////////////////////////// QString qpointToString (const QPoint &p); -QString qpointfToString (const QPointF &p); +QString qpointFToString (const QPointF &p); +QString VectorToString (const Vector &p); + + extern ostream &operator<< (ostream &stream, QPoint const &p); extern ostream &operator<< (ostream &stream, QPointF const &p); +extern ostream &operator<< (ostream &stream, Vector const &p); qreal getAngle(const QPointF &); qreal max (qreal,qreal); diff -r f1006de05c54 -r 7d67be709091 version.h --- a/version.h Mon Sep 07 15:36:57 2009 +0000 +++ b/version.h Tue Sep 08 12:15:39 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-09-07" +#define __VYM_BUILD_DATE "2009-09-08" bool checkVersion(const QString &); diff -r f1006de05c54 -r 7d67be709091 vymmodel.cpp --- a/vymmodel.cpp Mon Sep 07 15:36:57 2009 +0000 +++ b/vymmodel.cpp Tue Sep 08 12:15:39 2009 +0000 @@ -2341,15 +2341,13 @@ "delete ()", QString("Delete %1").arg(getObjectName(ti)) ); + unselect(); + deleteItem (ti); + emitDataHasChanged (pi); + select (pi); + reposition(); + emitShowSelection(); } - // FIXME-1 savestate missing for deletion of other types than above - unselect(); - deleteItem (ti); - emitDataHasChanged (pi); - select (pi); - reposition(); - emitShowSelection(); - return; } } @@ -4028,6 +4026,7 @@ for (int i=0;i<rootItem->branchCount(); i++) rootItem->getBranchObjNum(i)->reposition(); // for positioning heading + emitSelectionChanged(); } /* diff -r f1006de05c54 -r 7d67be709091 xml-vym.cpp --- a/xml-vym.cpp Mon Sep 07 15:36:57 2009 +0000 +++ b/xml-vym.cpp Tue Sep 08 12:15:39 2009 +0000 @@ -145,7 +145,7 @@ { // Treat the found mapcenter as a branch // in an existing map - BranchItem *bi=model->getSelectedBranch(); //FIXME-3 selection is no longer used here... //FIXME-2 really? we are adding to a map... + BranchItem *bi=model->getSelectedBranch(); //FIXME-2 selection is no longer used here... if (bi) { lastBranch=bi; @@ -153,7 +153,7 @@ { lastBranch=model->createBranch(lastBranch); } //else - //lastBranch->clear(); //FIXME-1 clear not really defined! + //lastBranch->clear(); //FIXME-2 clear not really defined! } else // add mapCenter without parent lastBranch=model->createMapCenter();