/** * This function sets up connections between robots who are close enough to * each other and have their connection ring set to 1. */ void RobotAgent::setUpConnections() { if (!gUseOrganisms) return; int nAgents = _wm->_world->getNbOfAgent(); int id = _wm->_agentId; if (this->isPartOfOrganism()) { if (this->getConnectToOthers() == Agent::NEGATIVE) { this->letGoOfOrganism(); }/* else if (this->getConnectToOthers() == Agent::NEUTRAL) { std::vector<RobotAgentPtr>::iterator it; for (it = this->connected->begin(); it != this->connected->end(); it++) { RobotAgentPtr other = (*it); if (other->getConnectToOthers() == Agent::NEUTRAL) { it = this->connected->erase(it); other->removeNeighbour(gWorld->getAgent(this->_wm->_agentId)); break; } } }*/ if (this->connected->empty()) { this->letGoOfOrganism(); } } for (int i = 0; i < nAgents; i++) { RobotAgentPtr other = _wm->_world->getAgent(i); RobotAgentWorldModel *otherWM = (RobotAgentWorldModel*) other->getWorldModel(); int otherId = otherWM->_agentId; if (otherId != id) { // If they're out of bounds, ignore. // This happens at the start of the simulation sometimes and can lead // to false positives if (this->isOutOfBounds() || other->isOutOfBounds()) { return; } double x1, y1, x2, y2; x1 = this->_wm->_xReal; y1 = this->_wm->_yReal; x2 = other->_wm->_xReal; y2 = other->_wm->_yReal; // Are they within range? if (SDL_CollideBoundingCircle(gAgentMaskImage, x1, y1, gAgentMaskImage, x2, y2, gConnectionGap)) { // connect to other robot // ---- Mark: but only connect in case you are willing to do so. if ((this->getConnectToOthers() == Agent::POSITIVE) && (other->getConnectToOthers() == Agent::POSITIVE)) { // || other->getConnectToOthers() == Agent::NEUTRAL)) { this->connectToRobot(other); } // else if (this->getConnectToOthers() == Agent::NEUTRAL && other->getConnectToOthers() == Agent::POSITIVE) { // this->connectToRobot(other); // } } } } }
/* a circle intersection detection algorithm that will use the position of the centre of the surface as the centre of the circle and approximate the radius using the width and height of the surface (for example a rect of 4x6 would have r = 2.5). */ int SDL_CollideBoundingCircle(SDL_Surface *a, int x1, int y1, SDL_Surface *b, int x2, int y2, int offset) { /* if radius is not specified we approximate them using SDL_Surface's width and height average and divide by 2*/ int r1 = (a->w + a->h) / 4; // same as / 2) / 2; int r2 = (b->w + b->h) / 4; x1 += a->w / 2; // offset x and y y1 += a->h / 2; // co-ordinates into // centre of image x2 += b->w / 2; y2 += b->h / 2; return SDL_CollideBoundingCircle(x1, y1, r1, x2, y2, r2, offset); }