NGRandomNetBuilder.cpp
Go to the documentation of this file.00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029
00030 #include <iostream>
00031 #include <math.h>
00032 #include <stdlib.h>
00033 #include "NGRandomNetBuilder.h"
00034 #include <utils/geom/GeomHelper.h>
00035 #include <utils/common/RandHelper.h>
00036
00037 #ifdef CHECK_MEMORY_LEAKS
00038 #include <foreign/nvwa/debug_new.h>
00039 #endif // CHECK_MEMORY_LEAKS
00040
00041
00042
00043
00044
00045
00046
00047
00048 void
00049 TNeighbourDistribution::add(int NumNeighbours, SUMOReal ratio) throw() {
00050 myNeighbours[NumNeighbours] = ratio;
00051 }
00052
00053
00054 int
00055 TNeighbourDistribution::num() throw() {
00056 SUMOReal sum=0, RandValue;
00057 std::map<int, SUMOReal>::iterator i;
00058
00059 for (i=myNeighbours.begin(); i!=myNeighbours.end(); ++i) {
00060 sum += (*i).second;
00061 }
00062
00063 RandValue = RandHelper::rand(sum);
00064
00065 i = myNeighbours.begin();
00066 sum = (*i).second;
00067 while ((i != myNeighbours.end()) && (sum < RandValue)) {
00068 i++;
00069 sum += (*i).second;
00070 }
00071 return (*i).first;
00072 }
00073
00074
00075
00076
00077
00078 NGRandomNetBuilder::NGRandomNetBuilder(NGNet &net, SUMOReal minAngle, SUMOReal minDistance,
00079 SUMOReal maxDistance, SUMOReal connectivity,
00080 int numTries, const TNeighbourDistribution &neighborDist) throw()
00081 : myNet(net), myMinLinkAngle(minAngle), myMinDistance(minDistance),
00082 myMaxDistance(maxDistance), myConnectivity(connectivity), myNumTries(numTries),
00083 myNeighbourDistribution(neighborDist) {
00084 }
00085
00086
00087 void
00088 NGRandomNetBuilder::removeOuterNode(NGNode *node) throw() {
00089 for (NGNodeList::iterator ni=myOuterNodes.begin(); ni!=myOuterNodes.end(); ++ni) {
00090 if (*ni==node) {
00091 myOuterNodes.erase(ni);
00092 return;
00093 }
00094 }
00095 }
00096
00097
00098 bool
00099 NGRandomNetBuilder::checkAngles(NGNode *node) throw() {
00100 bool check = true;
00101
00102 if (node->LinkList.size() > 1) {
00103
00104 NGEdgeList::iterator li;
00105 NGNode *ni;
00106 for (li = node->LinkList.begin(); li != node->LinkList.end(); ++li) {
00107
00108 if ((*li)->getStartNode() == node) {
00109 ni = (*li)->getEndNode();
00110 } else {
00111 ni = (*li)->getStartNode();
00112 }
00113 Position2D v1(
00114 ni->getPosition().x() - node->getPosition().x(),
00115 ni->getPosition().y() - node->getPosition().y());
00116
00117 NGEdgeList::iterator lj;
00118 for (lj = node->LinkList.begin(); lj != node->LinkList.end(); ++lj) {
00119 if (li != lj) {
00120 if ((*lj)->getStartNode() == node)
00121 ni = (*lj)->getEndNode();
00122 else
00123 ni = (*lj)->getStartNode();
00124 Position2D v2(
00125 ni->getPosition().x() - node->getPosition().x(),
00126 ni->getPosition().y() - node->getPosition().y());
00127 SUMOReal angle = GeomHelper::Angle2D(v1.x(), v1.y(), v2.x(), v2.y());
00128 if (fabs((SUMOReal) angle) < myMinLinkAngle)
00129 check = false;
00130 }
00131 }
00132 }
00133 }
00134 return check;
00135 }
00136
00137
00138 bool
00139 NGRandomNetBuilder::canConnect(NGNode *baseNode, NGNode *newNode) throw() {
00140 bool connectable=true;
00141 Position2D n1(baseNode->getPosition());
00142 Position2D n2(newNode->getPosition());
00143
00144
00145 if (connectable) {
00146 SUMOReal dist = n1.distanceTo(n2);
00147 if ((dist < myMinDistance) || (dist > myMaxDistance)) {
00148 connectable = false;
00149 }
00150 }
00151
00152
00153 if (connectable) connectable = checkAngles(baseNode);
00154 if (connectable) connectable = checkAngles(newNode);
00155
00156
00157 if (connectable) {
00158 NGEdgeList::iterator li;
00159 li = myOuterLinks.begin();
00160 while ((connectable == true) && (li != myOuterLinks.end())) {
00161
00162 Position2D p1((*li)->getStartNode()->getPosition());
00163 Position2D p2((*li)->getEndNode()->getPosition());
00164 if ((baseNode != (*li)->getStartNode()) && (baseNode!= (*li)->getEndNode())
00165 && (newNode != (*li)->getStartNode()) && (newNode!= (*li)->getEndNode())) {
00166 connectable = !GeomHelper::intersects(n1, n2, p1, p2);
00167
00168 }
00169
00170 if ((connectable) &&
00171 (newNode != (*li)->getStartNode()) && (newNode != (*li)->getEndNode())) {
00172 SUMOReal dist = GeomHelper::distancePointLine(n2, p1, p2);
00173 if ((dist < myMinDistance) && (dist > -1))
00174 connectable = false;
00175 }
00176 li++;
00177 }
00178 }
00179 return connectable;
00180 }
00181
00182
00183 void
00184 NGRandomNetBuilder::findPossibleOuterNodes(NGNode *node) throw() {
00185 myConNodes.clear();
00186 NGNodeList::iterator ni;
00187 for (ni = myOuterNodes.begin(); ni != myOuterNodes.end(); ++ni) {
00188 NGNode *on=*ni;
00189 if (!node->connected(on)) {
00190 if ((node->getMaxNeighbours() > node->LinkList.size()) &&
00191 ((on)->getMaxNeighbours() > (on)->LinkList.size())) {
00192 if (canConnect(node, on)) {
00193 myConNodes.push_back(on);
00194 }
00195 }
00196 }
00197 }
00198 }
00199
00200
00201 bool
00202 NGRandomNetBuilder::createNewNode(NGNode *baseNode) throw() {
00203
00204 SUMOReal dist = RandHelper::rand(myMinDistance, myMaxDistance);
00205 SUMOReal angle = RandHelper::rand((SUMOReal)(2*PI));
00206 SUMOReal x = baseNode->getPosition().x() + dist * cos(angle);
00207 SUMOReal y = baseNode->getPosition().y() + dist * sin(angle);
00208 NGNode *newNode = new NGNode(myNet.getNextFreeID());
00209 newNode->setX(x);
00210 newNode->setY(y);
00211 newNode->setMaxNeighbours((SUMOReal) myNeighbourDistribution.num());
00212 NGEdge *newLink = new NGEdge(myNet.getNextFreeID(), baseNode, newNode);
00213 if (canConnect(baseNode, newNode)) {
00214
00215 myNet.add(newNode);
00216 myOuterNodes.push_front(newNode);
00217
00218 myNet.add(newLink);
00219 myOuterLinks.push_back(newLink);
00220
00221 if (baseNode->LinkList.size() >= baseNode->getMaxNeighbours()) {
00222 removeOuterNode(baseNode);
00223 }
00224 return true;
00225 } else {
00226 delete newNode;
00227 return false;
00228 }
00229 }
00230
00231
00232 void
00233 NGRandomNetBuilder::createNet(int numNodes) throw() {
00234 myNumNodes = numNodes;
00235
00236 NGNode *outerNode = new NGNode(myNet.getNextFreeID());
00237 outerNode->setX(0);
00238 outerNode->setY(0);
00239 outerNode->setMaxNeighbours(4);
00240
00241 myNet.add(outerNode);
00242 myOuterNodes.push_back(outerNode);
00243
00244 bool created = true;
00245 while (((int) myNet.nodeNo() < numNodes) && (myOuterNodes.size() > 0)) {
00246
00247 if (!created) {
00248 myOuterNodes.push_front(myOuterNodes.back());
00249 myOuterNodes.pop_back();
00250 }
00251 outerNode = myOuterNodes.back();
00252 findPossibleOuterNodes(outerNode);
00253 created = false;
00254 if ((myConNodes.size() > 0) && (RandHelper::rand() < myConnectivity)) {
00255
00256 NGEdge *newLink = new NGEdge(myNet.getNextFreeID(), outerNode, myConNodes.back());
00257 if (canConnect(outerNode, myConNodes.back())) {
00258
00259 myNet.add(newLink);
00260 myOuterLinks.push_back(newLink);
00261
00262 if (outerNode->LinkList.size() >= outerNode->getMaxNeighbours()) {
00263 removeOuterNode(outerNode);
00264 }
00265 if (myConNodes.back()->LinkList.size() >= myConNodes.back()->getMaxNeighbours()) {
00266 removeOuterNode(myConNodes.back());
00267 }
00268 created = true;
00269 } else {
00270 delete newLink;
00271 }
00272 } else {
00273 int count=0;
00274 do {
00275 created = createNewNode(outerNode);
00276 count++;
00277 } while ((count <= myNumTries) && !created);
00278 if (!created) {
00279 outerNode->setMaxNeighbours((SUMOReal) outerNode->LinkList.size());
00280 myOuterNodes.remove(outerNode);
00281 }
00282 }
00283 }
00284 }
00285
00286
00287
00288