Search in sources :

Example 11 with KVector

use of org.eclipse.elk.core.math.KVector in project elk by eclipse.

the class NaiveMinST method createSpanningTree.

/**
 * Creates a minimum spanning tree for a graph using the cost function specified in the constructor.
 * @param tEdges the edges of the graph
 * @param root the root node to start the spanning tree
 * @param costFunction a function returning a cost value for a {@link TEdge}
 * @param debugOutputFile file name for debug SVG. Debug output will be deactivated if this is null.
 * @return the spanning tree
 */
public static Tree<KVector> createSpanningTree(final Set<TEdge> tEdges, final KVector root, final ICostFunction costFunction, final String debugOutputFile) {
    // determine edge weights
    Map<TEdge, Double> weight = Maps.newHashMap();
    for (TEdge edge : tEdges) {
        weight.put(edge, costFunction.cost(edge));
    }
    // sort edges by weight
    List<TEdge> edgeList = Lists.newArrayList(tEdges);
    edgeList.sort((TEdge e1, TEdge e2) -> weight.get(e1).compareTo(weight.get(e2)));
    // preserves order
    Set<TEdge> edges = Sets.newLinkedHashSet(edgeList);
    // iteratively add cheapest edge where one node is contained in current tree and one is new
    Tree<KVector> minST = new Tree<KVector>(root);
    Map<KVector, Tree<KVector>> treeNodes = Maps.newHashMap();
    treeNodes.put(root, minST);
    // debug output ----------------------------------------------------------------------------------------------
    SVGImage svg = new SVGImage(debugOutputFile);
    // elkjs-exclude-start
    svg.addGroups("e", "t");
    for (TEdge e : edges) {
        svg.g("e").addLine(e.u.x, e.u.y, e.v.x, e.v.y, "stroke=\"black\" stroke-width=\"1\"");
        svg.g("t").addElementStr("<text x=\"" + (e.u.x + e.v.x) / 2 + "\" y=\"" + (e.u.y + e.v.y) / 2 + "\" fill=\"blue\"" + " font-size=\"20px\">" + String.format("%.2f", weight.get(e)) + "</text>");
    }
    svg.isave();
    while (!edges.isEmpty()) {
        TEdge nextEdge = null;
        KVector nextNode = null;
        KVector nodeInTree = null;
        double minWeight = Double.POSITIVE_INFINITY;
        for (TEdge edge : edges) {
            if (weight.get(edge) <= minWeight) {
                if (treeNodes.containsKey(edge.u) && !treeNodes.containsKey(edge.v)) {
                    nextNode = edge.v;
                    nodeInTree = edge.u;
                    nextEdge = edge;
                    // because edges is sorted we don't have to look any further
                    break;
                }
                if (treeNodes.containsKey(edge.v)) {
                    if (!treeNodes.containsKey(edge.u)) {
                        nextNode = edge.u;
                        nodeInTree = edge.v;
                        nextEdge = edge;
                        // because edges is sorted we don't have to look any further
                        break;
                    }
                }
            }
        }
        // connects a new node to the tree.
        if (nextEdge == null) {
            break;
        }
        // add the new node to the spanning tree
        Tree<KVector> subTree = new Tree<KVector>(nextNode);
        treeNodes.get(nodeInTree).children.add(subTree);
        treeNodes.put(nextNode, subTree);
        edges.remove(nextEdge);
        // debug output -------------------------------------------------------------------------------------------
        svg.g("e").addLine(nextEdge.u.x, nextEdge.u.y, nextEdge.v.x, nextEdge.v.y, "stroke=\"red\" stroke-width=\"3\"");
        svg.isave();
    // --------------------------------------------------------------------------------------------------------
    }
    return minST;
}
Also used : KVector(org.eclipse.elk.core.math.KVector) SVGImage(org.eclipse.elk.alg.common.utils.SVGImage)

Example 12 with KVector

use of org.eclipse.elk.core.math.KVector in project elk by eclipse.

the class DepthFirstCompaction method compactTree.

/**
 * Recursive function to compact a tree depth-first.
 * @param tree root of a tree
 */
private static void compactTree(final Tree<Node> tree) {
    // first compact the children of the current node
    tree.children.forEach(DepthFirstCompaction::compactTree);
    // remove underlap between root and its children
    for (Tree<Node> child : tree.children) {
        // find the direction and distance the subtree has to be moved to close the gap to the root node
        KVector compactionVector = tree.node.vertex.clone().sub(child.node.vertex);
        if (orthogonalCompaction) {
            ElkRectangle rt = tree.node.rect;
            ElkRectangle rc = child.node.rect;
            // restrict the compaction vector to its larger coordinate
            if (Math.abs(compactionVector.x) >= Math.abs(compactionVector.y)) {
                compactionVector.y = 0;
                // scale compaction vector to orthogonal distance between tree and child
                if (rc.y + rc.height > rt.y && rc.y < rt.y + rt.height) {
                    // overlap in vertical dimension
                    compactionVector.scaleToLength(Math.max(rt.x - (rc.x + rc.width), rc.x - (rt.x + rt.width)));
                }
            } else {
                compactionVector.x = 0;
                // scale compaction vector to orthogonal distance between tree and child
                if (rc.x + rc.width > rt.x && rc.x < rt.x + rt.width) {
                    // overlap in horizontal dimension
                    compactionVector.scaleToLength(Math.max(rt.y - (rc.y + rc.height), rc.y - (rt.y + rt.height)));
                }
            }
        } else {
            compactionVector.scaleToLength(tree.node.underlap(child.node));
        }
        // determine the maximum distance the subtree can be moved without collision, i.e. the minimum underlap
        double minUnderlap = compactionVector.length();
        // find minimum underlap between any node in the child and any other node in the rest of the
        // tree in compaction direction
        minUnderlap = getMinUnderlap(root, child, minUnderlap, compactionVector);
        // use the minimum underlap to move whole subtree
        compactionVector.scaleToLength(minUnderlap);
        translateSubtree(child, compactionVector);
        debugOut(tree, child);
    }
}
Also used : KVector(org.eclipse.elk.core.math.KVector) ElkRectangle(org.eclipse.elk.core.math.ElkRectangle)

