54 #include <QLinkedList>
63 #include "graphicsScene.hh"
64 #include "elementArea.hh"
65 #include "sceneElement.hh"
66 #include "connection.hh"
67 #include "elementInput.hh"
68 #include "elementOutput.hh"
70 #define PAIR(p) QPair<int,int>((p).x (),(p).y ())
94 foreach (
Node *n, nodes_)
104 QRect bb = scene_->
elementArea ()->childrenBoundingRect ().toRect ().adjusted (-100, -100, 100, 100);
111 eR += e->mapRectToParent (e->boundingRect ()).toRect ().adjusted (-15,-15,15,15);
118 if (c->
way ().isEmpty ())
120 QPoint p1 = c->
way ().first ().toPoint ();
122 for (
int i = 1; i < c->
way ().size (); i++)
124 p2 = c->
way ()[i].toPoint ();
125 eR += QRect (qMin (p1.x (), p2.x ()), qMin (p1.y (), p2.y ()), abs (p1.x () - p2.x ()), abs (p1.y () - p2.y ())).adjusted (-2, -2, 2, 2);
133 if (c->
way ().isEmpty ())
135 QPoint p1 = c->
way ().first ().toPoint ();
137 for (
int i = 1; i < c->
way ().size (); i++)
139 p2 = c->
way ()[i].toPoint ();
140 eR += QRect (qMin (p1.x (), p2.x ()), qMin (p1.y (), p2.y ()), abs (p1.x () - p2.x ()), abs (p1.y () - p2.y ())).adjusted (-4, -4, 4, 4);
151 int x1 = (_from.x () / step) * step;
152 int y1 = (_from.y () / step) * step;
153 int x2 = (_to.x () / step) * step;
154 int y2 = (_to.y () / step) * step;
156 QPoint newTo = QPoint (x2, y2);
159 if (_from.x () != _to.x () && x1 == x2)
161 if (_from.x () > _to.x ())
167 if (_from.y () != _to.y () && y1 == y2)
169 if (_from.y () > _to.y ())
176 Node *n = NULL, *tmp, *tmp2, *lastIn = 0;
179 if (_from == oldFrom_ && eR == oldReg_)
181 if (map_.contains (PAIR(newTo)))
183 n = map_[PAIR(newTo)];
184 if (n->closed_ && n->counter_ == counter_)
195 if (!map_.contains (QPair<int,int>(x1, y1)))
197 ll_ =
new Node (counter_);
200 ll_->pos_ = QPoint (x1, y1);
201 map_.insert (QPair<int,int>(x1, y1), ll_);
203 for (
unsigned int k = 0; k < 4; k++)
205 QPoint p2 = validPos (k, step, ll_->pos_);
207 if (map_.contains (PAIR(p2)))
209 ll_->n_[k] = map_[PAIR(p2)];
210 map_[PAIR(p2)]->n_[(k + 2) & 3] = ll_;
216 ll_ = map_[QPair<int,int>(x1, y1)];
217 ll_->counter_ = counter_;
222 ll_->closed_ =
false;
227 ll_->h_ = heuristicDistance (_from, _to);
228 ll_->type_ = Node::Horizontal;
232 while (ll_ && !found)
243 if (n->pos_.y () == y2 && n->pos_.x () == x2)
250 for (
unsigned int i = 0; i < 4; i++)
253 QPoint p = validPos (i, step, n->pos_);
261 nn->n_[(i + 2) & 3] = n;
263 nn->h_ = heuristicDistance (p, newTo);
268 map_.insert (PAIR(nn->pos_), nn);
270 for (
unsigned int j = 0; j < 3; j++)
272 unsigned int k = (i - 1 + j) & 3;
273 QPoint p2 = validPos (k, step, p);
275 if (map_.contains (PAIR(p2)))
277 nn->n_[k] = map_[PAIR(p2)];
278 map_[PAIR(p2)]->n_[(k + 2) & 3] = nn;
283 else if (n->n_[i]->counter_ != counter_)
286 tmp->counter_ = counter_;
293 tmp->closed_ =
false;
294 if (eR.contains (tmp->pos_))
298 tmp->h_ = heuristicDistance (tmp->pos_, newTo);
302 for (
unsigned int i = 0; i < 4; i++)
307 if (n->n_[i]->closed_)
312 unsigned int g = n->g_;
315 if ((n->type_ == Node::Horizontal && (i & 1)) || (n->type_ == Node::Vertical && (i & 1) == 0))
323 tmp->type_ = (i & 1)? Node::Horizontal : Node::Vertical;
326 tmp->f_ = g + tmp->h_;
330 tmp->prev_->next_ = tmp->next_;
332 tmp->next_->prev_ = tmp->prev_;
337 if (!ll_ || tmp->f_ <= ll_->f_)
347 if (lastIn && lastIn->f_ <= tmp->f_ && lastIn != tmp)
351 while (tmp2->next_ && tmp2->next_->f_ < tmp->f_)
353 tmp->next_ = tmp2->next_;
355 tmp->next_->prev_ = tmp;
371 if (n->pos_.y () != n->from_->pos_.y ())
374 int lastX = n->pos_.x ();
375 int lastY = n->pos_.y ();
381 if (dir && n->pos_.y () != lastY)
384 lastX = n->pos_.x ();
385 lastY = n->pos_.y ();
387 last = QPoint (n->pos_.x (), last.y ());
389 else if (!dir && n->pos_.x () != lastX)
392 lastX = n->pos_.x ();
393 lastY = n->pos_.y ();
395 last = QPoint (last.x (), n->pos_.y ());
402 last.setY (_from.y ());
404 last.setX (_from.x ());
406 rv.append(QPointF (last));
407 rv.append(QPointF (_from));
411 rv.append(QPointF (_from));
412 rv.append(QPointF (_to));
413 std::cerr <<
"Not Found" << std::endl;
428 WayFind::Node::Node(
unsigned int _counter) :
449 WayFind::Node::~ Node()
456 QPoint WayFind::validPos(
unsigned int _dir,
int _step, QPoint _pnt)
460 if (_dir == 0 || _dir == 3)
463 if (_dir == 1 || _dir == 3)
464 rv += QPoint (_step, 0);
466 rv += QPoint (0, _step);
474 int WayFind::heuristicDistance(
const QPoint &_from,
const QPoint &_to)
const
476 QPoint p = _from - _to;
477 return abs (p.x ()) + abs (p.y ());
483 void VSI::WayFind::cleanup()
486 if ((counter_ & 0x7f) != 0)
489 QLinkedList<Node *>::iterator it = nodes_.begin();
491 while (it != nodes_.end ())
495 if (counter_ - n->counter_ > 64)
497 for (
unsigned int i = 0; i < 4; i++)
499 n->n_[i]->n_[(i+2)&3] = NULL;
500 it = nodes_.erase(it);
501 map_.remove (PAIR(n->pos_));
QVector< ElementInput * > inputs()
Inputs.
const QList< SceneElement * > & elements() const
Scene elements.
WayFind(GraphicsScene *_scene)
Constructor.
QList< Connection * > connections() const
Connections.
ElementInput * dataIn()
Scene input.
const QPolygonF & way() const
way of the connection
ElementOutput * output()
Output of this connection.
ElementArea * elementArea() const
Element area.
QPolygonF findWay(Connection *_conn, QPoint _from, QPoint _to)
Finds a way from _from to _to ignoring any already existent connections from _conn.