Search in sources :

Example 1 with ForceVectorNodeLayoutData

use of org.gephi.layout.plugin.ForceVectorNodeLayoutData in project gephi by gephi.

the class FruchtermanReingold method goAlgo.

@Override
public void goAlgo() {
    this.graph = graphModel.getGraphVisible();
    graph.readLock();
    try {
        Node[] nodes = graph.getNodes().toArray();
        Edge[] edges = graph.getEdges().toArray();
        for (Node n : nodes) {
            if (n.getLayoutData() == null || !(n.getLayoutData() instanceof ForceVectorNodeLayoutData)) {
                n.setLayoutData(new ForceVectorNodeLayoutData());
            }
            ForceVectorNodeLayoutData layoutData = n.getLayoutData();
            layoutData.dx = 0;
            layoutData.dy = 0;
        }
        // Déplacement limite : on peut le calibrer...
        float maxDisplace = (float) (Math.sqrt(AREA_MULTIPLICATOR * area) / 10f);
        // La variable k, l'idée principale du layout.
        float k = (float) Math.sqrt((AREA_MULTIPLICATOR * area) / (1f + nodes.length));
        for (Node N1 : nodes) {
            for (Node N2 : nodes) {
                // On fait toutes les paires de noeuds
                if (N1 != N2) {
                    // distance en x entre les deux noeuds
                    float xDist = N1.x() - N2.x();
                    float yDist = N1.y() - N2.y();
                    // distance tout court
                    float dist = (float) Math.sqrt(xDist * xDist + yDist * yDist);
                    if (dist > 0) {
                        // Force de répulsion
                        float repulsiveF = k * k / dist;
                        ForceVectorNodeLayoutData layoutData = N1.getLayoutData();
                        // on l'applique...
                        layoutData.dx += xDist / dist * repulsiveF;
                        layoutData.dy += yDist / dist * repulsiveF;
                    }
                }
            }
        }
        for (Edge E : edges) {
            // Idem, pour tous les noeuds on applique la force d'attraction
            Node Nf = E.getSource();
            Node Nt = E.getTarget();
            float xDist = Nf.x() - Nt.x();
            float yDist = Nf.y() - Nt.y();
            float dist = (float) Math.sqrt(xDist * xDist + yDist * yDist);
            float attractiveF = dist * dist / k;
            if (dist > 0) {
                ForceVectorNodeLayoutData sourceLayoutData = Nf.getLayoutData();
                ForceVectorNodeLayoutData targetLayoutData = Nt.getLayoutData();
                sourceLayoutData.dx -= xDist / dist * attractiveF;
                sourceLayoutData.dy -= yDist / dist * attractiveF;
                targetLayoutData.dx += xDist / dist * attractiveF;
                targetLayoutData.dy += yDist / dist * attractiveF;
            }
        }
        // gravity
        for (Node n : nodes) {
            ForceVectorNodeLayoutData layoutData = n.getLayoutData();
            float d = (float) Math.sqrt(n.x() * n.x() + n.y() * n.y());
            float gf = 0.01f * k * (float) gravity * d;
            layoutData.dx -= gf * n.x() / d;
            layoutData.dy -= gf * n.y() / d;
        }
        // speed
        for (Node n : nodes) {
            ForceVectorNodeLayoutData layoutData = n.getLayoutData();
            layoutData.dx *= speed / SPEED_DIVISOR;
            layoutData.dy *= speed / SPEED_DIVISOR;
        }
        for (Node n : nodes) {
            // Maintenant on applique le déplacement calculé sur les noeuds.
            // nb : le déplacement à chaque passe "instantanné" correspond à la force : c'est une sorte d'accélération.
            ForceVectorNodeLayoutData layoutData = n.getLayoutData();
            float xDist = layoutData.dx;
            float yDist = layoutData.dy;
            float dist = (float) Math.sqrt(layoutData.dx * layoutData.dx + layoutData.dy * layoutData.dy);
            if (dist > 0 && !n.isFixed()) {
                float limitedDist = Math.min(maxDisplace * ((float) speed / SPEED_DIVISOR), dist);
                n.setX(n.x() + xDist / dist * limitedDist);
                n.setY(n.y() + yDist / dist * limitedDist);
            }
        }
    } finally {
        graph.readUnlockAll();
    }
}
Also used : ForceVectorNodeLayoutData(org.gephi.layout.plugin.ForceVectorNodeLayoutData) Node(org.gephi.graph.api.Node) Edge(org.gephi.graph.api.Edge)

Example 2 with ForceVectorNodeLayoutData

use of org.gephi.layout.plugin.ForceVectorNodeLayoutData in project gephi by gephi.

the class ForceAtlasLayout method goAlgo.

