use of org.eclipse.elk.core.math.KVectorChain in project elk by eclipse.
the class ElkGraphTransformer method getContour.
/**
* Given all source, bend and target points of an edge in correct order, this method computes all vertices needed to
* construct a polygonal {@link DCElement} for it.
*
* @param edgePoints
* All relevant points of an Edge as described above
* @param thickness
* Desired thickness of the edge
* @return List of vertices of the edge as a polygon considering the given thickness
*/
private KVectorChain getContour(final List<KVector> edgePoints, final double thickness) {
List<KVector> ccwPoints = Lists.newArrayList();
List<KVector> cwPoints = Lists.newArrayList();
double radius = thickness / 2;
int numberOfPoints = edgePoints.size();
// special case: first edge segment. Assumption an edge has at least two points
KVector predecessor;
KVector current = edgePoints.get(0);
KVector successor = edgePoints.get(1);
List<KVector> orthPoints = getOrthogonalPoints(current.x, current.y, successor.x, successor.y, radius);
ccwPoints.add(orthPoints.get(0));
cwPoints.add(orthPoints.get(1));
// normal case: bendpoints have a preceding and a succeeding neighbor
for (int i = 2; i < numberOfPoints; i++) {
predecessor = current;
current = successor;
successor = edgePoints.get(i);
orthPoints = getOrthogonalPoints(current.x, current.y, predecessor.x, predecessor.y, radius);
ccwPoints.add(orthPoints.get(1));
cwPoints.add(orthPoints.get(0));
orthPoints = getOrthogonalPoints(current.x, current.y, successor.x, successor.y, radius);
ccwPoints.add(orthPoints.get(0));
cwPoints.add(orthPoints.get(1));
}
// For the last point, consider the line connecting back to the previous point (the resulting orthogonal points
// will be in reversed order in the resulting list, though.).
orthPoints = getOrthogonalPoints(successor.x, successor.y, current.x, current.y, radius);
ccwPoints.add(orthPoints.get(1));
cwPoints.add(orthPoints.get(0));
// Compute the intersections of the line segments of the orthogonal points
KVectorChain ccwMerged = new KVectorChain();
List<KVector> cwMerged = Lists.newArrayList();
ccwMerged.add(ccwPoints.get(0));
for (int i = 1; i < ccwPoints.size() - 2; i += 2) {
KVector currentPoint = ccwPoints.get(i);
KVector intersectionPoint = computeIntersection(ccwPoints.get(i - 1), currentPoint, ccwPoints.get(i + 1), ccwPoints.get(i + 2));
// Keep currentPoint if lines are coincident (or parallel).
if (!Double.isFinite(intersectionPoint.x) || !Double.isFinite(intersectionPoint.y)) {
ccwMerged.add(currentPoint);
} else {
ccwMerged.add(intersectionPoint);
}
}
ccwMerged.add(ccwPoints.get(ccwPoints.size() - 1));
cwMerged.add(cwPoints.get(0));
for (int i = 1; i < cwPoints.size() - 2; i += 2) {
KVector currentPoint = cwPoints.get(i);
KVector intersectionPoint = computeIntersection(cwPoints.get(i - 1), currentPoint, cwPoints.get(i + 1), cwPoints.get(i + 2));
// Keep currentPoint if lines are coincident (or parallel).
if (!Double.isFinite(intersectionPoint.x) || !Double.isFinite(intersectionPoint.y)) {
cwMerged.add(currentPoint);
} else {
cwMerged.add(intersectionPoint);
}
}
cwMerged.add(cwPoints.get(cwPoints.size() - 1));
// merge lists (one of them has to be added in reverse order)
for (int i = cwMerged.size() - 1; i >= 0; i--) {
ccwMerged.add(cwMerged.get(i));
}
return ccwMerged;
}
use of org.eclipse.elk.core.math.KVectorChain in project elk by eclipse.
the class BreakingPointRemover method remove.
private void remove(final LGraph graph, final BPInfo bpi) {
// assemble the new edge route
KVectorChain newBends = new KVectorChain();
// depending on the edge routing style we have to act differently
switch(edgeRouting) {
// so far, only the intermediate nubsplines have been attached via properties
case SPLINES:
// gather the computed spline information
List<SplineSegment> s1 = bpi.nodeStartEdge.getProperty(InternalProperties.SPLINE_ROUTE_START);
List<SplineSegment> s2 = bpi.startEndEdge.getProperty(InternalProperties.SPLINE_ROUTE_START);
List<SplineSegment> s3 = bpi.originalEdge.getProperty(InternalProperties.SPLINE_ROUTE_START);
List<LEdge> e1 = bpi.nodeStartEdge.getProperty(InternalProperties.SPLINE_EDGE_CHAIN);
List<LEdge> e2 = bpi.startEndEdge.getProperty(InternalProperties.SPLINE_EDGE_CHAIN);
List<LEdge> e3 = bpi.originalEdge.getProperty(InternalProperties.SPLINE_EDGE_CHAIN);
// join them (... and remember to reverse some of the segments)
List<SplineSegment> joinedSegments = Lists.newArrayList();
joinedSegments.addAll(s1);
s2.forEach(s -> s.inverseOrder = true);
joinedSegments.addAll(Lists.reverse(s2));
joinedSegments.addAll(s3);
List<LEdge> joinedEdges = Lists.newArrayList();
joinedEdges.addAll(e1);
joinedEdges.addAll(Lists.reverse(e2));
joinedEdges.addAll(e3);
// transfer the information to the original edge
bpi.originalEdge.setProperty(InternalProperties.SPLINE_ROUTE_START, joinedSegments);
bpi.originalEdge.setProperty(InternalProperties.SPLINE_EDGE_CHAIN, joinedEdges);
bpi.originalEdge.setProperty(InternalProperties.SPLINE_SURVIVING_EDGE, bpi.originalEdge);
// cleanup
bpi.nodeStartEdge.setProperty(InternalProperties.SPLINE_ROUTE_START, null);
bpi.nodeStartEdge.setProperty(InternalProperties.SPLINE_EDGE_CHAIN, null);
bpi.startEndEdge.setProperty(InternalProperties.SPLINE_ROUTE_START, null);
bpi.startEndEdge.setProperty(InternalProperties.SPLINE_EDGE_CHAIN, null);
break;
// note that the positions of bpi.start and bpi.end must be added as bend points
case POLYLINE:
newBends.addAll(bpi.nodeStartEdge.getBendPoints());
newBends.add(bpi.start.getPosition());
newBends.addAll(Lists.reverse(bpi.startEndEdge.getBendPoints()));
newBends.add(bpi.end.getPosition());
newBends.addAll(bpi.originalEdge.getBendPoints());
break;
// of bpi.start and bpi.end can be dropped since they lie on a straight line
default:
// ORTHOGONAL
newBends.addAll(bpi.nodeStartEdge.getBendPoints());
newBends.addAll(Lists.reverse(bpi.startEndEdge.getBendPoints()));
newBends.addAll(bpi.originalEdge.getBendPoints());
}
// restore original edge
bpi.originalEdge.getBendPoints().clear();
bpi.originalEdge.getBendPoints().addAll(newBends);
bpi.originalEdge.setSource(bpi.nodeStartEdge.getSource());
// collect any created junction points (order can be arbitrary)
KVectorChain junctionPointsOne = bpi.nodeStartEdge.getProperty(LayeredOptions.JUNCTION_POINTS);
KVectorChain junctionPointsTwo = bpi.startEndEdge.getProperty(LayeredOptions.JUNCTION_POINTS);
KVectorChain junctionPointsThree = bpi.originalEdge.getProperty(LayeredOptions.JUNCTION_POINTS);
if (junctionPointsOne != null || junctionPointsTwo != null || junctionPointsThree != null) {
KVectorChain newJunctionPoints = new KVectorChain();
addNullSafe(newJunctionPoints, junctionPointsThree);
addNullSafe(newJunctionPoints, junctionPointsTwo);
addNullSafe(newJunctionPoints, junctionPointsOne);
bpi.originalEdge.setProperty(LayeredOptions.JUNCTION_POINTS, newJunctionPoints);
}
// remove all the dummy stuff
bpi.startEndEdge.setSource(null);
bpi.startEndEdge.setTarget(null);
bpi.nodeStartEdge.setSource(null);
bpi.nodeStartEdge.setTarget(null);
bpi.end.setLayer(null);
bpi.start.setLayer(null);
if (bpi.prev != null) {
remove(graph, bpi.prev);
}
}
use of org.eclipse.elk.core.math.KVectorChain in project elk by eclipse.
the class GmfLayoutEditPolicy method addEdgeLayout.
/**
* Adds an edge layout to the given command.
*
* @param command
* command to which an edge layout shall be added
* @param elkEdge
* edge with layout data
* @param connectionEditPart
* edit part to which layout is applied
* @param scale
* scale factor for coordinates
*/
private void addEdgeLayout(final GmfLayoutCommand command, final ElkEdge elkEdge, final ConnectionEditPart connectionEditPart, final double scale) {
if (connectionEditPart.getSource() != null && connectionEditPart.getTarget() != null) {
// create source terminal identifier
INodeEditPart sourceEditPart = (INodeEditPart) connectionEditPart.getSource();
ConnectionAnchor sourceAnchor;
if (sourceEditPart instanceof ConnectionEditPart) {
// if the edge source is a connection, don't consider the source point
sourceAnchor = new SlidableAnchor(sourceEditPart.getFigure());
} else {
KVector sourceRel = getRelativeSourcePoint(elkEdge);
sourceAnchor = new SlidableAnchor(sourceEditPart.getFigure(), new PrecisionPoint(sourceRel.x, sourceRel.y));
}
String sourceTerminal = sourceEditPart.mapConnectionAnchorToTerminal(sourceAnchor);
// create target terminal identifier
INodeEditPart targetEditPart = (INodeEditPart) connectionEditPart.getTarget();
ConnectionAnchor targetAnchor;
if (targetEditPart instanceof ConnectionEditPart) {
// if the edge target is a connection, don't consider the target point
targetAnchor = new SlidableAnchor(targetEditPart.getFigure());
} else {
KVector targetRel = getRelativeTargetPoint(elkEdge);
targetAnchor = new SlidableAnchor(targetEditPart.getFigure(), new PrecisionPoint(targetRel.x, targetRel.y));
}
String targetTerminal = targetEditPart.mapConnectionAnchorToTerminal(targetAnchor);
PointList bendPoints = getBendPoints(elkEdge, connectionEditPart.getFigure(), scale);
// check whether the connection is a note attachment to an edge, then remove bend points
if (sourceEditPart instanceof ConnectionEditPart || targetEditPart instanceof ConnectionEditPart) {
while (bendPoints.size() > 2) {
bendPoints.removePoint(1);
}
}
// retrieve junction points and transform them to absolute coordinates
KVectorChain junctionPoints = elkEdge.getProperty(CoreOptions.JUNCTION_POINTS);
String serializedJP = null;
if (junctionPoints != null) {
for (KVector point : junctionPoints) {
ElkUtil.toAbsolute(point, elkEdge.getContainingNode());
}
serializedJP = junctionPoints.toString();
}
command.addEdgeLayout((Edge) connectionEditPart.getModel(), bendPoints, sourceTerminal, targetTerminal, serializedJP);
}
}
use of org.eclipse.elk.core.math.KVectorChain in project elk by eclipse.
the class PropertyTest method testPropertyDefaultIDataObject.
@Test
public void testPropertyDefaultIDataObject() {
// all IDataObjects
KVector v = new KVector(2, 3);
testPropertyObject(v);
KVectorChain vc = new KVectorChain(v, v);
testPropertyObject(vc);
ElkPadding ep = new ElkPadding(2, 3);
testPropertyObject(ep);
ElkMargin em = new ElkMargin(3, 2);
testPropertyObject(em);
}
use of org.eclipse.elk.core.math.KVectorChain in project elk by eclipse.
the class ElkMathTest method testPathIntersects.
@Test
public void testPathIntersects() {
ElkRectangle rect = new ElkRectangle(23, 14, 20, 20);
KVectorChain path = new KVectorChain();
path.add(24, 15);
path.add(27, 20);
path.add(39, 30);
path.add(29, 19);
assertTrue(!ElkMath.intersects(rect, path));
// on border
KVectorChain path2 = new KVectorChain(path);
path2.add(23, 14);
assertTrue(!ElkMath.intersects(rect, path2));
// cross
path.add(10, 10);
assertTrue(ElkMath.intersects(rect, path));
}
Aggregations