⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gemlayoutalgorithm.java

📁 用JGraph编的软件
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        Object[] cells = jgraph.getRoots();
        Object[] selectedCells = jgraph.getSelectionCells();
        
        CellView[] view = jgraph.getGraphLayoutCache().getMapping(cells,false);
        CellView[] selectedView = jgraph.getGraphLayoutCache().getMapping(
                                                           selectedCells,false);
        
        for (int i = 0; i < view.length; i++)
            if (view[i] instanceof VertexView){
                cellList.add(view[i]);
                if( applyToAll )
                    applyCellList.add(view[i]);
                
            }
            else if( view[i] instanceof EdgeView ){
                edgeList.add(view[i]);
            }
        if( !applyToAll )
            for( int i = 0; i < selectedView.length; i++ )
                if( selectedView[i] instanceof VertexView )
                    applyCellList.add(selectedView[i]);
    }
    
/******************************************************************************/
/**
 * Sets the initial Values, gained from the {@link #config configuration} 
 * into the Cells.
 * 
 * @return Because the progress dialog is allready visible during the 
 * initialisation, <b><code>true</code><b> is returned when cancel is pressed
 * on it.
 */
    private boolean initialize(){
        
        dlgProgress.setVisible(true);
        dlgProgress.setMessage(phaseName[PHASE_INITIALISATION]);
        
        int length = cellList.size();
        
        for( int i = 0; i < length; i++ ){
            
            CellView view = (CellView) cellList.get(i);
            
            initializeVertice(view);
            
            if( updateProgressDialog(PHASE_INITIALISATION,
                                     i,
                                     length) )
                                     
                return true; // canceled        
        }
        
        for( int i = 0; i < applyCellList.size(); i++ )
            computeLastImpulse( (CellView) applyCellList.get(i) );
            
        return false;    //not canceled
    }
    
/******************************************************************************/
/**
 * Sets the initial values for one Cell.
 * 
 * @param view Cell, the initial values should be set for.
 */
    private void initializeVertice(CellView view){
            Map attributes = view.getAttributes();
            if( attributes == null )
                attributes = new Hashtable();
                
            attributes.put(KEY_CAPTION,KEY_CAPTION);
            
            initPosition(view);                       

            if( isCluster(view) ){
                attributes.put(KEY_TEMPERATURE,
                               new Double(clusterInitTemperature));
            }
            else attributes.put(KEY_TEMPERATURE,
                                new Double(initTemperature));
            
            attributes.put(KEY_SKEWGAUGE,  new Double(0.0));
            attributes.put(KEY_CURRENT_IMPULSE,new Point2D.Double());
            attributes.put(KEY_LAST_IMPULSE   ,new Point2D.Double());
    }

/******************************************************************************/
/**
 * Runs the algorithm. First a running sequence is initialised. If 
 * {@link #shouldComputePermuation} is <b><code>true</code><b> then a new
 * permutation is computed for every round, else a single determined sequence is
 * established. After this for every Cell a current impulse is calculated, 
 * position and temperature is updated. This is done, until the graph is frozen,
 * a maximum on rounds is reached or cancel on the progress dialog is pressed.
 * 
 * @return <b><code>true</code></b> when cancel on the progress dialog is 
 * pressed
 * @see #computeCurrentImpulse(CellView)
 * @see #createPermutation(int)
 * @see #isFrozen()
 * @see #updatePosAndTemp(CellView)
 */
    private boolean calculate(){
        
        int length = applyCellList.size();
        int[] sequence = new int[length];
        boolean isCanceled = false;
        
        dlgProgress.setMessage(phaseName[PHASE_CALCULATION]);

        
        //case no permutation is desired, the series is computed one time only        
        if( !shouldComputePermutation ) //else is in the loop below
            for( int i = 0; i < length; i++ )
                sequence[i] = i;
        
        while( !isFrozen() && countRounds <= maxRounds && (!isCanceled) ){

            //case permutation is desired, it's calculated every round
            if( shouldComputePermutation ) 
                sequence = createPermutation(length);

            //loop over all nodes (order is in sequence)
            for( int i = 0; i < sequence.length; i++ ){
                CellView view = (CellView) applyCellList.get(sequence[i]);

                computeCurrentImpulse(view); //computes direction of impulse
                updatePosAndTemp(view);  //computes new position and temperature                
                
                if( updateProgressDialog(PHASE_CALCULATION,
                                         (countRounds*sequence.length)+i,
                                         maxRounds*sequence.length ) )
                    return true;
            }
            countRounds++;
        
        }
        return false;
    }
/******************************************************************************/
/**
 * Helps updating the progress dialog.
 * 
 * @param phase Identifies the phase, the algorithmis doing.
 * @param round current round, the algorithm is performing
 * @param maxRound maximum number of rounds, the algorithm could perform
 */
    private boolean updateProgressDialog(int phase, int round, int maxRound){
        
        int lowValue = 0;
        if( phase != 0 ) 
            lowValue = phaseLength[phase-1];
        
        int maxValue = phaseLength[phase];
        
        int width = maxValue - lowValue;
        
        int value = lowValue+(int)(width*((double)round/(double)maxRound));
        
        dlgProgress.setValue(value);
        
        return dlgProgress.isCanceled();
    }
    
/******************************************************************************/
/**
 * Calculates the current impulse for the given cell.
 * 
 * @param view Cell, the current impulse should be calculated
 * @see #computeImpulse(CellView)
 */    
    private void computeCurrentImpulse(CellView view){
        
        //gets the impulse for view
        Point2D.Double impulse = computeImpulse(view);
        
        //set result into node
        view.getAttributes().put(KEY_CURRENT_IMPULSE,impulse);
    }