@Override
public void goAlgo() {
    this.graph = graphModel.getGraphVisible();
    graph.readLock();
    boolean isDynamicWeight = graphModel.getEdgeTable().getColumn("weight").isDynamic();
    Interval interval = graph.getView().getTimeInterval();
    try {
        Node[] nodes = graph.getNodes().toArray();
        Edge[] edges = graph.getEdges().toArray();
        for (Node n : nodes) {
            if (n.getLayoutData() == null || !(n.getLayoutData() instanceof ForceVectorNodeLayoutData)) {
                n.setLayoutData(new ForceVectorNodeLayoutData());
            }
        }
        for (Node n : nodes) {
            ForceVectorNodeLayoutData layoutData = n.getLayoutData();
            layoutData.old_dx = layoutData.dx;
            layoutData.old_dy = layoutData.dy;
            layoutData.dx *= inertia;
            layoutData.dy *= inertia;
        }
        // repulsion
        if (isAdjustSizes()) {
            for (Node n1 : nodes) {
                for (Node n2 : nodes) {
                    if (n1 != n2) {
                        ForceVectorUtils.fcBiRepulsor_noCollide(n1, n2, getRepulsionStrength() * (1 + graph.getDegree(n1)) * (1 + graph.getDegree(n2)));
                    }
                }
            }
        } else {
            for (Node n1 : nodes) {
                for (Node n2 : nodes) {
                    if (n1 != n2) {
                        ForceVectorUtils.fcBiRepulsor(n1, n2, getRepulsionStrength() * (1 + graph.getDegree(n1)) * (1 + graph.getDegree(n2)));
                    }
                }
            }
        }
        // attraction
        if (isAdjustSizes()) {
            if (isOutboundAttractionDistribution()) {
                for (Edge e : edges) {
                    Node nf = e.getSource();
                    Node nt = e.getTarget();
                    double bonus = (nf.isFixed() || nt.isFixed()) ? (100) : (1);
                    bonus *= getEdgeWeight(e, isDynamicWeight, interval);
                    ForceVectorUtils.fcBiAttractor_noCollide(nf, nt, bonus * getAttractionStrength() / (1 + graph.getDegree(nf)));
                }
            } else {
                for (Edge e : edges) {
                    Node nf = e.getSource();
                    Node nt = e.getTarget();
                    double bonus = (nf.isFixed() || nt.isFixed()) ? (100) : (1);
                    bonus *= getEdgeWeight(e, isDynamicWeight, interval);
                    ForceVectorUtils.fcBiAttractor_noCollide(nf, nt, bonus * getAttractionStrength());
                }
            }
        } else {
            if (isOutboundAttractionDistribution()) {
                for (Edge e : edges) {
                    Node nf = e.getSource();
                    Node nt = e.getTarget();
                    double bonus = (nf.isFixed() || nt.isFixed()) ? (100) : (1);
                    bonus *= getEdgeWeight(e, isDynamicWeight, interval);
                    ForceVectorUtils.fcBiAttractor(nf, nt, bonus * getAttractionStrength() / (1 + graph.getDegree(nf)));
                }
            } else {
                for (Edge e : edges) {
                    Node nf = e.getSource();
                    Node nt = e.getTarget();
                    double bonus = (nf.isFixed() || nt.isFixed()) ? (100) : (1);
                    bonus *= getEdgeWeight(e, isDynamicWeight, interval);
                    ForceVectorUtils.fcBiAttractor(nf, nt, bonus * getAttractionStrength());
                }
            }
        }
        // gravity
        for (Node n : nodes) {
            float nx = n.x();
            float ny = n.y();
            double d = 0.0001 + Math.sqrt(nx * nx + ny * ny);
            double gf = 0.0001 * getGravity() * d;
            ForceVectorNodeLayoutData layoutData = n.getLayoutData();
            layoutData.dx -= gf * nx / d;
            layoutData.dy -= gf * ny / d;
        }
        // speed
        if (isFreezeBalance()) {
            for (Node n : nodes) {
                ForceVectorNodeLayoutData layoutData = n.getLayoutData();
                layoutData.dx *= getSpeed() * 10f;
                layoutData.dy *= getSpeed() * 10f;
            }
        } else {
            for (Node n : nodes) {
                ForceVectorNodeLayoutData layoutData = n.getLayoutData();
                layoutData.dx *= getSpeed();
                layoutData.dy *= getSpeed();
            }
        }
        // apply forces
        for (Node n : nodes) {
            ForceVectorNodeLayoutData nLayout = n.getLayoutData();
            if (!n.isFixed()) {
                double d = 0.0001 + Math.sqrt(nLayout.dx * nLayout.dx + nLayout.dy * nLayout.dy);
                float ratio;
                if (isFreezeBalance()) {
                    nLayout.freeze = (float) (getFreezeInertia() * nLayout.freeze + (1 - getFreezeInertia()) * 0.1 * getFreezeStrength() * (Math.sqrt(Math.sqrt((nLayout.old_dx - nLayout.dx) * (nLayout.old_dx - nLayout.dx) + (nLayout.old_dy - nLayout.dy) * (nLayout.old_dy - nLayout.dy)))));
                    ratio = (float) Math.min((d / (d * (1f + nLayout.freeze))), getMaxDisplacement() / d);
                } else {
                    ratio = (float) Math.min(1, getMaxDisplacement() / d);
                }
                nLayout.dx *= ratio / getCooling();
                nLayout.dy *= ratio / getCooling();
                float x = n.x() + nLayout.dx;
                float y = n.y() + nLayout.dy;
                n.setX(x);
                n.setY(y);
            }
        }
    } finally {
        graph.readUnlockAll();
    }
}
Also used : ForceVectorNodeLayoutData(org.gephi.layout.plugin.ForceVectorNodeLayoutData) Node(org.gephi.graph.api.Node) Edge(org.gephi.graph.api.Edge) Interval(org.gephi.graph.api.Interval)

Aggregations

Edge (org.gephi.graph.api.Edge)2 Node (org.gephi.graph.api.Node)2 ForceVectorNodeLayoutData (org.gephi.layout.plugin.ForceVectorNodeLayoutData)2 Interval (org.gephi.graph.api.Interval)1