Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

22 - Add optional control point to ConnectorSkeleton for curved edges #23

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions src-test/org/graphstream/ui/viewer_swing/test/TestCurvedEdges.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* This file is part of GraphStream <http://graphstream-project.org>.
*
* GraphStream is a library whose purpose is to handle static or dynamic
* graph, create them from scratch, file or any source and display them.
*
* This program is free software distributed under the terms of two licenses, the
* CeCILL-C license that fits European law, and the GNU Lesser General Public
* License. You can use, modify and/ or redistribute the software under the terms
* of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
* URL <http://www.cecill.info> or under the terms of the GNU LGPL as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
*/

/**
* @author Antoine Dutot <[email protected]>
* @author Guilhelm Savin <[email protected]>
* @author Hicham Brahimi <[email protected]>
*/

package org.graphstream.ui.viewer_swing.test;

import org.graphstream.graph.Edge;
import org.graphstream.graph.Graph;
import org.graphstream.graph.implementations.MultiGraph;
import org.graphstream.ui.geom.Point3;

public class TestCurvedEdges {
public static void main(String[] args) {
(new TestCurvedEdges()).run();
}

private void run() {
System.setProperty("org.graphstream.ui", "org.graphstream.ui.swing.util.Display");
Graph graph = new MultiGraph( "TestSprites" );

populateGraph(graph);

graph.setAttribute("ui.stylesheet", styleSheet);
graph.setAttribute("ui.antialias");
graph.display(false);
}

private void populateGraph(Graph graph) {
Edge edge;
graph.addNode("A");
graph.addNode("B");
graph.addNode("C");

graph.addEdge("AB", "A", "B", true);
graph.addEdge("BA", "B", "A", true);
graph.addEdge("BC", "B", "C", true);
graph.addEdge("CB", "C", "B", true);
graph.addEdge("CA", "C", "A", true);
graph.addEdge("AC", "A", "C", true);

// Replacing node D with the modelling of an intersection
graph.addNode("D1");
graph.addNode("D2");
graph.addNode("D3");
graph.addNode("D4");
graph.addNode("D5");
graph.addNode("D6");

graph.getNode("A").setAttribute("xyz", -1500d, -1100d, 0.0 );
graph.getNode("B").setAttribute("xyz", 1500d, -1100d, 0.0 );
graph.getNode("C").setAttribute("xyz", 100d, 1500d, 0.0 );
graph.getNode("D1").setAttribute("xyz", -100d, 300d, 0.0 );
graph.getNode("D2").setAttribute("xyz", 100d, 300d, 0.0 );
graph.getNode("D3").setAttribute("xyz", 250d, -100d, 0.0 );
graph.getNode("D4").setAttribute("xyz", 200d, -300d, 0.0 );
graph.getNode("D5").setAttribute("xyz", -200d, -300d, 0.0 );
graph.getNode("D6").setAttribute("xyz", -250d, -100d, 0.0 );

edge = graph.addEdge("CD1", "C", "D1", true);
edge.setAttribute("ui.control-point", new Point3(-100.0d, 500.0d, 0.0));
graph.addEdge("D2C", "D2", "C", true);

edge = graph.addEdge("BD3", "B", "D3", true);
edge.setAttribute("ui.control-point", new Point3(1000.0d, -600.0d, 0.0));
edge = graph.addEdge("D4B", "D4", "B", true);
edge.setAttribute("ui.control-point", new Point3(1000.0d, -600.0d, 0.0));

edge = graph.addEdge("AD5", "A", "D5", true);
edge.setAttribute("ui.control-point", new Point3(-1000.0d, -600.0d, 0.0));
edge = graph.addEdge("D6A", "D6", "A", true);
edge.setAttribute("ui.control-point", new Point3(-700.0d, -300.0d, 0.0));

edge = graph.addEdge("D1D6", "D1", "D6", true);
edge.setAttribute("ui.control-point", new Point3(-100.0d, 100.0d, 0.0));
edge = graph.addEdge("D1D4", "D1", "D4", true);
edge.setAttribute("ui.control-point", new Point3(0.0d, -0.0d, 0.0));
edge = graph.addEdge("D5D2", "D5", "D2", true);
edge.setAttribute("ui.control-point", new Point3(0.0d, 0.0d, 0.0));
edge = graph.addEdge("D3D2", "D3", "D2", true);
edge.setAttribute("ui.control-point", new Point3(100.0d, 100.0d, 0.0));
edge = graph.addEdge("D3D6", "D3", "D6", true);
edge.setAttribute("ui.control-point", new Point3(0.0d, 0.0d, 0.0));
edge = graph.addEdge("D5D4", "D5", "D4", true);
edge.setAttribute("ui.control-point", new Point3(0.0d, -240.0d, 0.0));
}

String styleSheet = "edge { shape: cubic-curve; }";
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public void buttonReleased( String id ) {}
private void moveSprites() {
sprites.forEach( s -> ((TestSprite)s).move() );
}


private void addSprites() {
sprites = new SpriteManager( graph );
Expand Down
9 changes: 9 additions & 0 deletions src/org/graphstream/ui/swing/renderer/ConnectorSkeleton.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class ConnectorSkeleton extends Skeleton implements AttributeUtils, org.g
private boolean isACurve;
private int aMulti;
private boolean isALoop;
private Point3 controlPoint;

public ConnectorSkeleton() {
this.points = new EdgePoints(2);
Expand Down Expand Up @@ -114,6 +115,10 @@ public void setPoly(Object aSetOfPoints) {
lengths = null ;
}
}

public void setControlPoint(Point3 controlPoint) {
this.controlPoint = controlPoint;
}

public void setPoly(Point3[] aSetOfPoints) {
if (points == null || points.size() != aSetOfPoints.length) {
Expand Down Expand Up @@ -193,6 +198,10 @@ public Point3 to() {
public Point3 from() {
return points.get(0);
}

public Point3 getControlPoint() {
return controlPoint;
}

/**
* Total length of the polyline defined by the points.
Expand Down
3 changes: 3 additions & 0 deletions src/org/graphstream/ui/swing/renderer/shape/Connector.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ public void configureConnectorForElement(DefaultCamera2D camera, GraphicEdge ele
if(element.hasAttribute("ui.points")) {
skel.setPoly(element.getAttribute("ui.points"));
} else {
if(element.hasAttribute("ui.control-point")) {
skel.setControlPoint(element.getAttribute("ui.control-point", Point3.class));
}
positionForLinesAndCurves( skel, element.from.getStyle(), element.from,
element.to, element.multi, element.getGroup() );
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,17 @@

package org.graphstream.ui.swing.renderer.shape.swing.advancedShapes;

import java.awt.Graphics2D;
import java.awt.geom.Path2D;

import org.graphstream.ui.geom.Point3;
import org.graphstream.ui.geom.Vector2;
import org.graphstream.ui.graphicGraph.GraphicElement;
import org.graphstream.ui.swing.Backend;
import org.graphstream.ui.view.camera.DefaultCamera2D;
import org.graphstream.ui.swing.renderer.Skeleton;
import org.graphstream.ui.swing.renderer.shape.swing.ShowCubics;
import org.graphstream.ui.swing.renderer.shape.swing.baseShapes.LineConnectorShape;
import org.graphstream.ui.view.camera.DefaultCamera2D;

import java.awt.Graphics2D;
import java.awt.geom.Path2D;

public class CubicCurveShape extends LineConnectorShape {
ShowCubics showCubics ;
Expand All @@ -56,12 +57,12 @@ public void make(Backend backend, DefaultCamera2D camera) {
}

private void make(DefaultCamera2D camera, double sox, double soy, double swx, double swy) {
if (skel.multi() > 1 || skel.isLoop()) // is a loop or a multi edge
makeMultiOrLoop(camera, sox, soy, swx, swy);
else if(skel.isPoly() && skel.size() == 4)
makeFromPoints(camera, sox, soy, swx, swy); // has points positions
if (skel.multi() > 1 || skel.isLoop()) // is a loop or a multi edge
makeMultiOrLoop(camera, sox, soy, swx, swy);
else if (skel.isPoly() && skel.size() == 4)
makeFromPoints(camera, sox, soy, swx, swy); // has points positions
else
makeSingle(camera, sox, soy, swx, swy); // is a single edge.
makeSingle(camera, sox, soy, swx, swy); // is a single edge.
}

private void makeMultiOrLoop(DefaultCamera2D camera, double sox, double soy, double swx, double swy) {
Expand Down Expand Up @@ -132,24 +133,32 @@ private void makeSingle(DefaultCamera2D camera, double sox, double soy, double s
Vector2 mainDir = new Vector2(skel.from(), skel.to());
double length = mainDir.length();
double angle = mainDir.y() / length;
double c1x = 0.0;
double c1y = 0.0;
double c2x = 0.0;
double c2y = 0.0;

if (angle > 0.707107f || angle < -0.707107f) {
// North or south.
c1x = fromx + mainDir.x() / 2;
c2x = c1x;
c1y = fromy;
c2y = toy;
}
else {
// East or west.
c1x = fromx;
c2x = tox;
c1y = fromy + mainDir.y() / 2;
c2y = c1y;
double c1x;
double c1y;
double c2x;
double c2y;

if (skel.getControlPoint() != null) {
Point3 controlPoint = skel.getControlPoint();
c1x = controlPoint.x;
c1y = controlPoint.y;
c2x = controlPoint.x;
c2y = controlPoint.y;
} else {
if (angle > 0.707107f || angle < -0.707107f) {
// North or south.
c1x = fromx + mainDir.x() / 2;
c1y = fromy;
c2x = c1x;
c2y = toy;
}
else {
// East or west.
c1x = fromx;
c1y = fromy + mainDir.y() / 2;
c2x = tox;
c2y = c1y;
}
}

theShape.reset();
Expand Down Expand Up @@ -192,7 +201,7 @@ public void render(Backend bck, DefaultCamera2D camera, GraphicElement element,
// g.setStroke( s );
// g.setColor( c );
// showCtrlPoints( g, camera )
// }
// }
}

@Override
Expand Down