48 #include <QLinkedList> 57 #include "graphicsScene.hh" 58 #include "elementArea.hh" 59 #include "sceneElement.hh" 60 #include "connection.hh" 61 #include "elementInput.hh" 62 #include "elementOutput.hh" 64 #define PAIR(p) QPair<int,int>((p).x (),(p).y ()) 88 foreach (
Node *n, nodes_)
98 QRect bb = scene_->
elementArea ()->childrenBoundingRect ().toRect ().adjusted (-100, -100, 100, 100);
105 eR += e->mapRectToParent (e->boundingRect ()).toRect ().adjusted (-15,-15,15,15);
112 if (c->
way ().isEmpty ())
114 QPoint p1 = c->
way ().first ().toPoint ();
116 for (
int i = 1; i < c->
way ().size (); i++)
118 p2 = c->
way ()[i].toPoint ();
119 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);
127 if (c->
way ().isEmpty ())
129 QPoint p1 = c->
way ().first ().toPoint ();
131 for (
int i = 1; i < c->
way ().size (); i++)
133 p2 = c->
way ()[i].toPoint ();
134 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);
145 int x1 = (_from.x () / step) * step;
146 int y1 = (_from.y () / step) * step;
147 int x2 = (_to.x () / step) * step;
148 int y2 = (_to.y () / step) * step;
150 QPoint newTo = QPoint (x2, y2);
153 if (_from.x () != _to.x () && x1 == x2)
155 if (_from.x () > _to.x ())
161 if (_from.y () != _to.y () && y1 == y2)
163 if (_from.y () > _to.y ())
170 Node *n = NULL, *tmp, *tmp2, *lastIn = 0;
173 if (_from == oldFrom_ && eR == oldReg_)
175 if (map_.contains (PAIR(newTo)))
177 n = map_[PAIR(newTo)];
178 if (n->closed_ && n->counter_ == counter_)
189 if (!map_.contains (QPair<int,int>(x1, y1)))
191 ll_ =
new Node (counter_);
194 ll_->pos_ = QPoint (x1, y1);
195 map_.insert (QPair<int,int>(x1, y1), ll_);
197 for (
unsigned int k = 0; k < 4; k++)
199 QPoint p2 = validPos (k, step, ll_->pos_);
201 if (map_.contains (PAIR(p2)))
203 ll_->n_[k] = map_[PAIR(p2)];
204 map_[PAIR(p2)]->n_[(k + 2) & 3] = ll_;
210 ll_ = map_[QPair<int,int>(x1, y1)];
211 ll_->counter_ = counter_;
216 ll_->closed_ =
false;
221 ll_->h_ = heuristicDistance (_from, _to);
222 ll_->type_ = Node::Horizontal;
226 while (ll_ && !found)
237 if (n->pos_.y () == y2 && n->pos_.x () == x2)
244 for (
unsigned int i = 0; i < 4; i++)
247 QPoint p = validPos (i, step, n->pos_);
255 nn->n_[(i + 2) & 3] = n;
257 nn->h_ = heuristicDistance (p, newTo);
262 map_.insert (PAIR(nn->pos_), nn);
264 for (
unsigned int j = 0; j < 3; j++)
266 unsigned int k = (i - 1 + j) & 3;
267 QPoint p2 = validPos (k, step, p);
269 if (map_.contains (PAIR(p2)))
271 nn->n_[k] = map_[PAIR(p2)];
272 map_[PAIR(p2)]->n_[(k + 2) & 3] = nn;
277 else if (n->n_[i]->counter_ != counter_)
280 tmp->counter_ = counter_;
287 tmp->closed_ =
false;
288 if (eR.contains (tmp->pos_))
292 tmp->h_ = heuristicDistance (tmp->pos_, newTo);
296 for (
unsigned int i = 0; i < 4; i++)
301 if (n->n_[i]->closed_)
306 unsigned int g = n->g_;
309 if ((n->type_ == Node::Horizontal && (i & 1)) || (n->type_ == Node::Vertical && (i & 1) == 0))
317 tmp->type_ = (i & 1)? Node::Horizontal : Node::Vertical;
320 tmp->f_ = g + tmp->h_;
324 tmp->prev_->next_ = tmp->next_;
326 tmp->next_->prev_ = tmp->prev_;
331 if (!ll_ || tmp->f_ <= ll_->f_)
341 if (lastIn && lastIn->f_ <= tmp->f_ && lastIn != tmp)
345 while (tmp2->next_ && tmp2->next_->f_ < tmp->f_)
347 tmp->next_ = tmp2->next_;
349 tmp->next_->prev_ = tmp;
365 if (n->pos_.y () != n->from_->pos_.y ())
368 int lastX = n->pos_.x ();
369 int lastY = n->pos_.y ();
375 if (dir && n->pos_.y () != lastY)
378 lastX = n->pos_.x ();
379 lastY = n->pos_.y ();
381 last = QPoint (n->pos_.x (), last.y ());
383 else if (!dir && n->pos_.x () != lastX)
386 lastX = n->pos_.x ();
387 lastY = n->pos_.y ();
389 last = QPoint (last.x (), n->pos_.y ());
396 last.setY (_from.y ());
398 last.setX (_from.x ());
400 rv.append(QPointF (last));
401 rv.append(QPointF (_from));
405 rv.append(QPointF (_from));
406 rv.append(QPointF (_to));
407 std::cerr <<
"Not Found" << std::endl;
422 WayFind::Node::Node(
unsigned int _counter) :
443 WayFind::Node::~ Node()
450 QPoint WayFind::validPos(
unsigned int _dir,
int _step, QPoint _pnt)
454 if (_dir == 0 || _dir == 3)
457 if (_dir == 1 || _dir == 3)
458 rv += QPoint (_step, 0);
460 rv += QPoint (0, _step);
468 int WayFind::heuristicDistance(
const QPoint &_from,
const QPoint &_to)
const 470 QPoint p = _from - _to;
471 return abs (p.x ()) + abs (p.y ());
477 void VSI::WayFind::cleanup()
480 if ((counter_ & 0x7f) != 0)
483 QLinkedList<Node *>::iterator it = nodes_.begin();
485 while (it != nodes_.end ())
489 if (counter_ - n->counter_ > 64)
491 for (
unsigned int i = 0; i < 4; i++)
493 n->n_[i]->n_[(i+2)&3] = NULL;
494 it = nodes_.erase(it);
495 map_.remove (PAIR(n->pos_));
const QList< SceneElement * > & elements() const
Scene elements.
ElementArea * elementArea() const
Element area.
QList< Connection * > connections() const
Connections.
ElementOutput * output()
Output of this connection.
WayFind(GraphicsScene *_scene)
Constructor.
QVector< ElementInput * > inputs()
Inputs.
const QPolygonF & way() const
way of the connection
QPolygonF findWay(Connection *_conn, QPoint _from, QPoint _to)
Finds a way from _from to _to ignoring any already existent connections from _conn.
ElementInput * dataIn()
Scene input.