Search in sources :

Example 1 with NubSpline

use of org.eclipse.elk.alg.layered.p5edges.splines.NubSpline in project elk by eclipse.

the class FinalSplineBendpointsCalculator method calculateBezierBendPoints.

/**
 * Collects all NUB control points computed for a spline segment and converts them to bezier control points.
 * Note that additional NUB control points <em>may</em> be added before the conversion is performed.
 */
private void calculateBezierBendPoints(final List<LEdge> edgeChain, final LEdge survivingEdge) {
    if (edgeChain.isEmpty()) {
        return;
    }
    // in this chain we will put all NURBS control points.
    final KVectorChain allCP = new KVectorChain();
    // add the computed bendpoints to the specified edge (default to the first edge in the edge chain)
    final LEdge edge = survivingEdge != null ? survivingEdge : edgeChain.get(0);
    // Process the source end of the edge-chain.
    final LPort sourcePort = edge.getSource();
    // edge must be the first edge of a chain of edges
    if (!SplineEdgeRouter.isQualifiedAsStartingNode(sourcePort.getNode())) {
        throw new IllegalArgumentException("The target node of the edge must be a normal node " + "or a northSouthPort.");
    }
    // add the source as the very first control point.
    allCP.addLast(sourcePort.getAbsoluteAnchor());
    // add an additional control point if the source port is a north or south port
    if (PortSide.SIDES_NORTH_SOUTH.contains(sourcePort.getSide())) {
        double y = sourcePort.getProperty(InternalProperties.SPLINE_NS_PORT_Y_COORD);
        KVector northSouthCP = new KVector(sourcePort.getAbsoluteAnchor().x, y);
        allCP.addLast(northSouthCP);
    }
    // copy the calculated control points for all spline segments,
    // possibly adding additional control points halfway between computed ones
    KVector lastCP = null;
    boolean addMidPoint = false;
    Iterator<LEdge> edgeIterator = edgeChain.iterator();
    while (edgeIterator.hasNext()) {
        LEdge currentEdge = edgeIterator.next();
        // read the stored bend-points for vertical segments, calculated by calculateNUBSBendPoint.
        final KVectorChain currentBendPoints = currentEdge.getBendPoints();
        if (!currentBendPoints.isEmpty()) {
            // get a more straight horizontal segment
            if (addMidPoint) {
                KVector halfway = lastCP.add(currentBendPoints.getFirst()).scale(ONE_HALF);
                allCP.addLast(halfway);
                addMidPoint = false;
            } else {
                addMidPoint = true;
            }
            lastCP = currentBendPoints.getLast().clone();
            allCP.addAll(currentBendPoints);
            currentBendPoints.clear();
        }
    }
    // finalize the spline
    LPort targetPort = edge.getTarget();
    // again, add an additional control point if the target port is a north or sout port
    if (PortSide.SIDES_NORTH_SOUTH.contains(targetPort.getSide())) {
        double y = targetPort.getProperty(InternalProperties.SPLINE_NS_PORT_Y_COORD);
        KVector northSouthCP = new KVector(targetPort.getAbsoluteAnchor().x, y);
        allCP.addLast(northSouthCP);
    }
    // finish with the target as last control point.
    allCP.addLast(targetPort.getAbsoluteAnchor());
    // insert straightening control points (if desired)
    if (splineRoutingMode == SplineRoutingMode.CONSERVATIVE) {
        // Add a control point for a straight segment at the very start and at the very end of a spline to prevent
        // the edge from colliding with self-loops or the like inside the margin of the node.
        // This also ensures the correct initial direction of the edge
        insertStraighteningControlPoints(allCP, sourcePort, targetPort);
    }
    // convert list of NUB control points to bezier control points
    final NubSpline nubSpline = new NubSpline(true, SplineEdgeRouter.SPLINE_DIMENSION, allCP);
    // ... and set them as bendpoints of the edge
    edge.getBendPoints().addAll(nubSpline.getBezierCP());
}
Also used : KVectorChain(org.eclipse.elk.core.math.KVectorChain) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) LPort(org.eclipse.elk.alg.layered.graph.LPort) NubSpline(org.eclipse.elk.alg.layered.p5edges.splines.NubSpline) KVector(org.eclipse.elk.core.math.KVector)

Example 2 with NubSpline

use of org.eclipse.elk.alg.layered.p5edges.splines.NubSpline in project elk by eclipse.

the class SplineSelfLoopRouter method modifyBendPoints.

/**
 * Turns a vector chain of orthogonal bend points into polyline bend points by cutting the corners.
 */
@Override
protected KVectorChain modifyBendPoints(final SelfLoopEdge slEdge, final EdgeRoutingDirection routingDirection, final KVectorChain bendPoints) {
    double edgeLabelDistance = LGraphUtil.getIndividualOrInherited(slEdge.getSLHyperLoop().getSLHolder().getLNode(), LayeredOptions.SPACING_EDGE_LABEL);
    // For the splines to be routed correctly, we also have to include the source and target positions, so we build
    // up the new list of bend points bit by bit
    KVectorChain splineBendPoints = new KVectorChain(relativePortAnchor(slEdge.getSLSource()));
    addSplineControlPoints(slEdge, routingDirection, bendPoints, splineBendPoints, edgeLabelDistance);
    splineBendPoints.add(relativePortAnchor(slEdge.getSLTarget()));
    return new NubSpline(true, DIM, splineBendPoints).getBezierCP();
}
Also used : KVectorChain(org.eclipse.elk.core.math.KVectorChain) NubSpline(org.eclipse.elk.alg.layered.p5edges.splines.NubSpline)

Aggregations

NubSpline (org.eclipse.elk.alg.layered.p5edges.splines.NubSpline)2 KVectorChain (org.eclipse.elk.core.math.KVectorChain)2 LEdge (org.eclipse.elk.alg.layered.graph.LEdge)1 LPort (org.eclipse.elk.alg.layered.graph.LPort)1 KVector (org.eclipse.elk.core.math.KVector)1