VisClient/org/hfbk/vis/VisNodeLayouter.java

Go to the documentation of this file.
00001 package org.hfbk.vis;
00002 
00003 
00004 import java.util.List;
00005 
00006 import org.hfbk.vis.visnode.VisNode;
00007 import org.lwjgl.util.vector.Vector3f;
00008 
00018 public class VisNodeLayouter {
00019 
00020 
00030         public static void layOut(VisNode node, float spreadX, float spreadY, float spreadZ){
00031                 List<VisNode> childs=node.children;
00032                 int n=childs.size();
00033                 
00034                 if (node.layoutLocked || childs.size()==0) //we have finished this in the past
00035                         return; 
00036                 //we need to buffer the new positions 
00037                 //else the partially updated nodes affects the ones still to update 
00038                 Vector3f[] updatePos=new Vector3f[n];
00039 
00040                 for (int i=0; i<n; i++) //fill with cloned positions
00041                         updatePos[i]=new Vector3f(childs.get(i).position);
00042                 
00043                 //repelling force between node pairs
00044                 for (int i=0; i<n; i++){
00045                         VisNode ni=childs.get(i);
00046                         for (int j=i+1; j<n; j++){ //every pair is only considered once
00047                                 VisNode nj=childs.get(j);
00048                                 Vector3f diff=Vector3f.sub(ni.position,nj.position,null);
00049                                 
00050                                 float r=diff.lengthSquared();
00051                                 diff.scale(2f/r);
00052                                 diff.x*=spreadX; diff.y*=spreadY; diff.z*=spreadZ;
00053                                 
00054                                 Vector3f.add(updatePos[i], diff, updatePos[i]);
00055                                 Vector3f.sub(updatePos[j], diff, updatePos[j]);
00056                         }
00057                 }
00058                 
00059                 //attracting force to parent node
00060                 for (int i=0; i<updatePos.length; i++){                                         
00061                         VisNode ni=childs.get(i);
00062                         
00063                         updatePos[i].scale(.95f); //attract
00064                         
00065                         //float d=updatePos[i].length()/10;
00066                         //updatePos[i].scale(1/d);  //repell if too near
00067                         
00068                         node.layoutLocked=true; //if we move nothing, we are finished forever.                  
00069                         //we do some stickyness so the nodes will not creep forever but settle down
00070                         float speed=Vector3f.sub(updatePos[i], childs.get(i).position,null).length();
00071                         if (speed >.1f) {//if fast enough update the node.
00072                                 ni.position=updatePos[i];
00073                                 node.layoutLocked=false; //we still need to layout
00074                         }
00075                         
00076                 }
00077         }               
00078         
00079 }

Generated on Tue Apr 7 17:57:22 2009 for visclient by  doxygen 1.5.1