ClusteredSpringEmbedder.cpp 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390
  1. #include "ClusteredSpringEmbedder.h"
  2. ClusteredSpringEmbedder::ClusteredSpringEmbedder()
  3. {
  4. }
  5. void ClusteredSpringEmbedder :: springForEachCluster(SubGraph& gMaingraph, int iIterations)
  6. {
  7. // XXX obselete LAYOUT_ASSERT( &gMaingraph != NULL,
  8. // LayoutException(__FUNCTION__
  9. // ,LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  10. // ,"Input and Output graphml path"
  11. // ,"applyLayout"));
  12. Postprocessing postProcessor, preprocessor;
  13. preprocessor.applyPreProcessing(gMaingraph);
  14. m_gMaingraph = gMaingraph;
  15. QQueue<SubGraph*> qSubgraphs; // a queue of subgraphs
  16. qSubgraphs.enqueue(&gMaingraph);
  17. SubGraph* gSubgraph1 = NULL;
  18. while(qSubgraphs.isEmpty() == false) // Iterating subgraphs till they exist
  19. {
  20. gSubgraph1 = qSubgraphs.dequeue();
  21. // call each step of algo with a subgraph
  22. springStep((*gSubgraph1),gMaingraph,iIterations);
  23. ChildrenIterator iterChild , iterChildEnd;
  24. for(boost::tie(iterChild , iterChildEnd) = gSubgraph1->children();
  25. iterChild != iterChildEnd;iterChild++)
  26. {
  27. SubGraph* gChildGraph = &(*iterChild);
  28. if(boost::num_vertices(*gChildGraph) ==0)
  29. {
  30. continue; // handle empty compartments
  31. }
  32. qSubgraphs.enqueue(gChildGraph);
  33. }
  34. }
  35. // set Vertices Displacements as zero
  36. springSetVerticesDisplacementZero();
  37. // handle empty clusters
  38. postProcessor.applyPostProcessing(gMaingraph);
  39. // Check if two cluster overlaps
  40. postProcessor.checkClusterOverlap(gMaingraph);
  41. // try to reduce vertex overlap trivially
  42. postProcessor.overlapRemoval(gMaingraph);
  43. // VertexOverlapRemoval vertexOverlapRemove; to be included
  44. // vertexOverlapRemove.removeOverlaps(gMaingraph); separately
  45. // check if membership of any subgraph is violated
  46. postProcessor.checkAndFixMembership(gMaingraph);
  47. postProcessor.membershipFixer(gMaingraph);
  48. }
  49. void ClusteredSpringEmbedder:: springTestRecursive(SubGraph& gMaingraph)
  50. {
  51. // To do : Test this approach
  52. ChildrenIterator itrChild, itrEndChild;
  53. for(boost::tie(itrChild, itrEndChild) = gMaingraph.children();
  54. itrChild != itrEndChild; ++itrChild)
  55. {
  56. this->springStep(*itrChild, gMaingraph,100);
  57. }
  58. }
  59. void ClusteredSpringEmbedder:: springStep(SubGraph& gSubgraph,
  60. SubGraph& gMaingraph,
  61. int iIterations)
  62. {
  63. while(iIterations)
  64. {
  65. // relax only immediate edges of subgraphs
  66. springRelaxImmediate(gSubgraph);
  67. // relax interedges
  68. springRelaxInterEdges(gMaingraph);
  69. // repel only immediate subgraphs
  70. springRepelImmediate(gSubgraph);
  71. // clusters repelling other nodes only
  72. springRepelFromClusters(gSubgraph);
  73. // repel cluster to cluster
  74. springTestRepelClusterToCluster(gSubgraph);
  75. // move clusters a nudge
  76. springMoveClusters(gSubgraph);
  77. // move nodes a nudge
  78. springMoveRestricted(gSubgraph);
  79. iIterations--;
  80. }
  81. Reingold *rein = new Reingold();
  82. rein->setCompartMentProps(gSubgraph,10); // set height , width
  83. }
  84. void ClusteredSpringEmbedder:: springRelaxImmediate(SubGraph& gSubgraph)
  85. {
  86. int iGraphId = m_bGraphWrapper.getGraphClusterID(gSubgraph);
  87. int iVertexGraphId1, iVertexGraphId2;
  88. EdgeIterator eStart, eEnd;
  89. for (boost::tie(eStart, eEnd) = edges(gSubgraph); eStart != eEnd; ++eStart)
  90. {
  91. VertexDescriptor verV = source(*eStart, gSubgraph);
  92. VertexDescriptor verU = target(*eStart, gSubgraph);
  93. iVertexGraphId1 = m_bGraphWrapper.getVertexClusterID(verV,gSubgraph);
  94. iVertexGraphId2 = m_bGraphWrapper.getVertexClusterID(verU,gSubgraph);
  95. if(!(iVertexGraphId1 == iVertexGraphId2 && iVertexGraphId1 == iGraphId) )
  96. {
  97. continue; // not an inter edges
  98. }
  99. double dXCoordV = m_bGraphWrapper.getVertexCenterCoordX(verV,gSubgraph);
  100. double dYCoordV = m_bGraphWrapper.getVertexCenterCoordY(verV,gSubgraph);
  101. double dXCoordU = m_bGraphWrapper.getVertexCenterCoordX(verU,gSubgraph);
  102. double dYCoordU = m_bGraphWrapper.getVertexCenterCoordY(verU,gSubgraph);
  103. double dXDisp = m_bGraphWrapper.getVertXDisp(verV,gSubgraph);
  104. double dYDisp = m_bGraphWrapper.getVertYDisp(verV,gSubgraph);
  105. double dXDispU = 0;
  106. double dYDispU = 0;
  107. dXDispU = m_bGraphWrapper.getVertXDisp(verU,gSubgraph);
  108. dYDispU = m_bGraphWrapper.getVertYDisp(verU,gSubgraph);
  109. // Logic for vertex size here
  110. double dXsizeU = m_bGraphWrapper.getVertexWidth(verU,gSubgraph);
  111. double dXsizeV = m_bGraphWrapper.getVertexWidth(verV,gSubgraph);
  112. if(dXCoordU > dXCoordV)
  113. {
  114. dXCoordV = dXCoordV + dXsizeV/2;
  115. dXCoordU = dXCoordU - dXsizeU/2;
  116. }
  117. else
  118. {
  119. dXCoordV = dXCoordV - dXsizeV/2;
  120. dXCoordU = dXCoordU + dXsizeU/2;
  121. }
  122. double dVx = dXCoordV - dXCoordU;
  123. double dVy = dYCoordV - dYCoordU;
  124. // calculate movement vectors
  125. cout<<"\n Delta X and Y at attractive force : "<<dVy<<" "
  126. << dVx;
  127. double dDist = fabs(sqrt((dVx*dVx+dVy* dVy)));
  128. cout<<"Distance at attractive force : "<<dDist;
  129. if(dDist == 0)
  130. {
  131. dDist = 0.0001;
  132. }
  133. // desired length = 50 MACRO
  134. // HOOK'S LAW
  135. double dForce = ATTRACTION_MULTIPLIER *( DEFAULT_EDGE_LENGTH - dDist)/dDist ;
  136. // reduce force if degree of node is high ---- Degree Based charge KUMAR
  137. dForce = dForce * std::pow(0.7,in_degree(verV,gSubgraph)+in_degree(verU,gSubgraph)
  138. + out_degree(verU,gSubgraph)+out_degree(verV,gSubgraph) -2);
  139. double dx = dForce * dVx;
  140. double dy = dForce * dVy;
  141. // add to displacement
  142. dXDisp += dx;
  143. dYDisp += dy;
  144. dXDispU -= dx;
  145. dYDispU -= dy;
  146. cout<<"\n Attractive Forces Displacement " ;
  147. cout<<"\n at I X Disp : "<<dXDisp;
  148. cout<<" Y Disp : "<<dYDisp;
  149. cout<<"\n at J X Disp : "<<dXDispU;
  150. cout<<" Y Disp : "<<dYDispU;
  151. m_bGraphWrapper.setVertXDisp(dXDisp,verV,gSubgraph);
  152. m_bGraphWrapper.setVertYDisp(dYDisp,verV,gSubgraph);
  153. m_bGraphWrapper.setVertXDisp(dXDispU,verU,gSubgraph);
  154. m_bGraphWrapper.setVertYDisp(dYDispU,verU,gSubgraph);
  155. }
  156. }
  157. void ClusteredSpringEmbedder :: springRepelImmediate(SubGraph& gSubgraph)
  158. {
  159. VertexDescriptor verAffected,verVisitor;
  160. VertexIterPair verIter,verIterEnd;
  161. int iGraphId = m_bGraphWrapper.getGraphClusterID(gSubgraph);
  162. int iVertexGraphId1, iVertexGraphId2;
  163. for(tie(verIter.first,verIter.second)=vertices(gSubgraph)
  164. ;verIter.first!=verIter.second;++verIter.first)
  165. {
  166. verAffected = *verIter.first;
  167. double dDx = 0;
  168. double dDy = 0;
  169. double dXDisp =0;
  170. double dYDisp = 0;
  171. double dXCoordV = m_bGraphWrapper.getVertexCenterCoordX(verAffected,gSubgraph);
  172. double dYCoordV = m_bGraphWrapper.getVertexCenterCoordY(verAffected,gSubgraph);
  173. for(tie(verIterEnd.first,verIterEnd.second)=vertices(gSubgraph);
  174. verIterEnd.first != verIterEnd.second;++verIterEnd.first)
  175. {
  176. verVisitor = *verIterEnd.first;
  177. iVertexGraphId1 = m_bGraphWrapper.getVertexClusterID(verAffected,gSubgraph);
  178. iVertexGraphId2 = m_bGraphWrapper.getVertexClusterID(verVisitor,gSubgraph);
  179. if(!(iVertexGraphId1 == iVertexGraphId2 && iVertexGraphId1 == iGraphId) )
  180. {
  181. continue; // not immediate neighbours
  182. }
  183. double dXCoordU = m_bGraphWrapper.getVertexCenterCoordX(verVisitor,gSubgraph);
  184. double dYCoordU = m_bGraphWrapper.getVertexCenterCoordY(verVisitor,gSubgraph);
  185. if(verAffected == verVisitor)
  186. {
  187. continue;
  188. }
  189. // Logic for vertex size here
  190. double dXsizeU = m_bGraphWrapper.getVertexWidth(verVisitor,gSubgraph);
  191. double dXsizeV = m_bGraphWrapper.getVertexWidth(verAffected,gSubgraph);
  192. // try to comment it
  193. if(dXCoordU > dXCoordV)
  194. {
  195. dXCoordV = dXCoordV + dXsizeV/2;
  196. dXCoordU = dXCoordU - dXsizeU/2;
  197. }
  198. else
  199. {
  200. dXCoordV = dXCoordV - dXsizeV/2;
  201. dXCoordU = dXCoordU + dXsizeU/2;
  202. }
  203. // get cliiping points here cordinates here.
  204. double dVx = dXCoordV - dXCoordU;
  205. double dVy = dYCoordV - dYCoordU;
  206. // calculate square distance
  207. double dDist = fabs((dVx*dVx + dVy* dVy));
  208. cout<<"\nDistance at Repulsive force : "<<dDist;
  209. if(dDist == 0 || dDist < 500 )
  210. {
  211. // too close move some random distance away
  212. dDist = std::rand()%300+100;
  213. }
  214. if(dDist < REPULSION_RANGE )
  215. {
  216. dDx += REPULSION_MULTIPLIER*dVx/dDist; // factor =1 def works well for 1000
  217. dDy += REPULSION_MULTIPLIER*dVy/dDist;
  218. }
  219. else{
  220. cout<<"\n Skipping due to distance";
  221. }
  222. cout<<"\ndx and dy at Repulsive force : "<<dDx<<" "<<dDy;
  223. }
  224. double dLen = dDx*dDx+ dDy*dDy;
  225. dLen = sqrt(fabs(dLen))/2;
  226. if(dLen > 0)
  227. {
  228. dXDisp = m_bGraphWrapper.getVertXDisp(verAffected,gSubgraph);
  229. dYDisp = m_bGraphWrapper.getVertYDisp(verAffected,gSubgraph);
  230. // add displacement
  231. dXDisp += (dDx/dLen);
  232. dYDisp += (dDy/dLen);
  233. m_bGraphWrapper.setVertXDisp(dXDisp,verAffected,gSubgraph);
  234. m_bGraphWrapper.setVertYDisp(dYDisp,verAffected,gSubgraph);
  235. cout<<"\nDisplacement at Repulsive force : "<<dYDisp<<" "
  236. << dXDisp;
  237. }
  238. }
  239. }
  240. void ClusteredSpringEmbedder :: springMoveRestricted(SubGraph& gSubgraph)
  241. {
  242. int iGHeight=0;
  243. int iGwidth=0;
  244. int iMinX=0;
  245. int iMaxY=0;
  246. int iMinY=0;
  247. iGHeight = m_bGraphWrapper.getGraphHeight(gSubgraph);
  248. iGwidth = m_bGraphWrapper.getGraphWidth(gSubgraph);
  249. iMinX = m_bGraphWrapper.getGraphLeftTopCoordX(gSubgraph);
  250. iMaxY = m_bGraphWrapper.getGraphLeftTopCoordY(gSubgraph);
  251. iMaxY = iMinX + iGwidth;
  252. iMinY = iMaxY - iGHeight;
  253. // XXX set but not used
  254. Q_UNUSED(iMinY);
  255. VertexDescriptor verAffected;
  256. VertexIterPair verIter;
  257. int iGraphId = m_bGraphWrapper.getGraphClusterID(gSubgraph);
  258. int iVertexGraphId1;
  259. for(tie(verIter.first,verIter.second)=vertices(gSubgraph)
  260. ;verIter.first!=verIter.second;++verIter.first)
  261. {
  262. verAffected = *verIter.first;
  263. iVertexGraphId1 = m_bGraphWrapper.getVertexClusterID(verAffected,gSubgraph);
  264. if(iGraphId != iVertexGraphId1)
  265. {
  266. continue; // not part of current graph
  267. }
  268. double dXCoordV = m_bGraphWrapper.getVertexCenterCoordX
  269. (verAffected,gSubgraph);
  270. double dYCoordV = m_bGraphWrapper.getVertexCenterCoordY
  271. (verAffected,gSubgraph);
  272. double dXDisp = m_bGraphWrapper.getVertXDisp(verAffected,gSubgraph);
  273. double dYDisp = m_bGraphWrapper.getVertYDisp(verAffected,gSubgraph);
  274. m_bGraphWrapper.setVertXDisp(dXDisp/4,verAffected,gSubgraph); // /4
  275. m_bGraphWrapper.setVertYDisp(dYDisp/4,verAffected,gSubgraph); // /4
  276. // limit displacement to max value
  277. if(dXDisp < 0)
  278. {
  279. dXDisp = std::max(dXDisp,- UNIT_DISPLACEMENT);
  280. }
  281. else
  282. {
  283. dXDisp = std::min(dXDisp,UNIT_DISPLACEMENT);
  284. }
  285. if(dYDisp < 0)
  286. {
  287. dYDisp = std::max(dYDisp,- UNIT_DISPLACEMENT);
  288. }
  289. else
  290. {
  291. dYDisp = std::min(dYDisp,UNIT_DISPLACEMENT);
  292. }
  293. m_bGraphWrapper.setVertexCenterCoordX(verAffected,gSubgraph,
  294. dXCoordV+dXDisp);
  295. m_bGraphWrapper.setVertexCenterCoordY(verAffected,gSubgraph,
  296. dYCoordV+dYDisp);
  297. }
  298. }
  299. void ClusteredSpringEmbedder :: springRepelFromClusters(SubGraph& gSubgraph)
  300. {
  301. cout<<"\n ***********Repelling Vertices with Cluster First ***********";
  302. VertexDescriptor verAffected;
  303. VertexIterPair verIter;
  304. int iGraphId = m_bGraphWrapper.getGraphClusterID(gSubgraph);
  305. int iVertexGraphId1 ;
  306. double dDx = 0,dDy = 0;
  307. // for each immediate cluster of received subgraph
  308. QQueue<SubGraph*> qSubgraphs; // a queue of subgraphs
  309. qSubgraphs.enqueue(&gSubgraph);
  310. SubGraph* gSubgraph1 = NULL;
  311. while(qSubgraphs.isEmpty() == false) // Iterating subgraphs till they exist
  312. {
  313. gSubgraph1 = qSubgraphs.dequeue();
  314. ChildrenIterator iterChild , iterChildEnd;
  315. for(boost::tie(iterChild , iterChildEnd) = gSubgraph1->children();
  316. iterChild != iterChildEnd;
  317. iterChild++)
  318. {
  319. SubGraph* gChildGraph = &(*iterChild);
  320. for(tie(verIter.first,verIter.second)=vertices(gSubgraph)
  321. ;verIter.first!=verIter.second;++verIter.first)
  322. {
  323. verAffected = *verIter.first;
  324. iVertexGraphId1 = m_bGraphWrapper.getVertexClusterID(verAffected,gSubgraph);
  325. if(iVertexGraphId1 != iGraphId)
  326. {
  327. continue; // not part of subGraph
  328. }
  329. int iClusterTopLeftXCoord = m_bGraphWrapper.getGraphLeftTopCoordX(*gChildGraph);
  330. int iClusterTopLeftYCoord = m_bGraphWrapper.getGraphLeftTopCoordY(*gChildGraph);
  331. int iClusterHeight = m_bGraphWrapper.getGraphHeight(*gChildGraph);
  332. int iClusterWidth = m_bGraphWrapper.getGraphWidth(*gChildGraph);
  333. int iClusterCentreXCoord = m_bGraphWrapper.getGraphCenterCoordX(*gChildGraph);
  334. int iClusterCentreYCoord = m_bGraphWrapper.getGraphCenterCoordY(*gChildGraph);
  335. int iVertexXCoord = m_bGraphWrapper.getVertexCenterCoordX(verAffected,gSubgraph);
  336. int iVertexYCoord = m_bGraphWrapper.getVertexCenterCoordY(verAffected,gSubgraph);
  337. int iClusterClipXCoord , iClusterClipYCoord;
  338. //Form 4 pairs forclusters and edge between two centres
  339. typedef boost::geometry::model::point<int, 2, boost::geometry::cs::cartesian> Points;
  340. Points pP,pQ,pR,pS,pX,pY;
  341. typedef boost::geometry::model::segment<Points> Segment;
  342. std::vector<Points> pOutput;
  343. pP.set<0>(iClusterTopLeftXCoord);
  344. pP.set<1>(iClusterTopLeftYCoord);
  345. pQ.set<0>(iClusterTopLeftXCoord);
  346. pQ.set<1>(iClusterTopLeftYCoord + iClusterHeight);
  347. pR.set<0>(iClusterTopLeftXCoord + iClusterWidth);
  348. pR.set<1>(iClusterTopLeftYCoord + iClusterHeight);
  349. pS.set<0>(iClusterTopLeftXCoord+ iClusterWidth);
  350. pS.set<1>(iClusterTopLeftYCoord);
  351. pX.set<0>(iClusterCentreXCoord);
  352. pX.set<1>(iClusterCentreYCoord);
  353. pY.set<0>(iVertexXCoord);
  354. pY.set<1>(iVertexYCoord);
  355. Segment PQ( pP,pQ );
  356. Segment QR( pQ,pR );
  357. Segment RS( pR,pS );
  358. Segment SP( pS,pP );
  359. Segment Edge (pX,pY);
  360. bool bNoIntersection = false;
  361. cout<<"\n ***********Repelling Vertices with Cluster";
  362. if(boost::geometry::intersects(Edge,PQ))
  363. {
  364. boost::geometry::intersection(Edge,PQ,pOutput);
  365. cout<<" \n Cluster Repulsion Clip Found with Edge PQ";
  366. }
  367. else if( boost::geometry::intersects(Edge,QR))
  368. {
  369. boost::geometry::intersection(Edge,QR,pOutput);
  370. cout<<" \n Cluster Repulsion Clip Found with Edge QR";
  371. }
  372. else
  373. {
  374. if(boost::geometry::intersects(Edge,RS))
  375. {
  376. boost::geometry::intersection(Edge,RS,pOutput);
  377. cout<<" \n Cluster Repulsion Clip Found with Edge RS";
  378. }
  379. else if(boost::geometry::intersects(Edge,SP))
  380. {
  381. boost::geometry::intersection(Edge,SP,pOutput);
  382. cout<<" \n Cluster Repulsion Clip Found with Edge SP";
  383. }
  384. else
  385. {
  386. cout<<"\n *** No Intersection in Outer *** Check Cluster cordinates" ;
  387. bNoIntersection = true;
  388. }
  389. }
  390. if(!bNoIntersection)
  391. {
  392. // intersection found
  393. Points pIntersection = pOutput[0];
  394. iClusterClipXCoord = pIntersection.get<0>();
  395. iClusterClipYCoord = pIntersection.get<1>();
  396. cout<<"\n Intersection at "<<iClusterClipXCoord <<" "<<iClusterClipYCoord;
  397. double dVx = iClusterClipXCoord - iVertexXCoord;
  398. double dVy = iClusterClipYCoord - iVertexYCoord;
  399. double dDist = fabs((dVx*dVx + dVy* dVy));
  400. cout<<"\nDistance at Cluster Repulsion : "<<dDist;
  401. if(dDist == 0 )
  402. {
  403. dDist = 0.001;
  404. }
  405. bool bTooClose = false;
  406. if( dDist < CLUSTER_REPULSION_RANGE ) // within range only
  407. {
  408. dDx += CLUSTER_REPULSION_MULTIPLIER*dVx/dDist; // factor = 1 def , works well for 1000
  409. dDy += CLUSTER_REPULSION_MULTIPLIER*dVy/dDist;
  410. if(dDist < CLOSE_TO_BOUNDRY ) // Close to boundry 200 default
  411. {
  412. bTooClose = true;
  413. }
  414. cout<<"\ndx and dy at Repulsive force : "<<dDx<<" "<<dDy;
  415. double dLen = dDx*dDx+ dDy*dDy;
  416. dLen = sqrt(fabs(dLen))/2;
  417. double dXDisp = 0,dYDisp = 0;
  418. int iClusterXDisp= 0 , iClusterYDisp = 0;
  419. dXDisp = m_bGraphWrapper.getVertXDisp(verAffected,gSubgraph);
  420. dYDisp = m_bGraphWrapper.getVertYDisp(verAffected,gSubgraph);
  421. if(bTooClose)
  422. {
  423. // vertex is too close to cluster boundry
  424. if(dDx > 0)
  425. {
  426. dXDisp += std::min(20.0,dDx/dLen);
  427. }
  428. else
  429. {
  430. dXDisp += std::max( -20.0,dDx/dLen);
  431. }
  432. {
  433. if(dDy > 0)
  434. {
  435. dYDisp += std::min(20.0,dDy/dLen);
  436. }
  437. else
  438. {
  439. dYDisp += std::max(-20.0,dDy/dLen);
  440. }
  441. }
  442. }
  443. else
  444. {
  445. if(dDx > 0)
  446. {
  447. dXDisp += CLOSE_TO_BOUNDRY - dDist;
  448. }
  449. else
  450. {
  451. dXDisp += - CLOSE_TO_BOUNDRY + dDist;
  452. }
  453. {
  454. if(dDy > 0)
  455. {
  456. dYDisp += CLOSE_TO_BOUNDRY - dDist;
  457. }
  458. else
  459. {
  460. dYDisp += - CLOSE_TO_BOUNDRY + dDist;
  461. }
  462. }
  463. bTooClose = false;
  464. }
  465. m_bGraphWrapper.setVertXDisp(dXDisp,verAffected,gSubgraph);
  466. m_bGraphWrapper.setVertYDisp(dYDisp,verAffected,gSubgraph);
  467. cout<<"\nX Disp "<<dDx/dLen<<" "<<"Y Disp "<<dDy/dLen;
  468. iClusterXDisp = m_bGraphWrapper.getClusterXDisplacement(*gChildGraph);
  469. iClusterYDisp = m_bGraphWrapper.getClusterYDisplacement(*gChildGraph);
  470. if(dDx > 0)
  471. {
  472. iClusterXDisp += (int)std::min(2.0,dDx/dLen);
  473. }
  474. else
  475. {
  476. iClusterXDisp += (int)std::max( - 2.0,dDx/dLen);
  477. }
  478. {
  479. if(dDy > 0)
  480. {
  481. iClusterYDisp += (int)std::min(2.0,dDy/dLen);
  482. }
  483. else
  484. {
  485. iClusterYDisp += (int)std::max(-2.0,dDy/dLen);
  486. }
  487. }
  488. m_bGraphWrapper.setClusterXDisplacement(*gChildGraph,iClusterXDisp);
  489. m_bGraphWrapper.setClusterYDisplacement(*gChildGraph,iClusterYDisp);
  490. cout<<"\nDisplacement at Cluster Repulsion : "<<dYDisp<<" "<< dXDisp;
  491. }
  492. }
  493. }
  494. }
  495. }
  496. }
  497. void ClusteredSpringEmbedder :: springRepelClustersToCluster(SubGraph& gSubgraph)
  498. {
  499. Q_UNUSED(gSubgraph);
  500. // XXX NOT USED ANY MORE REMOVE
  501. return;
  502. }
  503. /* Algo for interedges
  504. *
  505. * 1> For each edge E do
  506. * 2> get vertices u and v
  507. * 3> check graph id's
  508. *
  509. * Case i) u = 999 and v = immediate subgraph
  510. * get Clipping Points
  511. * Apply RF attractive or spring embedder
  512. *
  513. * Case ii)u = 999 and v = non immediate subgraph
  514. * get outermost parent of v
  515. * get clipping points1 for 999 and outer most parent of v
  516. * Apply RF attractive to clip point1 and u
  517. * get clipping points2 for 999 and subgraph of v
  518. * Apply RF attractive to clip point2 and v.
  519. *
  520. * Case iii) u = XXX and v = YYY
  521. * get Clip point1 with subgraph u and v
  522. * apply rf attractive with clip point1 and u.
  523. * get Clip point2 with subgraph v and and u.
  524. * apply rf attractive with clip point2 and v.
  525. */
  526. // case 3 and 4
  527. // get two outermost rectangles , check whether they overlap
  528. // if they overlap then case 3
  529. // else case 4
  530. // Overlap i.e case 3
  531. // Algorithm
  532. /* 1> Get two vertices
  533. 2> get their graphids
  534. 3> get their graphs by iterating
  535. 4> check whether overlapping or not
  536. 5> Overlapping
  537. 6> find out which graph cointains other thus finding outer and inner
  538. 7> repeat case 2 :)
  539. */
  540. void ClusteredSpringEmbedder :: springRelaxInterEdges(SubGraph& gMaingraph)
  541. {
  542. // XXX obselete LAYOUT_ASSERT( &gMaingraph != NULL,
  543. // LayoutException(__FUNCTION__
  544. // ,LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  545. // ,"Input and Output graphml path"
  546. // ,"springRepelInterEdges"));
  547. RelaxInterEdges *relaxInterEdges = new RelaxInterEdges();
  548. std::cout<< "\n **************** Continuing inter edges *************** ";
  549. EdgeIterator eStart, eEnd;
  550. for (boost::tie(eStart, eEnd) = edges(gMaingraph); eStart != eEnd; ++eStart)
  551. {
  552. std::cout<< "\n **************** Continuing inter edges *************** ";
  553. VertexDescriptor vSource = source(*eStart, gMaingraph);
  554. VertexDescriptor vTarget = target(*eStart, gMaingraph);
  555. int iSourceGraphId = m_bGraphWrapper.getVertexClusterID(vSource,gMaingraph);
  556. int iTargetGraphId = m_bGraphWrapper.getVertexClusterID(vTarget,gMaingraph);
  557. if(iSourceGraphId == iTargetGraphId )
  558. {
  559. continue; // not an interedge
  560. }
  561. int iParentGraphId = 0;
  562. bool bParentFound = false , bIsSourceOuter = false;
  563. bool bISCase3OR4 = false;
  564. SubGraph* gSource = NULL , *gTarget = NULL ;
  565. // decide the type of interedge
  566. if(iSourceGraphId == 999 || iTargetGraphId == 999 )
  567. {
  568. if(iSourceGraphId == 999)
  569. {
  570. gSource = &gMaingraph;
  571. bIsSourceOuter = true; // check case 1,2 or 3,4
  572. }
  573. else if(iTargetGraphId == 999)
  574. {
  575. gTarget = &gMaingraph;
  576. bIsSourceOuter = false ;
  577. }
  578. }
  579. else
  580. {
  581. bISCase3OR4 = true;
  582. }
  583. if(!bISCase3OR4)
  584. {
  585. QQueue<SubGraph*> qSubgraphs; // a queue of subgraphs
  586. qSubgraphs.enqueue(&gMaingraph);
  587. SubGraph* gSubgraph1 = NULL;
  588. while(qSubgraphs.isEmpty() == false) // Iterating subgraphs till they exist
  589. {
  590. gSubgraph1 = qSubgraphs.dequeue();
  591. ChildrenIterator iterChild , iterChildEnd;
  592. for(boost::tie(iterChild , iterChildEnd) = gSubgraph1->children();
  593. iterChild != iterChildEnd;iterChild++)
  594. {
  595. SubGraph* gChildGraph = &(*iterChild);
  596. int iClusterId = m_bGraphWrapper.getGraphClusterID(*gChildGraph);
  597. // decide whether source is outer or inner
  598. if(bIsSourceOuter)
  599. {
  600. if(iClusterId == iTargetGraphId)
  601. {
  602. gTarget = gChildGraph;
  603. }
  604. }
  605. else if(!bIsSourceOuter)
  606. {
  607. if(iClusterId == iSourceGraphId)
  608. {
  609. gSource = gChildGraph;
  610. }
  611. }
  612. else
  613. {
  614. // case 3
  615. if(iClusterId == iTargetGraphId)
  616. {
  617. gTarget = gChildGraph;
  618. }
  619. if(iClusterId == iSourceGraphId)
  620. {
  621. gSource = gChildGraph;
  622. }
  623. }
  624. qSubgraphs.enqueue(gChildGraph);
  625. }
  626. }
  627. // get two graph objects of ids of source and target
  628. bool bIsSourceRoot = (*gSource).is_root(); // for checking purpose
  629. bool bIsTatgetRoot = (*gTarget).is_root();
  630. cout<<"\n Source Root " << bIsSourceRoot;
  631. cout<<"\n Target Root " << bIsTatgetRoot;
  632. int iMapGraphid1 = m_bGraphWrapper.getGraphClusterID(*gSource);
  633. int iMapGraphid2 = m_bGraphWrapper.getGraphClusterID(*gTarget);
  634. cout<<"\n Source ID "<<iMapGraphid1;
  635. cout<<"\n Target ID "<<iMapGraphid2;
  636. }
  637. SubGraph *gTempGraph = NULL ;
  638. // Case 1 and 2 *** VIMP Logic
  639. if(iSourceGraphId == 999 || iTargetGraphId == 999)
  640. {
  641. // case 1 and 2 starts here
  642. std::cout<< "\n ****************Case 1 or 2 detected : Continuing inter edges ";
  643. if(iSourceGraphId == 999)
  644. {
  645. bIsSourceOuter = true; // source is outer
  646. gTempGraph = (gTarget);
  647. while( !bParentFound )
  648. {
  649. SubGraph& gParentGraph = (*gTempGraph).parent();
  650. iParentGraphId = m_bGraphWrapper.getGraphClusterID(gParentGraph);
  651. if(iParentGraphId == 999)
  652. {
  653. bParentFound = true;
  654. }
  655. else
  656. {
  657. gTempGraph = & gParentGraph;
  658. }
  659. }
  660. //temp graph has outermost parent of target vertex
  661. // get cordinates of outer most parent and call do intersect with
  662. // edge cordinates if returns true call getIntersection points
  663. }
  664. else
  665. {
  666. gTempGraph = gSource;
  667. // find the parent graph of inner graphs
  668. while( !bParentFound )
  669. {
  670. SubGraph& gParentGraph = (*gTempGraph).parent();
  671. iParentGraphId = m_bGraphWrapper.getGraphClusterID(gParentGraph);
  672. if(iParentGraphId == 999)
  673. {
  674. bParentFound = true;
  675. }
  676. else
  677. {
  678. gTempGraph = & gParentGraph;
  679. }
  680. }
  681. }
  682. int iHeight,iLeftTopX,iLeftTopY,iWidth; // outer compartment of inner vertex
  683. iHeight = m_bGraphWrapper.getGraphHeight(*gTempGraph);
  684. iWidth = m_bGraphWrapper.getGraphWidth(*gTempGraph);
  685. iLeftTopX = m_bGraphWrapper.getGraphLeftTopCoordX(*gTempGraph);
  686. iLeftTopY = m_bGraphWrapper.getGraphLeftTopCoordY(*gTempGraph);
  687. int iOuterMostGraphID = m_bGraphWrapper.getGraphClusterID(*gTempGraph);
  688. cout<< "\n Outer Cordinates of Clusters " ;
  689. cout<<"\n Outer Graph ID "<<iOuterMostGraphID;
  690. cout<< "Height "<<iHeight;
  691. cout<< "Width "<<iWidth;
  692. cout<< "Lefttop X "<<iLeftTopX;
  693. cout<< "Lefttop Y "<<iLeftTopY;
  694. int iSourceX = m_bGraphWrapper.getVertexCenterCoordX(vSource,gMaingraph);
  695. int iSourceY = m_bGraphWrapper.getVertexCenterCoordY(vSource,gMaingraph);
  696. int iTargetX = m_bGraphWrapper.getVertexCenterCoordX(vTarget,gMaingraph);
  697. int iTargetY = m_bGraphWrapper.getVertexCenterCoordY(vTarget,gMaingraph);
  698. cout<< "\n Source X "<<iSourceX;
  699. cout<< "\n Source Y "<<iSourceY;
  700. cout<< "\n Target X "<<iTargetX;
  701. cout<< "\n Target Y "<<iTargetY;
  702. // Form 4 piars of P Q R S with Edge e ===> PQ , QR , RS , SP
  703. typedef boost::geometry::model::point<int, 2, boost::geometry::cs::cartesian> Points;
  704. boost::geometry::model::point<int, 2, boost::geometry::cs::cartesian> pP;
  705. boost::geometry::model::point<int, 2, boost::geometry::cs::cartesian>pQ;
  706. boost::geometry::model::point<int, 2, boost::geometry::cs::cartesian>pR;
  707. boost::geometry::model::point<int, 2, boost::geometry::cs::cartesian>pS;
  708. boost::geometry::model::point<int, 2, boost::geometry::cs::cartesian>pX;
  709. boost::geometry::model::point<int, 2, boost::geometry::cs::cartesian>pY;
  710. typedef boost::geometry::model::segment<Points> Segment;
  711. std::vector<Points> pOutput;
  712. pP.set<0>(iLeftTopX);
  713. pP.set<1>(iLeftTopY);
  714. pQ.set<0>(iLeftTopX);
  715. pQ.set<1>(iLeftTopY + iHeight);
  716. pR.set<0>(iLeftTopX + iWidth);
  717. pR.set<1>(iLeftTopY + iHeight);
  718. pS.set<0>(iLeftTopX+ iWidth);
  719. pS.set<1>(iLeftTopY);
  720. pX.set<0>(iSourceX);
  721. pX.set<1>(iSourceY);
  722. pY.set<0>(iTargetX);
  723. pY.set<1>(iTargetY);
  724. Segment PQ( pP,pQ );
  725. Segment QR( pQ,pR );
  726. Segment RS( pR,pS );
  727. Segment SP( pS,pP );
  728. Segment Edge (pX,pY);
  729. int iOuterIntersect[2] = {0,0}; // x and y
  730. bool bNoOuterIntersection = false;
  731. // need 5 line segments
  732. if(boost::geometry::intersects(Edge,PQ))
  733. {
  734. boost::geometry::intersection(Edge,PQ,pOutput);
  735. cout<<" \n Outer Clip Found with Edge PQ";
  736. }
  737. else if( boost::geometry::intersects(Edge,QR))
  738. {
  739. boost::geometry::intersection(Edge,QR,pOutput);
  740. cout<<" \n Outer Clip Found with Edge QR";
  741. }
  742. else
  743. {
  744. if(boost::geometry::intersects(Edge,RS))
  745. {
  746. boost::geometry::intersection(Edge,RS,pOutput);
  747. cout<<" \n Outer Clip Found with Edge RS";
  748. }
  749. else if(boost::geometry::intersects(Edge,SP))
  750. {
  751. boost::geometry::intersection(Edge,SP,pOutput);
  752. cout<<" \n Outer Clip Found with Edge SP";
  753. }
  754. else
  755. {
  756. // no intersection , not possible but handle
  757. cout<<"\n *** No Intersection in Outer *** Check Cluster cordinates" ;
  758. bNoOuterIntersection = true;
  759. }
  760. }
  761. if(!bNoOuterIntersection)
  762. {
  763. Points pIntersection = pOutput[0];
  764. iOuterIntersect[0] = pIntersection.get<0>();
  765. iOuterIntersect[1] = pIntersection.get<1>();
  766. }
  767. cout<<"\n Outer Intersection Points "<< " "<<iOuterIntersect[0]<< " "
  768. <<iOuterIntersect[1];
  769. // check whether it was case one or two, for case one calculate attractive force
  770. // for case two get inner clipping points.
  771. // checking for case
  772. bool bISCase1 = false;
  773. if(bIsSourceOuter)
  774. {
  775. SubGraph &gTemp = (*gTarget).parent();
  776. int iTempId = m_bGraphWrapper.getGraphClusterID(gTemp);
  777. if(iTempId == 999)
  778. {
  779. bISCase1 = true;
  780. }
  781. }
  782. else
  783. {
  784. SubGraph &gTemp = (*gSource).parent();
  785. int iTempId = m_bGraphWrapper.getGraphClusterID(gTemp);
  786. if(iTempId == 999)
  787. {
  788. bISCase1 = true;
  789. }
  790. }
  791. // call ISCase1
  792. if(bISCase1 )
  793. {
  794. if((!bNoOuterIntersection))
  795. {
  796. relaxInterEdges->interEdgesCaseOne(gMaingraph,
  797. vSource,vTarget,iOuterIntersect);
  798. }
  799. }
  800. else
  801. {
  802. cout<<"\n Case 2 detected ";
  803. // Case 2 here
  804. // calculate inner clipping points
  805. if(bIsSourceOuter) // Source is outer
  806. {
  807. relaxInterEdges->interEdgesCaseTwoSourceOuter(gMaingraph,vSource,vTarget,
  808. iOuterIntersect,gTarget);
  809. // Call cse2source is outer here
  810. }
  811. else
  812. {
  813. // Call case2sourceInner
  814. relaxInterEdges->interEdgesCaseTwoSourceInner(gMaingraph,vSource,vTarget,
  815. iOuterIntersect,gTarget);
  816. }
  817. }
  818. // ********************* Case 1 and 2 ends here *******************
  819. }
  820. else
  821. {
  822. cout<<"\n \n ***** Case 3 **** Detected";
  823. bool bIsOverlapCase = false;
  824. bIsSourceOuter = false ;
  825. QQueue<SubGraph*> qSubgraphs; // a queue of subgraphs
  826. qSubgraphs.enqueue(&gMaingraph);
  827. SubGraph* gSubgraph1 = NULL;
  828. while(qSubgraphs.isEmpty() == false) // Iterating subgraphs till they exist
  829. {
  830. gSubgraph1 = qSubgraphs.dequeue();
  831. ChildrenIterator iterChild , iterChildEnd;
  832. for(boost::tie(iterChild , iterChildEnd) = gSubgraph1->children();
  833. iterChild != iterChildEnd;iterChild++)
  834. {
  835. SubGraph* gChildGraph = &(*iterChild);
  836. int iClusterId = m_bGraphWrapper.getGraphClusterID(*gChildGraph);
  837. if(iClusterId == iTargetGraphId)
  838. {
  839. gTarget = gChildGraph;
  840. }
  841. if(iClusterId == iSourceGraphId)
  842. {
  843. gSource = gChildGraph;
  844. }
  845. qSubgraphs.enqueue(gChildGraph);
  846. }
  847. }
  848. int iSourceGraphHeight = m_bGraphWrapper.getGraphHeight(*gSource);
  849. int iSourceTopXLeft = m_bGraphWrapper.getGraphLeftTopCoordX(*gSource);
  850. int iSourceGraphWidth = m_bGraphWrapper.getGraphWidth(*gSource);
  851. int iSourceTopYLeft = m_bGraphWrapper.getGraphLeftTopCoordY(*gSource);
  852. int iTargetGraphHeight = m_bGraphWrapper.getGraphHeight(*gTarget);
  853. int iTargetTopXLeft = m_bGraphWrapper.getGraphLeftTopCoordX(*gTarget);
  854. int iTargetGraphWidth = m_bGraphWrapper.getGraphWidth(*gTarget);
  855. int iTargetTopYLeft = m_bGraphWrapper.getGraphLeftTopCoordY(*gTarget);
  856. int iInnerIntersectX = 0;
  857. int iInnerIntersectY = 0;
  858. int iOuterIntersectX = 0;
  859. int iOuterIntersectY = 0;
  860. // XXX unused
  861. Q_UNUSED(iTargetGraphHeight);
  862. Q_UNUSED(iInnerIntersectX);
  863. Q_UNUSED(iInnerIntersectY);
  864. Q_UNUSED(iSourceGraphHeight);
  865. Q_UNUSED(iOuterIntersectX);
  866. Q_UNUSED(iOuterIntersectY);
  867. // check overlap
  868. // 1 . Source outer
  869. if(((iSourceTopXLeft < iTargetTopXLeft) &&(iSourceTopXLeft + iSourceGraphWidth) >
  870. (iTargetTopXLeft +iTargetGraphWidth))||((iSourceTopXLeft == iTargetTopXLeft) &&
  871. (iSourceTopXLeft + iSourceGraphWidth) > (iTargetTopXLeft +iTargetGraphWidth)) ||
  872. ((iSourceTopXLeft < iTargetTopXLeft) &&(iSourceTopXLeft + iSourceGraphWidth) ==
  873. (iTargetTopXLeft +iTargetGraphWidth)) )
  874. {
  875. // source is outer
  876. // add check for y axis in both cases.
  877. if( iSourceTopYLeft < iTargetTopYLeft || iSourceTopYLeft == iTargetTopYLeft )
  878. {
  879. bIsOverlapCase = true;
  880. bIsSourceOuter = true;
  881. cout<< "\n Overlapping and Source is Outer with id "<< iSourceGraphId;
  882. }
  883. }
  884. else if(
  885. // XXX fix this and cocument whats going on here
  886. (
  887. (
  888. ((iSourceTopXLeft > iTargetTopXLeft)
  889. && (
  890. (iSourceTopXLeft + iSourceGraphWidth) < (iTargetTopXLeft +iTargetGraphWidth))
  891. )
  892. )
  893. ||
  894. (
  895. (
  896. (iSourceTopXLeft == iTargetTopXLeft)
  897. &&
  898. (
  899. (iSourceTopXLeft + iSourceGraphWidth) < (iTargetTopXLeft +iTargetGraphWidth)
  900. )
  901. )
  902. )
  903. ||
  904. (
  905. (
  906. (iSourceTopXLeft > iTargetTopXLeft)
  907. &&
  908. (
  909. (iSourceTopXLeft + iSourceGraphWidth) == (iTargetTopXLeft +iTargetGraphWidth)
  910. )
  911. )
  912. )
  913. )
  914. )
  915. {
  916. if( iTargetTopYLeft < iSourceTopYLeft || iSourceTopYLeft == iTargetTopYLeft )
  917. {
  918. // source is inner
  919. bIsOverlapCase = true;
  920. bIsSourceOuter = false;
  921. cout<< "\n Overlapping and Source is Inner with id "<<iTargetGraphId;
  922. }
  923. }
  924. else
  925. {
  926. bIsOverlapCase = false;
  927. cout<< "\n Non Overlapping ";
  928. // Non overlapping Case
  929. }
  930. // Start
  931. bParentFound = false;
  932. if(bIsOverlapCase)
  933. {
  934. if(bIsSourceOuter)
  935. {
  936. relaxInterEdges->OverLapCaseSourceOuter(gMaingraph,vSource,
  937. vTarget,gTarget,iSourceGraphId);
  938. // Call OverLapCaseSourceisOuter
  939. }
  940. else
  941. {
  942. relaxInterEdges->OverLapCaseSourceInner(gMaingraph,vSource,
  943. vTarget,gSource,iTargetGraphId);
  944. }
  945. }
  946. else
  947. {
  948. relaxInterEdges->nonOverLapCase(gMaingraph,vSource,vTarget,gSource,gTarget);
  949. // call NonOverLapcase
  950. }
  951. }
  952. }
  953. }
  954. void ClusteredSpringEmbedder :: springMoveClusters(SubGraph& gSubgraph)
  955. {
  956. Reingold *rein = new Reingold();
  957. QQueue<SubGraph*> qSubgraphs; // a queue of subgraphs
  958. qSubgraphs.enqueue(&gSubgraph );
  959. SubGraph* gSubgraph1 = NULL;
  960. while(qSubgraphs.isEmpty() == false) // Iterating subgraphs till they exist
  961. {
  962. gSubgraph1 = qSubgraphs.dequeue();
  963. ChildrenIterator iterChild , iterChildEnd;
  964. for(boost::tie(iterChild , iterChildEnd) = gSubgraph1->children();
  965. iterChild != iterChildEnd;iterChild++)
  966. {
  967. SubGraph* gChildGraph = &(*iterChild);
  968. // dividing by two for testing , remove later
  969. int iXClusterdisp = (m_bGraphWrapper.getClusterXDisplacement(*gChildGraph))/2;
  970. int iYClusterdisp = (m_bGraphWrapper.getClusterYDisplacement(*gChildGraph))/2;
  971. VertexDescriptor verAffected;
  972. VertexIterPair verIter;
  973. for(tie(verIter.first,verIter.second)=vertices(*gChildGraph)
  974. ;verIter.first!=verIter.second;++verIter.first)
  975. {
  976. verAffected = *verIter.first;
  977. int iXCoord = m_bGraphWrapper.getVertexCenterCoordX(verAffected,*gChildGraph);
  978. int iYCoord = m_bGraphWrapper.getVertexCenterCoordY(verAffected,*gChildGraph);
  979. m_bGraphWrapper.setVertexCenterCoordX(verAffected,*gChildGraph,
  980. iXCoord+iXClusterdisp);
  981. m_bGraphWrapper.setVertexCenterCoordY(verAffected,*gChildGraph,
  982. iYCoord+iYClusterdisp);
  983. }
  984. m_bGraphWrapper.setClusterXDisplacement(*gChildGraph,0);
  985. m_bGraphWrapper.setClusterYDisplacement(*gChildGraph,0);
  986. rein->setCompartMentProps(*gChildGraph,10);
  987. }
  988. }
  989. }
  990. void ClusteredSpringEmbedder:: springSetVerticesDisplacementZero()
  991. {
  992. // reset displacement to zero
  993. VertexDescriptor verAffected;
  994. VertexIterPair verIter;
  995. for(tie(verIter.first,verIter.second)=vertices(m_gMaingraph)
  996. ;verIter.first!=verIter.second;++verIter.first)
  997. {
  998. verAffected = *verIter.first;
  999. m_bGraphWrapper.setVertXDisp(0,verAffected,m_gMaingraph);
  1000. m_bGraphWrapper.setVertYDisp(0,verAffected,m_gMaingraph);
  1001. }
  1002. int iMainTopY = 0 ,iMainTopX = 0 ;
  1003. iMainTopX = m_bGraphWrapper.getGraphLeftTopCoordX(m_gMaingraph);
  1004. iMainTopY = m_bGraphWrapper.getGraphLeftTopCoordY(m_gMaingraph);
  1005. QQueue<SubGraph*> qSubgraphs; // a queue of subgraphs
  1006. qSubgraphs.enqueue(&m_gMaingraph );
  1007. SubGraph* gSubgraph1 = NULL;
  1008. while(qSubgraphs.isEmpty() == false) // Iterating subgraphs till they exist
  1009. {
  1010. gSubgraph1 = qSubgraphs.dequeue();
  1011. ChildrenIterator iterChild , iterChildEnd;
  1012. for(boost::tie(iterChild , iterChildEnd) = gSubgraph1->children();
  1013. iterChild != iterChildEnd;iterChild++)
  1014. {
  1015. SubGraph* gChildGraph = &(*iterChild);
  1016. if(boost::num_vertices(*gChildGraph) == 0)
  1017. {
  1018. m_bGraphWrapper.setGraphLeftTopCoordX(iMainTopX,*gChildGraph);
  1019. m_bGraphWrapper.setGraphLeftTopCoordY(iMainTopY,*gChildGraph);
  1020. }
  1021. }
  1022. }
  1023. }
  1024. void ClusteredSpringEmbedder:: springTestRepelClusterToCluster(SubGraph &gSubgraph)
  1025. {
  1026. // make default
  1027. BoostGraphWrapper bGraphWrapper;
  1028. VertexDescriptor verAffected;
  1029. // XXX unused
  1030. Q_UNUSED(verAffected);
  1031. VertexIterPair verIter;
  1032. QQueue<SubGraph*> qSubgraphs; // a queue of subgraphs
  1033. qSubgraphs.enqueue(&gSubgraph );
  1034. SubGraph* gSubgraph1 = NULL;
  1035. while(qSubgraphs.isEmpty() == false) // Iterating subgraphs till they exist
  1036. {
  1037. gSubgraph1 = qSubgraphs.dequeue();
  1038. ChildrenIterator iterChild , iterChildEnd;
  1039. for(boost::tie(iterChild , iterChildEnd) = gSubgraph1->children();
  1040. iterChild != iterChildEnd;iterChild++)
  1041. {
  1042. SubGraph* gChildGraph = &(*iterChild);
  1043. ChildrenIterator iterChildInner , iterChildEndInner;
  1044. for(boost::tie(iterChildInner , iterChildEndInner) = gSubgraph1->children();
  1045. iterChildInner != iterChildEndInner;iterChildInner++)
  1046. {
  1047. SubGraph* gGraph = &(*iterChildInner);
  1048. if(gChildGraph == gGraph)
  1049. {
  1050. continue;
  1051. }
  1052. double dVCenterX = bGraphWrapper.getGraphCenterCoordX(*gChildGraph);
  1053. double dVCenterY = bGraphWrapper.getGraphCenterCoordY(*gChildGraph);
  1054. double dVHeight = bGraphWrapper.getGraphHeight(*gChildGraph);
  1055. double dVWidth = bGraphWrapper.getGraphWidth(*gChildGraph);
  1056. double dVTopLeftX = bGraphWrapper.getGraphLeftTopCoordX(*gChildGraph);
  1057. double dVTopLeftY = bGraphWrapper.getGraphLeftTopCoordY(*gChildGraph);
  1058. double dUCenterX = bGraphWrapper.getGraphCenterCoordX(*gGraph);
  1059. double dUCenterY = bGraphWrapper.getGraphCenterCoordY(*gGraph);
  1060. double dUHeight = bGraphWrapper.getGraphHeight(*gGraph);
  1061. double dUWidth = bGraphWrapper.getGraphWidth(*gGraph);
  1062. double dUTopLeftX = bGraphWrapper.getGraphLeftTopCoordX(*gGraph);
  1063. double dUTopLeftY = bGraphWrapper.getGraphLeftTopCoordY(*gGraph);
  1064. // repel code here
  1065. typedef boost::geometry::model::point<double, 2, boost::geometry::cs::cartesian> Points;
  1066. // Find intersection to clusters
  1067. Points pP,pQ,pR,pS,pX,pY,pA,pB,pC,pD;
  1068. typedef boost::geometry::model::segment<Points> Segment;
  1069. std::vector<Points> pPintersect,pAintersect;
  1070. pP.set<0>(dVTopLeftX);
  1071. pP.set<1>(dVTopLeftY);
  1072. pQ.set<0>(dVTopLeftX);
  1073. pQ.set<1>(dVTopLeftY + dVHeight);
  1074. pR.set<0>(dVTopLeftX + dVWidth);
  1075. pR.set<1>(dVTopLeftY + dVHeight);
  1076. pS.set<0>(dVTopLeftX+ dVWidth);
  1077. pS.set<1>(dVTopLeftY);
  1078. pA.set<0>(dUTopLeftX);
  1079. pA.set<1>(dUTopLeftY);
  1080. pB.set<0>(dUTopLeftX);
  1081. pB.set<1>(dUTopLeftY + dUHeight);
  1082. pC.set<0>(dUTopLeftX + dUWidth);
  1083. pC.set<1>(dUTopLeftY + dUHeight);
  1084. pD.set<0>(dUTopLeftX+ dUWidth);
  1085. pD.set<1>(dUTopLeftY);
  1086. pX.set<0>(dVCenterX);
  1087. pX.set<1>(dVCenterY);
  1088. pY.set<0>(dUCenterX);
  1089. pY.set<1>(dUCenterY);
  1090. Segment PQ( pP,pQ );
  1091. Segment QR( pQ,pR );
  1092. Segment RS( pR,pS );
  1093. Segment SP( pS,pP );
  1094. Segment AB( pA,pB );
  1095. Segment BC( pB,pC );
  1096. Segment CD( pC,pD );
  1097. Segment DA( pD,pA );
  1098. Segment Edge (pX,pY);
  1099. bool bNoPIntersection = false,bNoAIntersection = false;
  1100. // Find intersecting edge
  1101. if(boost::geometry::intersects(Edge,PQ))
  1102. {
  1103. boost::geometry::intersection(Edge,PQ,pPintersect);
  1104. cout<<" \n Clip Found while Repelling Clusters to Clusters Edge PQ";
  1105. }
  1106. else if( boost::geometry::intersects(Edge,QR))
  1107. {
  1108. boost::geometry::intersection(Edge,QR,pPintersect);
  1109. cout<<" \n Clip Found while Repelling Clusters to Clusters Edge QR";
  1110. }
  1111. else
  1112. {
  1113. if(boost::geometry::intersects(Edge,RS))
  1114. {
  1115. boost::geometry::intersection(Edge,RS,pPintersect);
  1116. cout<<" \n Clip Found while Repelling Clusters to Clusters Edge RS";
  1117. }
  1118. else if(boost::geometry::intersects(Edge,SP))
  1119. {
  1120. boost::geometry::intersection(Edge,SP,pPintersect);
  1121. cout<<" \n Clip Found while Repelling Clusters to Clusters Edge SP";
  1122. }
  1123. else
  1124. {
  1125. // no intersection , not possible but handle
  1126. cout<<"\n *** No Intersection in Inner *** Check Cluster cordinates" ;
  1127. bNoPIntersection = true;
  1128. }
  1129. }
  1130. { // For separating two if else loops
  1131. if(boost::geometry::intersects(Edge,AB))
  1132. {
  1133. boost::geometry::intersection(Edge,AB,pAintersect);
  1134. cout<<" \n OverLapping Inner Clip Found with Edge AB";
  1135. }
  1136. else if( boost::geometry::intersects(Edge,BC))
  1137. {
  1138. boost::geometry::intersection(Edge,BC,pAintersect);
  1139. cout<<" \n OverLapping Inner Clip Found with Edge BC";
  1140. }
  1141. else
  1142. {
  1143. if(boost::geometry::intersects(Edge,CD))
  1144. {
  1145. boost::geometry::intersection(Edge,CD,pAintersect);
  1146. cout<<" \n OverLapping Inner Clip Found with Edge CD";
  1147. }
  1148. else if(boost::geometry::intersects(Edge,DA))
  1149. {
  1150. boost::geometry::intersection(Edge,DA,pAintersect);
  1151. cout<<" \n OverLapping Inner Clip Found with Edge DA";
  1152. }
  1153. else
  1154. {
  1155. cout<<"\n *** No Inner Intersection in Overlap *** Check Cluster cordinates" ;
  1156. bNoAIntersection = true;
  1157. }
  1158. }
  1159. }
  1160. if( !bNoAIntersection && !bNoPIntersection)
  1161. {
  1162. double dVIntersectX = 0 , dVIntersectY =0 ,dUIntersectY = 0
  1163. ,dUIntersectX = 0 ;
  1164. Points pPIntersection = pPintersect[0];
  1165. dVIntersectX = pPIntersection.get<0>();
  1166. dVIntersectY = pPIntersection.get<1>();
  1167. Points pAIntersection = pAintersect[0];
  1168. dUIntersectX = pAIntersection.get<0>();
  1169. dVIntersectY = pAIntersection.get<1>();
  1170. double dXDisp = dVIntersectX- dUIntersectX;
  1171. double dYDisp = dVIntersectY - dUIntersectY;
  1172. double dDist = fabs(dXDisp * dXDisp + dYDisp*dYDisp);
  1173. //double dDistance = sqrt(dCentreDist);
  1174. double dDx = 1000000 * dXDisp/dDist;
  1175. double dDy = 1000000 * dYDisp/dDist;
  1176. double dLen = dDx*dDx + dDy*dDy;
  1177. dLen = sqrt(fabs(dLen/2));
  1178. if(dLen < CLUSTER_TO_CLUSTER_REPULSION_RANGE) // do it small
  1179. {
  1180. int iTotalXDisp = m_bGraphWrapper.getClusterXDisplacement(*gChildGraph);
  1181. int iTotalYDisp = m_bGraphWrapper.getClusterYDisplacement(*gChildGraph);
  1182. // limit movement to some extent
  1183. if(dDx < 0)
  1184. {
  1185. dDx = std::max(- UNIT_CLUSTER_DISPLACEMENT,dDx);
  1186. }
  1187. else
  1188. {
  1189. dDx = std::min(UNIT_CLUSTER_DISPLACEMENT, dDx);
  1190. }
  1191. {
  1192. if(dDy < 0)
  1193. {
  1194. dDy = std::max(- UNIT_CLUSTER_DISPLACEMENT,dDy);
  1195. }
  1196. else
  1197. {
  1198. dDy = std::min(UNIT_CLUSTER_DISPLACEMENT, dDy);
  1199. }
  1200. }
  1201. iTotalXDisp += dDx/dLen*100;
  1202. iTotalYDisp += dDy/dLen*100;
  1203. m_bGraphWrapper.setClusterXDisplacement(*gChildGraph,iTotalXDisp);
  1204. m_bGraphWrapper.setClusterYDisplacement(*gChildGraph,iTotalYDisp);
  1205. }
  1206. }
  1207. }
  1208. qSubgraphs.enqueue(gChildGraph);
  1209. }
  1210. }
  1211. }