#include #include #include #include "ConeTree.h" LAYOUTPLUGIN(ConeTree,"Cone Tree (Carriere and Kazman)","David Auber","01/08/2002","Ok","1","0"); using namespace std; double ConeTree::treePlace3D(node n, STL_EXT_NS::hash_map *posRelX, STL_EXT_NS::hash_map *posRelY) { (*posRelX)[n]=0; (*posRelY)[n]=0; if (superGraph->outdeg(n)==0) {return 1.0;} if (superGraph->outdeg(n)==1) { Iterator *itN=superGraph->getOutNodes(n); node itn=itN->next(); delete itN; return treePlace3D(itn,posRelX,posRelY); } double maxRayon=0; double somRayon=0; double newRayon; double dAlpha; STL_EXT_NS::hash_map cache; int nbLeaves=0; Iterator *itN=superGraph->getOutNodes(n); for (;itN->hasNext();) { node itn=itN->next(); cache[itn]=2.0f*treePlace3D(itn,posRelX,posRelY); somRayon+=cache[itn]; if (cache[itn]/2>maxRayon) maxRayon=cache[itn]/2; if (superGraph->outdeg(itn)==0) nbLeaves++; } delete itN; //int toFree=somRayon-2*nbLeaves; dAlpha=2.0*M_PI/somRayon; newRayon=somRayon/(2.0f*M_PI); double alpha=0; if (superGraph->outdeg(n)==2) { itN=superGraph->getOutNodes(n); node itn=itN->next(); node itn2=itN->next(); double x1=-2*cache[itn]/2.0f; double x2=2*cache[itn2]/2.0f; double decal=(x2+x1)/2; (*posRelX)[itn]=-cache[itn]/2.0f-decal; (*posRelY)[itn]=0; (*posRelX)[itn2]=+cache[itn]/2.0f-decal; (*posRelY)[itn2]=0; maxRayon=(x2-x1)/2; delete itN; } else { itN=superGraph->getOutNodes(n); for (;itN->hasNext();) { node itn=itN->next(); alpha+=cache[itn]/2.0f*dAlpha; (*posRelX)[itn]=newRayon*cos(alpha); (*posRelY)[itn]=newRayon*sin(alpha); alpha+=cache[itn]/2.0f*dAlpha; } delete itN; } return newRayon+maxRayon; // return sqrt(((maxX-minX)/2.0f) * ((maxX-minX)/2.0f) + ((maxY-minY)/2.0f) * ((maxY-minY)/2.0f))/sqrt(2.0f); } void ConeTree::calcLayout(node n, STL_EXT_NS::hash_map *px, STL_EXT_NS::hash_map *py, double x, double y, int level) { layoutProxy->setNodeValue(n,Coord(x+(*px)[n],level,y+(*py)[n])); Iterator *it=superGraph->getOutNodes(n); for (;it->hasNext();) { node itn; itn=it->next(); calcLayout(itn,px,py,x+(*px)[n],y+(*py)[n] , level+2); } delete it; } ConeTree::ConeTree(PropertyContext *context):Layout(context) {} ConeTree::~ConeTree() {} bool ConeTree::run() { layoutProxy->setAllEdgeValue(vector(0)); STL_EXT_NS::hash_map posX; STL_EXT_NS::hash_map posY; getLocalProxy(superGraph,"viewSize")->setAllNodeValue(Size(1,1,1)); getLocalProxy(superGraph,"viewSize")->setAllEdgeValue(Size(0.125,0.125,0.5)); node startNode; Iterator *itN=superGraph->getNodes(); for (;itN->hasNext();) { node itn=itN->next(); if (superGraph->indeg(itn)==0) { startNode=itn; break; } }delete itN; treePlace3D(startNode,&posX,&posY); calcLayout(startNode,&posX,&posY,0,0,0); return true; } bool ConeTree::check(string &erreurMsg) { if (superGraph->isTree()) { erreurMsg=""; return true; } else { erreurMsg="The Graph must be a Tree"; return false; } } void ConeTree::reset() {}