6 #include <QGraphicsPolygonItem> 8 #include <QApplication> 22 const QBrush FreeSpaceView::AREA_BRUSH1(QColor(Qt::blue).darker());
23 const QBrush FreeSpaceView::AREA_BRUSH2(Qt::blue);
25 const double FreeSpaceView::TF_MAX_ARG = 1e6;
26 const double CellView::MAX_DIAMETER = 1e5;
28 const QColor FreeSpaceView::LIGHT_GRAY (230,230,230);
29 const QColor FreeSpaceView::AREA_COLOR (228,37,72);
31 FreeSpaceView::FreeSpaceView(QWidget *parent)
32 :
BaseView(parent,
"Free-Space Diagram",false),
35 pathView(nullptr), select(nullptr),
38 GRID_PEN[
SOLID] = QPen(Qt::black, 0.5, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin);
39 GRID_PEN[
THIN] = QPen(Qt::black, 0.2, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin);
40 GRID_PEN[
DOTTED] = QPen(Qt::black, 0.5, Qt::DotLine, Qt::SquareCap, Qt::RoundJoin);
42 AREA_PEN = QPen(Qt::red, 0.5, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin);
43 BOUNDS_PEN = QPen(Qt::green, 0.5, Qt::DotLine, Qt::SquareCap, Qt::RoundJoin);
44 PATH_PEN = QPen(Qt::yellow, 2.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
47 view()->setMouseTracking(
true);
48 view()->viewport()->setMouseTracking(
true);
53 FreeSpace::ptr freeSpace = FrechetViewApplication::instance()->getFreeSpace();
54 for(
int i=0; i < freeSpace->n-1; ++i)
55 for(
int j=0; j < freeSpace->m-1; ++j)
56 delete cells->at(i,j);
61 Grid::ptr grid = FrechetViewApplication::instance()->getGrid();
62 FreeSpace::ptr freeSpace = FrechetViewApplication::instance()->getFreeSpace();
73 graphicsView->setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
77 QRectF r = grid->sceneRect();
90 for(
int i=0; i < freeSpace->n; ++i)
91 addGridLine( grid->verticalGridLine(i), grid->hor().lineStyle(i) );
93 for(
int j=0; j < freeSpace->m; ++j)
94 addGridLine( grid->horizontalGridLine(j), grid->vert().lineStyle(j) );
96 for(
int i=0; i < freeSpace->n-1; ++i)
97 for(
int j=0; j < freeSpace->m-1; ++j)
99 cells->at(i,j) = NULL;
107 if ((freeSpace->n > 0) && (freeSpace->m > 0))
113 scene->setSceneRect(r);
120 pathView =
new QGraphicsItemGroup();
124 select =
new QGraphicsPathItem();
125 select->setVisible(
false);
131 graphicsView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
136 for(
int i=0; i <
cells->n; ++i)
137 for(
int j=0; j <
cells->m; ++j)
141 scene->removeItem(cv);
163 FreeSpace::ptr freeSpace = FrechetViewApplication::instance()->getFreeSpace();
164 if (!freeSpace)
return;
171 QApplication::setOverrideCursor(Qt::WaitCursor);
173 freeSpace->calculateFreeSpace(eps);
178 freeSpace->calculateBounds(eps);
181 switch(FrechetViewApplication::instance()->currentAlgorithm())
183 case FrechetViewApplication::ALGORITHM_K_FRECHET:
185 freeSpace->components().calculateComponents(*freeSpace);
188 FrechetViewApplication::instance()->cancelBackgroundJob();
189 kalgorithm->runGreedy();
192 case FrechetViewApplication::ALGORITHM_CURVE:
194 freeSpace->components().clear();
196 path_ok = (bool)poly->decideCurve(freeSpace,fspath,NAN,
false);
200 case FrechetViewApplication::ALGORITHM_POLYGON:
202 freeSpace->components().clear();
204 switch (poly->status()) {
207 path_ok = (bool)poly->decideCurve(freeSpace,fspath,NAN,
false);
225 QApplication::restoreOverrideCursor();
230 FreeSpace::ptr freeSpace = FrechetViewApplication::instance()->getFreeSpace();
231 graphicsView->setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
234 Grid::ptr grid = FrechetViewApplication::instance()->getGrid();
237 int countEmpty=0, countEllipse=0, countPoly=0;
240 for(
int i=0; i < freeSpace->n-1; ++i)
241 for(
int j=0; j < freeSpace->m-1; ++j)
244 if (cl || ! freeSpace->cellEmptyBounds(i,j))
248 size_t comp = freeSpace->component(i,j);
249 if (FrechetViewApplication::instance()->currentAlgorithm(
250 FrechetViewApplication::ALGORITHM_K_FRECHET))
260 Q_ASSERT((i==0) || !freeSpace->cell(i,j).L || (comp==freeSpace->component(i-1,j)));
261 Q_ASSERT((j==0) || !freeSpace->cell(i,j).B || (comp==freeSpace->component(i,j-1)));
291 graphicsView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
304 Grid::ptr grid = FrechetViewApplication::instance()->getGrid();
310 QList<QGraphicsItem*> children =
pathView->childItems();
313 for(
int i=0; i < 2; ++i) {
314 Curve c = fspath->getPath(i);
315 c = grid->mapCurve(c);
318 for(
int j=0; j+1 < c.size(); ++j) {
319 QLineF line(c[j],c[j+1]);
320 if (k < children.size()) {
323 item->setVisible(
true);
336 for( ; k < children.size(); ++k)
337 children[k]->setVisible(
false);
347 FreeSpace::ptr freeSpace = FrechetViewApplication::instance()->getFreeSpace();
349 graphicsView->setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
354 for(
int i=0; i < freeSpace->n-1; ++i)
355 for(
int j=0; j < freeSpace->m-1; ++j)
358 if (cl || ! freeSpace->cellEmptyBounds(i,j))
362 if (FrechetViewApplication::instance()->currentAlgorithm()
363 ==FrechetViewApplication::ALGORITHM_K_FRECHET)
370 size_t comp = freeSpace->component(i,j);
387 graphicsView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
392 Grid::ptr grid = FrechetViewApplication::instance()->getGrid();
395 QRectF old_scene =
scene->sceneRect();
396 QRectF r = grid->sceneRect();
399 FrechetViewApplication::instance()->currentAlgorithm(
400 FrechetViewApplication::ALGORITHM_K_FRECHET))
423 scene->setSceneRect(r);
431 FreeSpace::ptr freeSpace = FrechetViewApplication::instance()->getFreeSpace();
433 for(
int i=0; i < freeSpace->n-1; ++i)
434 for(
int j=0; j < freeSpace->m-1; ++j)
437 if (cl || ! freeSpace->cellEmptyBounds(i,j))
441 size_t comp = freeSpace->component(i,j);
442 if (FrechetViewApplication::instance()->currentAlgorithm(
443 FrechetViewApplication::ALGORITHM_K_FRECHET))
447 if (!resultSet || resultSet->
contains(comp))
465 FreeSpace::ptr freeSpace = FrechetViewApplication::instance()->getFreeSpace();
466 Grid::ptr grid = FrechetViewApplication::instance()->getGrid();
468 Point s1 = freeSpace->P[i];
469 Point s2 = freeSpace->P[i+1];
471 Point t1 = freeSpace->Q[j];
472 Point t2 = freeSpace->Q[j+1];
478 double origx = grid->hor().map(i) - Point::dotProduct(s1-p0,dir1);
479 double origy = grid->vert().map(j) - Point::dotProduct(t1-p0,dir2);
481 double ang = Point::dotProduct(dir1,dir2);
482 double mu = 1.0/
sqrt(2*(1-ang));
483 double mv = 1.0/
sqrt(2*(1+ang));
485 return QTransform( mu, mu, -mv, mv, origx, origy );
503 return !std::isnan(x)
527 showResult(&kalgorithm->greedyResult().result);
533 showResult(&kalgorithm->optimalResult().result);
564 Grid::ptr grid = FrechetViewApplication::instance()->getGrid();
566 if (!fspath || fspath->empty() || !
pathView->isVisible())
586 Point q1 = fspath->mapFromP(a);
587 Point q2 = fspath->mapFromP(b);
588 double penw =
select->pen().widthF();
589 addPoint(path, grid->mapPoint(q1), penw);
590 addPoint(path, grid->mapPoint(q2), penw);
598 Point p1 = fspath->mapFromQ(a);
599 Point p2 = fspath->mapFromQ(b);
600 double penw =
select->pen().widthF();
601 addPoint(path, grid->mapPoint(p1), penw);
602 addPoint(path, grid->mapPoint(p2), penw);
606 Curve c = fspath->getPath(a);
607 mapped[0].push_back(c[b]);
608 mapped[0].push_back(c[b+1]);
609 Q_ASSERT((c[b].x() != c[b+1].x()) && (c[b].y() != c[b+1].y()));
632 Grid::ptr grid = FrechetViewApplication::instance()->getGrid();
633 double penw =
select->pen().widthF();
634 addPoint(path, grid->mapPoint(p), penw);
641 settings.beginGroup(group);
650 settings.beginGroup(group);
651 _showBounds = settings.value(
"show.bounds",
false).toBool();
661 : QGraphicsItemGroup(),
664 cellBounds(), clipShape(),
666 _ellipse(NULL), useEllipse(true),
670 Grid::ptr grid = FrechetViewApplication::instance()->getGrid();
686 _poly =
new QGraphicsPolygonItem(
this);
687 _poly->setPen(Qt::NoPen);
703 _ellipse =
new QGraphicsEllipseItem(
this);
717 _bounds[
i] =
new QGraphicsLineItem(
this);
730 for(
int i=0;
i < 4; ++
i)
731 if (bounds[
i].isNull()) {
764 QPen pen = item->pen();
765 if ((pen.style()!=Qt::NoPen) && (pen.color() != col)) {
773 for(
int i=0;
i < len; ++
i)
775 QPen pen = items[
i]->pen();
776 if ((pen.style()!=Qt::NoPen) && (pen.color() != col)) {
778 items[
i]->setPen(pen);
785 QBrush brush = item->brush();
786 if ((brush.style() != Qt::NoBrush) && (brush.color() != col)) {
788 item->setBrush(brush);
794 QPen pen = item->pen();
795 if (pen.style() != style) {
803 QPen pen = item->pen();
804 if (pen.style() != style) {
808 if (pen.widthF() != width) {
809 pen.setWidthF(width);
819 for (
int i=0;
i < 4; ++
i)
827 for(
int i=0;
i < 4; ++
i) {
842 removeFromGroup(
_poly);
843 scene()->removeItem(
_poly);
844 _poly->setVisible(
false);
853 setFlag(GraphicsItemFlag::ItemClipsToShape,
false);
854 setFlag(GraphicsItemFlag::ItemClipsChildrenToShape,
false);
862 _poly->setVisible(
true);
866 setFlag(GraphicsItemFlag::ItemClipsToShape,
true);
867 setFlag(GraphicsItemFlag::ItemClipsChildrenToShape,
true);
880 if (*item && !(*item)->isVisible()) {
888 bool any_bounds=
false;
889 for(
int i=0;
i < 4; ++
i) {
903 FreeSpace::ptr freeSpace = FrechetViewApplication::instance()->getFreeSpace();
908 if (freeSpace->cellEmptyBounds(
i,
j))
918 if (freeSpace->cellFull(
i,
j))
958 FreeSpace::ptr freeSpace = FrechetViewApplication::instance()->getFreeSpace();
959 QRectF r = freeSpace->segmentBounds(i,j);
961 if (r.left() > 0.0 && !std::isnan(r.height()))
962 result[0] =
boundsLine(r.bottomLeft(),r.topLeft(), i,j);
964 result[0] = QLineF();
966 if (r.right() < 1.0 && !std::isnan(r.height()))
967 result[1] =
boundsLine(r.bottomRight(),r.topRight(), i,j);
969 result[1] = QLineF();
971 if (r.top() > 0.0 && !std::isnan(r.width()))
972 result[2] =
boundsLine(r.topLeft(),r.topRight(), i,j);
974 result[2] = QLineF();
976 if (r.bottom() < 1.0 && !std::isnan(r.width()))
977 result[3] =
boundsLine(r.bottomLeft(),r.bottomRight(), i,j);
979 result[3] = QLineF();
986 const Interval& L = fspath->left(i,j);
987 const Interval& B = fspath->bottom(i,j);
988 const Interval& R = fspath->left(i+1,j);
989 const Interval& T = fspath->bottom(i,j+1);
994 QPointF(0.0, L.
lower()),
995 QPointF(0.0, L.
upper()), i,j);
997 result[0] = QLineF();
1002 QPointF(B.
lower(), 0.0),
1003 QPointF(B.
upper(), 0.0), i,j);
1005 result[1] = QLineF();
1011 QPointF(1.0,R.
lower()),
1012 QPointF(1.0,R.
upper()), i,j);
1014 result[2] = QLineF();
1020 QPointF(T.
lower(),1.0),
1021 QPointF(T.
upper(),1.0), i,j);
1023 result[3] = QLineF();
1031 Grid::ptr grid = FrechetViewApplication::instance()->getGrid();
1034 line.translate(i,j);
1035 return grid->mapLine(line);
1045 FreeSpace::ptr freeSpace = FrechetViewApplication::instance()->getFreeSpace();
1046 Grid::ptr grid = FrechetViewApplication::instance()->getGrid();
1050 const Interval& R = freeSpace->cell(
i+1,
j).L;
1053 const Interval& T = freeSpace->cell(
i,
j+1).B;
base class for view widgets.
Represents a polygon line segment from node i to j.
QGraphicsPolygonItem * _poly
content area may be a polygon (created on demand)
QGraphicsLineItem * _bounds[4]
boundary lines of the content area
virtual void segmentSelected(GraphicsHoverLineItem *item) override
called when the mouse hovers over a sensitve line item
void setColor(QColor areaColor, QColor borderColor=QColor())
update drawing colors
static void setPenStyle(QAbstractGraphicsShapeItem *item, Qt::PenStyle style)
update pen style (dotted,solid,...) of a graphics item
used for segments that are not mouse sensitive
void showOptimalResult()
show the optimal result of the k-Frechet (brute-force) algorithms. Highlights all components that are...
static bool validTransform(const QTransform &tf)
validity test for a transformation. If transform parameters become excessively large,...
QPen BOUNDS_PEN
pen for bounding rectangles
bool path_ok
true, if there is a feasible path
What
display mode; what is displayed? Flags can be combined (except Poly and Ellipse).
QGraphicsPathItem * select
highlighted line segment (or nullptr)
void addGridLine(QLineF line, LineStyle style)
add a grid line to the graphics scene
input data have been successfully processed, the algorithm is now ready to execute
static const QColor LIGHT_GRAY
used for disabled components (k-Frechet)
FreeSpaceView * parent
pointer to parent
bool _showBounds
true, if bounding rectangle are shown
Point normalized(Point p)
normalize a vector to unit length
void dropUnusedItem(QGraphicsItem **item)
release an unused item
negative result of the decision version
QGraphicsView * view() const
QGraphicsEllipseItem * getEllipse()
global definitions for all algorithms.
bool useEllipse
true if an ellipse is to be shown
input data are faulty. P is convex.
IntervalView * intervalView[2]
k-Frechet: show component intervals below and to the left
void clear()
remove all entries from the map
positive result of the decision version
static void setBoundsPenColor(QGraphicsLineItem **bounds, int len, QColor col)
update pen color of several graphics item
display a clipped ellipse
the algorithm is currently computing (decision variant, or optimisation variant)
void hiliteSegment(int loc, int a, int b)
raised when the mouse moves over a highlighted segment This signal triggers the display of associated...
boost::shared_ptr< Algorithm > ptr
(smart) pointer to an Algorithm object
void populateScene()
create the grid lines and an array of CellView objects
a segment of the feasible paht (displayed in the free-space diagram)
void createReachabilityRect(int i, int j, QLineF result[4])
create a set of line segments for reachability intervals
QGraphicsItemGroup * pathView
the feasible path
void onHiliteSegment(int loc, int a, int b)
highlight a segment of the feasible path
CellView(FreeSpaceView *parent, int i, int j)
default constructor
static const QColor AREA_COLOR
color for content area (except k-Frechet)
Display k-Frechet intervals, i.e. projections of connected components to the domain axes.
static const QBrush AREA_BRUSH2
brush (fill color) for content area
display the free-space diagram.
boost::shared_ptr< Matrix > MatrixPtr
pointer to an array of cell views
static void addPolygon(QPainterPath &ppath, const QPolygonF &poly)
add a polygon curve segment to a QPainterPath
QGraphicsLineItem * getBounds(int i)
Float sqrt(const Float &x)
square-root function template for floating point types
void setBounds(QLineF bounds[4])
update bounding rectangle
void setupMatrix()
set up transformation matrix to account for zoom,rotate,scroll
const Location loc
location on screen
void onAlgorithmChanged(int alg)
updatee free-space diagram when a new algorithm is selected. For example, for the k-Frechet algorithm...
QPainterPath clipShape
shape used for clipping ellipses
void updateBounds()
update bounding rectangles
void createBoundsRect(int i, int j, QLineF result[4])
create a boundary rectangle for a cell
QGraphicsScene * scene
scene that is displayed by graphicsView
QPen PATH_PEN
pen for feasible path
QGraphicsPolygonItem * getPoly()
static const QPen PEN_SELECT
pen for drawing selected polygon segment
QPolygonF createPolygon(int i, int j, bool *thin)
create a polygon that draws the content area
GraphicsHoverLineItem * selected_item
the currently selected mouse sensitve polyon segment (or nullptr)
void showGreedyResult()
show the result of the k-Frechet greedy algorithms. Highlights all components that are part of the so...
a QGraphicsLitem that can handle mouse hover events. It is used to highlight mouse sensitve polygon s...
int i
column index in free-space grid
virtual ~FreeSpaceView()
destructor; releases all items
display polygon plus bounding rect
void update(int a, int b)
update identifiers
QTransform createEllipseTransform(int i, int j)
compute the transformation for drawing an ellipse
QPointF Point
a point in the plane; with double floating point precision. This type is heavily used throughout all ...
void hideResult()
hide results of the k-Frechet algorithms. Remove gray-out, display all components in their original c...
bool contains(int offset) const
void flipVertical(bool flip)
flip graphics scene vertically
Point intersection(Point p1, Point p2, Point p3, Point p4)
compute the intersection of two lines
boost::shared_ptr< FSPath > ptr
smart pointer to an FSPath object
bool dropUnusedItems()
release graphics items that are not currently displayed
enum frechet::view::CellView::What what
QRectF cellBounds
bounding rectangle
static void addPoint(QPainterPath &ppath, const QPointF &point, double diameter=1.0)
add a dot to a QPainterPath
void update(double eps, bool showBounds, QLineF bounds[4])
update display
virtual void dropUnusedItems() override
release graphics items that are currently not drawn implements empty method from super-class
const int a
parameters loc,a, and b identify a segment.
static void setPenStyleWidth(QAbstractGraphicsShapeItem *item, Qt::PenStyle style, float width)
update pen style and pen width of a graphics item
QPen AREA_PEN
pen for content area
QPolygonF Curve
a polygonal curve in the plane; with double floating point precision. This type is heavily used throu...
QLineF boundsLine(QPointF a, QPointF b, int i, int j)
calculates one boundary line
void curveFinished(bool yes)
raised when after decision variant of the curve algorithm
A simple two-dimensional array of fixed size.
virtual void restoreSettings(QSettings &settings, QString group)
load settings from application preferences
void showResult(const frechet::data::BitSet *resultSet)
highlight result set of a k-Frechet algorithm. All intervals that are not part of the result set are ...
double min(double a, double b)
minimum function with checks for NAN
void dodraw(What what)
update content
virtual void restoreSettings(QSettings &settings, QString group)
load view settings to application prefs
static const double TF_MAX_ARG
max. value for affine transforms
CellView * getCellView(int i, int j)
get a free-space cell view
virtual ~CellView()
destructor
boost::shared_ptr< Grid > ptr
smart pointer to a Grid object
display ellipse plus bounding rect
void addAll(const k::IntervalMap &mvals)
add a set of intervals
virtual void saveSettings(QSettings &settings, QString group)
store settings to application preferences
static void setBrushColor(QAbstractGraphicsShapeItem *item, QColor col)
update brush (fill) color of a graphics item
A simple bit vector of fixed size.
QGraphicsView * graphicsView
the embedded QGraphicsView
displays one cell of the free-space diagram.
empty cell. display nothing
LineStyle
display style of grid lines in free-space diagram
void showPath(bool show)
show or hide feasible path
static bool validTransformArg(double x)
validity test for a transformation
static const double OPACITY
static void setPenColor(QAbstractGraphicsShapeItem *item, QColor col)
update pen (edge) color of a graphics item
virtual void saveSettings(QSettings &settings, QString group)
store view settings to application prefs
int j
row index in free-space grid
input data are faulty. Q is convex.
void updateIntervals()
update component intervals (k-Frechet only)
CellView::MatrixPtr cells
free space areas for all cells (i,j)
boost::shared_ptr< kAlgorithm > ptr
smart pointer to an kAlgorithm object
an interval of two double values.
QGraphicsEllipseItem * _ellipse
void doHiliteSegment(GraphicsHoverLineItem::Location loc, int a, int b)
highlight a line segment
static const component_id_t NO_COMPONENT
empty cells have an invalid component ID
Number abs(const Number &x)
abs() function template for arbitrary numerical types
Location
location of the polygon segment
bool valid() const
validity test
void hilitePoint(QPointF p)
hilite on point inf the diagram (used for animation only)
boost::shared_ptr< FreeSpace > ptr
smart pointer to FreeSpace object
void clear()
remove all intervals
void updateView(double eps)
update free-space view in response to a change of epsilon
void showResult(const data::BitSet *resultSet)
show the result of a k-Frechet algorithm
double max(double a, double b)
maximum function with checks for NAN
static void setPenWidth(QGraphicsItem *item, double width)
update the pen width of a graphics item
void calculateFreeSpace(double epsilon)
update free-space diagram when epsilon changes. If the curve algorithm is selected,...