/******************************************************************************/
/**
 * Calculates the last impulse for the given cell. This is only nesessary while
 * initializing the cells.
 * 
 * @param view Cell, the last impulse should be calculated
 * @see #computeImpulse(CellView)
 */
    private void computeLastImpulse(CellView view){
        
        //gets the impulse for view
        Point2D.Double impulse = computeImpulse(view);
        
        //set result into node
        view.getAttributes().put(KEY_LAST_IMPULSE,impulse);
    }

/******************************************************************************/
/**
 * Computes an Impulse representing a Force affecting the position of the given 
 * Cell. This impulse consists of a attracting force, pulling the cell to the
 * barycenter of all cells, a pulse with user defined length and random 
 * direction, a force repulsing cells from each other, a force attracting 
 * connected cells together, and, as a additional feature, a force, repulsing 
 * the current cell from overlapping cells.
 * 
 * @param view Cell, the impulse should be computed
 * @return impulse, transformed in a Point2D.Double-Instance.  
 */
    private Point2D.Double computeImpulse(CellView view){
        Point2D.Double impulse = new Point2D.Double();
        Point2D.Double pos     = getPosition(view);
        boolean isCellACluster = isCluster(view);
        
        //the more edges a cell have, the heavier the cell is
        double massIndex = getNodeWeight(view);
            
        //gets the barycenter of all cells
        Point2D.Double barycenter = computeBarycenter(cellList);
        
        //attracting force from the barycenter to every cell
        Point2D.Double gravitationForce = new Point2D.Double(
                    (barycenter.getX() - pos.getX()) * gravitation * massIndex,
                    (barycenter.getY() - pos.getY()) * gravitation * massIndex);
        
        //random glitch is added to force
        Point2D.Double randomImpulse = getRandomVector(randomImpulseRange);
        
        //repulsive Forces
        //from all nodes
        ArrayList repulsiveForce = new ArrayList();
        for( int i = 0 ; i < cellList.size(); i++ ) 
            if( cellList.get(i) != view ){//all cells except the actual view
//                CellView uView = (CellView) cellList.get(i);
//                if( !isCluster(uView)){
                
                Point2D.Double uPos = getPosition(i,cellList);
                
                double deltaX = (double)(pos.getX() - uPos.getX());
                double deltaY = (double)(pos.getY() - uPos.getY());
/*                
                double sgnX = MathExtensions.sgn(deltaX);
                double sgnY = MathExtensions.sgn(deltaY);
                
                if( isCellACluster && isCluster(uView) ){
                    deltaX -= uView.getBounds().getWidth() / 2.0;
                    deltaY -= uView.getBounds().getHeight()/ 2.0;
                }
                if( isCellACluster ){
                    deltaX -= view.getBounds().getWidth() / 2.0;
                    deltaY -= view.getBounds().getHeight()/ 2.0;
                }
                
                if( sgnX != MathExtensions.sgn(deltaX) ){
                    deltaX *= sgnX;
                }
                if( sgnY != MathExtensions.sgn(deltaY) ){
                    deltaY *= sgnY;
                }
*/              
                                
                double absDelta = MathExtensions.abs(deltaX,deltaY);
                
                if( absDelta > equalsNull ){
                    repulsiveForce.add(new Point2D.Double(
                        deltaX * ((prefEdgeLength * prefEdgeLength) / (absDelta * absDelta)),
                        deltaY * ((prefEdgeLength * prefEdgeLength) / (absDelta * absDelta))));
                }
//                } 
            } 
                
        //attractive Forces:
        //from all nodes that have an edge with view
        ArrayList relatives = getRelativesFrom(cellList,view);
        ArrayList attractiveForce = new ArrayList(relatives.size());
        for( int i = 0; i < relatives.size(); i++ ){

//            CellView child = (CellView) relatives.get(i);
            
            Point2D.Double cPos = getPosition(i,relatives);
        
            double deltaX = (double)(pos.getX() - cPos.getX());
            double deltaY = (double)(pos.getY() - cPos.getY());
/*          
            double sgnX = MathExtensions.sgn(deltaX);
            double sgnY = MathExtensions.sgn(deltaY);
            
            if( isCellACluster && isCluster( child )){
                deltaX -= child.getBounds().getWidth() / 2.0;
                deltaY -= child.getBounds().getHeight()/ 2.0;
            }
            if( isCellACluster ){
                deltaX -= view.getBounds().getWidth() / 2.0;
                deltaY -= view.getBounds().getHeight()/ 2.0;
            }
            
            if( sgnX != MathExtensions.sgn(deltaX) )
                deltaX *= sgnX;
            if( sgnY != MathExtensions.sgn(deltaY) )
                deltaY *= sgnY;
*/        
            double absDelta = MathExtensions.abs(deltaX,deltaY);
            
            attractiveForce.add(new Point2D.Double(
                deltaX * (( absDelta * absDelta ) / ( prefEdgeLength * prefEdgeLength * massIndex )),
                deltaY * (( absDelta * absDelta ) / ( prefEdgeLength * prefEdgeLength * massIndex ))));
        }
        
        
        /* the next part is NOT part of the original algorithm */
        /* it adds a force if the actual cell overlapps another cell */
        ArrayList forcesByOverlapping = new ArrayList();
        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -