56 #include "graphicsScene.hh" 57 #include "elementArea.hh" 58 #include "sceneElement.hh" 59 #include "connection.hh" 60 #include "elementInput.hh" 61 #include "elementOutput.hh" 63 #define PAIR(p) QPair<int,int>((p).x (),(p).y ()) 87 foreach (
Node *n, nodes_)
97 QRect bb = scene_->
elementArea ()->childrenBoundingRect ().toRect ().adjusted (-100, -100, 100, 100);
104 eR += e->mapRectToParent (e->boundingRect ()).toRect ().adjusted (-15,-15,15,15);
111 if (c->
way ().isEmpty ())
113 QPoint p1 = c->
way ().first ().toPoint ();
115 for (
int i = 1; i < c->
way ().size (); i++)
117 p2 = c->
way ()[i].toPoint ();
118 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);
126 if (c->
way ().isEmpty ())
128 QPoint p1 = c->
way ().first ().toPoint ();
130 for (
int i = 1; i < c->
way ().size (); i++)
132 p2 = c->
way ()[i].toPoint ();
133 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);
144 int x1 = (_from.x () / step) * step;
145 int y1 = (_from.y () / step) * step;
146 int x2 = (_to.x () / step) * step;
147 int y2 = (_to.y () / step) * step;
149 QPoint newTo = QPoint (x2, y2);
152 if (_from.x () != _to.x () && x1 == x2)
154 if (_from.x () > _to.x ())
160 if (_from.y () != _to.y () && y1 == y2)
162 if (_from.y () > _to.y ())
169 Node *n = NULL, *tmp, *tmp2, *lastIn = 0;
172 if (_from == oldFrom_ && eR == oldReg_)
174 if (map_.contains (PAIR(newTo)))
176 n = map_[PAIR(newTo)];
177 if (n->closed_ && n->counter_ == counter_)
188 if (!map_.contains (QPair<int,int>(x1, y1)))
190 ll_ =
new Node (counter_);
191 nodes_.push_back (ll_);
193 ll_->pos_ = QPoint (x1, y1);
194 map_.insert (QPair<int,int>(x1, y1), ll_);
196 for (
unsigned int k = 0; k < 4; k++)
198 QPoint p2 = validPos (k, step, ll_->pos_);
200 if (map_.contains (PAIR(p2)))
202 ll_->n_[k] = map_[PAIR(p2)];
203 map_[PAIR(p2)]->n_[(k + 2) & 3] = ll_;
209 ll_ = map_[QPair<int,int>(x1, y1)];
210 ll_->counter_ = counter_;
215 ll_->closed_ =
false;
220 ll_->h_ = heuristicDistance (_from, _to);
221 ll_->type_ = Node::Horizontal;
225 while (ll_ && !found)
236 if (n->pos_.y () == y2 && n->pos_.x () == x2)
243 for (
unsigned int i = 0; i < 4; i++)
246 QPoint p = validPos (i, step, n->pos_);
250 nodes_.push_back (nn);
254 nn->n_[(i + 2) & 3] = n;
256 nn->h_ = heuristicDistance (p, newTo);
261 map_.insert (PAIR(nn->pos_), nn);
263 for (
unsigned int j = 0; j < 3; j++)
265 unsigned int k = (i - 1 + j) & 3;
266 QPoint p2 = validPos (k, step, p);
268 if (map_.contains (PAIR(p2)))
270 nn->n_[k] = map_[PAIR(p2)];
271 map_[PAIR(p2)]->n_[(k + 2) & 3] = nn;
276 else if (n->n_[i]->counter_ != counter_)
279 tmp->counter_ = counter_;
286 tmp->closed_ =
false;
287 if (eR.contains (tmp->pos_))
291 tmp->h_ = heuristicDistance (tmp->pos_, newTo);
295 for (
unsigned int i = 0; i < 4; i++)
300 if (n->n_[i]->closed_)
305 unsigned int g = n->g_;
308 if ((n->type_ == Node::Horizontal && (i & 1)) || (n->type_ == Node::Vertical && (i & 1) == 0))
316 tmp->type_ = (i & 1)? Node::Horizontal : Node::Vertical;
319 tmp->f_ = g + tmp->h_;
323 tmp->prev_->next_ = tmp->next_;
325 tmp->next_->prev_ = tmp->prev_;
330 if (!ll_ || tmp->f_ <= ll_->f_)
340 if (lastIn && lastIn->f_ <= tmp->f_ && lastIn != tmp)
344 while (tmp2->next_ && tmp2->next_->f_ < tmp->f_)
346 tmp->next_ = tmp2->next_;
348 tmp->next_->prev_ = tmp;
364 if (n->pos_.y () != n->from_->pos_.y ())
367 int lastX = n->pos_.x ();
368 int lastY = n->pos_.y ();
374 if (dir && n->pos_.y () != lastY)
377 lastX = n->pos_.x ();
378 lastY = n->pos_.y ();
380 last = QPoint (n->pos_.x (), last.y ());
382 else if (!dir && n->pos_.x () != lastX)
385 lastX = n->pos_.x ();
386 lastY = n->pos_.y ();
388 last = QPoint (last.x (), n->pos_.y ());
395 last.setY (_from.y ());
397 last.setX (_from.x ());
399 rv.append(QPointF (last));
400 rv.append(QPointF (_from));
404 rv.append(QPointF (_from));
405 rv.append(QPointF (_to));
406 std::cerr <<
"Not Found" << std::endl;
421 WayFind::Node::Node(
unsigned int _counter) :
442 WayFind::Node::~ Node()
449 QPoint WayFind::validPos(
unsigned int _dir,
int _step, QPoint _pnt)
453 if (_dir == 0 || _dir == 3)
456 if (_dir == 1 || _dir == 3)
457 rv += QPoint (_step, 0);
459 rv += QPoint (0, _step);
467 int WayFind::heuristicDistance(
const QPoint &_from,
const QPoint &_to)
const 469 QPoint p = _from - _to;
470 return abs (p.x ()) + abs (p.y ());
476 void VSI::WayFind::cleanup()
479 if ((counter_ & 0x7f) != 0)
482 std::list<Node *>::iterator it = nodes_.begin();
484 while (it != nodes_.end ())
488 if (counter_ - n->counter_ > 64)
490 for (
unsigned int i = 0; i < 4; i++)
492 n->n_[i]->n_[(i+2)&3] = NULL;
493 it = nodes_.erase(it);
494 map_.remove (PAIR(n->pos_));
QPolygonF findWay(Connection *_conn, QPoint _from, QPoint _to)
Finds a way from _from to _to ignoring any already existent connections from _conn.
const QList< SceneElement * > & elements() const
Scene elements.
ElementInput * dataIn()
Scene input.
ElementArea * elementArea() const
Element area.
const QPolygonF & way() const
way of the connection
ElementOutput * output()
Output of this connection.
WayFind(GraphicsScene *_scene)
Constructor.
QVector< ElementInput * > inputs()
Inputs.
QList< Connection * > connections() const
Connections.