Example 13 with KVector

use of org.eclipse.elk.core.math.KVector in project elk by eclipse.

the class SVGImage method addRect.

public void addRect(final double x, final double y, final double w, final double h, final String attributes) {
    if (debug) {
        addElementStr("<rect x=\"" + x + "\" y=\"" + y + "\" width=\"" + w + "\" height=\"" + h + "\" " + attributes + " />");
        updateViewBox(new KVector(x, y), new KVector(x + w, y + h));
    }
}
Also used : KVector(org.eclipse.elk.core.math.KVector)

Example 14 with KVector

use of org.eclipse.elk.core.math.KVector in project elk by eclipse.

the class TTriangle method calculateCircumcenter.

/**
 * Determines the center of the circumscribed circle of the triangle.
 *
 * @return the center point of the circumcircle
 */
private KVector calculateCircumcenter() {
    KVector ab = b.clone().sub(a);
    KVector ac = c.clone().sub(a);
    KVector bc = c.clone().sub(b);
    double e = ab.x * (a.x + b.x) + ab.y * (a.y + b.y);
    double f = ac.x * (a.x + c.x) + ac.y * (a.y + c.y);
    double g = 2 * (ab.x * bc.y - ab.y * bc.x);
    double px = (ac.y * e - ab.y * f) / g;
    double py = (ab.x * f - ac.x * e) / g;
    return new KVector(px, py);
}
Also used : KVector(org.eclipse.elk.core.math.KVector)

Example 15 with KVector

use of org.eclipse.elk.core.math.KVector in project elk by eclipse.

the class DebugUtil method drawHitboxes.

/**
 * For debugging. Writes hitboxes to svg.
 *
 * @param fileName
 *          filename.
 */
public static void drawHitboxes(final CGraph cGraph, final String fileName) {
    // determine viewBox
    KVector topLeft = new KVector(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
    KVector bottomRight = new KVector(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
    for (CNode cNode : cGraph.cNodes) {
        topLeft.x = Math.min(topLeft.x, cNode.hitbox.x);
        topLeft.y = Math.min(topLeft.y, cNode.hitbox.y);
        bottomRight.x = Math.max(bottomRight.x, cNode.hitbox.x + cNode.hitbox.width);
        bottomRight.y = Math.max(bottomRight.y, cNode.hitbox.y + cNode.hitbox.height);
    }
    KVector size = bottomRight.clone().sub(topLeft);
    // drawing hitboxes to svg
    PrintWriter out;
    try {
        out = new PrintWriter(new FileWriter(fileName));
        out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        out.println("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\"" + "  viewBox=\"" + (topLeft.x) + " " + (topLeft.y) + " " + size.x + " " + size.y + "\">");
        out.println("<defs><marker id=\"markerArrow\" markerWidth=\"10\" " + "markerHeight=\"10\" refX=\"0\" refY=\"3\" orient=\"auto\">" + "  <path d=\"M0,0 L0,6 L9,3 z\" style=\"fill: #000000;\" />" + "</marker></defs>");
        for (CNode cNode : cGraph.cNodes) {
            // the node's representation
            out.println(cNode.getDebugSVG());
            // the constraints
            for (CNode inc : cNode.constraints) {
                out.println("<line x1=\"" + (inc.hitbox.x) + "\" y1=\"" + (inc.hitbox.y + inc.hitbox.height / 2) + "\" x2=\"" + (cNode.hitbox.x + cNode.hitbox.width) + "\" y2=\"" + (cNode.hitbox.y + cNode.hitbox.height / 2) + "\" stroke=\"black\" opacity=\"0.4\"" + " style=\"marker-end: url(#markerArrow);\" />");
            }
        }
        out.println("</svg>");
        out.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Also used : CNode(org.eclipse.elk.alg.common.compaction.oned.CNode) FileWriter(java.io.FileWriter) IOException(java.io.IOException) KVector(org.eclipse.elk.core.math.KVector) PrintWriter(java.io.PrintWriter)

Aggregations

KVector (org.eclipse.elk.core.math.KVector)292 KVectorChain (org.eclipse.elk.core.math.KVectorChain)52 ElkNode (org.eclipse.elk.graph.ElkNode)49 LNode (org.eclipse.elk.alg.layered.graph.LNode)39 LPort (org.eclipse.elk.alg.layered.graph.LPort)37 ElkRectangle (org.eclipse.elk.core.math.ElkRectangle)36 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)35 Test (org.junit.Test)30 ElkEdge (org.eclipse.elk.graph.ElkEdge)28 ElkLabel (org.eclipse.elk.graph.ElkLabel)27 ElkEdgeSection (org.eclipse.elk.graph.ElkEdgeSection)26 ElkPadding (org.eclipse.elk.core.math.ElkPadding)25 LLabel (org.eclipse.elk.alg.layered.graph.LLabel)20 PortSide (org.eclipse.elk.core.options.PortSide)19 ElkPort (org.eclipse.elk.graph.ElkPort)18 SizeConstraint (org.eclipse.elk.core.options.SizeConstraint)17 LGraph (org.eclipse.elk.alg.layered.graph.LGraph)15 ArrayList (java.util.ArrayList)13 Layer (org.eclipse.elk.alg.layered.graph.Layer)12 LMargin (org.eclipse.elk.alg.layered.graph.LMargin)11