Author: paperwing
Date: 2012-01-30 15:09:23 -0800 (Mon, 30 Jan 2012)
New Revision: 28158
Modified:
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/RenderArcEdgesProcedure.java
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/shapes/EdgeShapeDrawer.java
Log:
corrected arc edge drawing algorithms to alternate 180 degrees every other edge
level for aesthetic effect, updated arc edge default facings. For self edges,
the first edge faces towards the positive x direction and is orthogonal to the
z axis, with preceding edges being radially distributed about the y axis. In
process of debugging self-edges for sparse edges, used for dashed and dotted
edges.
Modified:
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/RenderArcEdgesProcedure.java
===================================================================
---
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/RenderArcEdgesProcedure.java
2012-01-30 22:07:39 UTC (rev 28157)
+++
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/RenderArcEdgesProcedure.java
2012-01-30 23:09:23 UTC (rev 28158)
@@ -41,19 +41,23 @@
private static final RenderColor DEFAULT_HOVER_COLOR =
new RenderColor(0.5, 0.5, 0.7);
- private static final float DASHED_EDGE_RADIUS = 0.007f;
- private static final float DASHED_EDGE_LENGTH = 0.04f;
- private static final float DASHED_EDGE_SPACING = 0.10f;
+ private static final float DASHED_EDGE_RADIUS = 0.006f;
+ private static final float DASHED_EDGE_LENGTH = 0.05f;
+ private static final float DASHED_EDGE_SPACING = 0.07f;
- private static final float DOTTED_EDGE_RADIUS = 0.012f;
- private static final float DOTTED_EDGE_SPACING = 0.08f;
+ private static final float DOTTED_EDGE_RADIUS = 0.017f;
+ private static final float DOTTED_EDGE_SPACING = 0.057f;
- private static final double ARC_EDGE_MINIMUM_RADIUS = 0.1;
+ private static final double ARC_SELF_EDGE_MINIMUM_RADIUS = 0.04;
+ private static final double ARC_SELF_EDGE_RADIUS_FACTOR = 0.007;
private static final Vector3 X_UNIT_VECTOR = new Vector3(1, 0, 0);
private static final Vector3 Y_UNIT_VECTOR = new Vector3(0, 1, 0);
private static final Vector3 Z_UNIT_VECTOR = new Vector3(0, 0, 1);
+ private static final Vector3 SELF_EDGE_DEFAULT_FACING = new Vector3(1,
0, 0);
+ private static final Vector3 SELF_EDGE_DEFAULT_ROTATION_AXIS = new
Vector3(0, 1, 0);
+
/**
* The number of straight segments used to approximate a curved edge
*/
@@ -290,22 +294,24 @@
Vector3 startOffset = start.subtract(circleCenter);
Vector3 endOffset = end.subtract(circleCenter);
- Vector3 rotationNormal = startOffset.cross(endOffset);
+ Vector3 rotationNormal;
- // TODO: Check if this is a good place to put this
- if (rotationNormal.magnitude() < MIN_LENGTH) {
- rotationNormal = startOffset.cross(Y_UNIT_VECTOR);
+ // Self-edge suspected, use default normal to avoid division by 0
+ if (start.distanceSquared(end) < MIN_LENGTH) {
+ rotationNormal = startOffset.cross(new Vector3(0, 1,
0));
+ } else {
+ rotationNormal = startOffset.cross(endOffset);
}
double arcAngle = startOffset.angle(endOffset);
+ double rotation = arcAngle / segments;
- // Invert the angle if needed
+ // Invert the angle and the rotation directin if needed
if (invert) {
- arcAngle = -2 * Math.PI + arcAngle;
+ arcAngle = 2 * Math.PI - arcAngle;
+ rotation = -rotation;
}
- double rotation = arcAngle / segments;
-
for (int i = 0; i < segments; i++) {
arcCoordinates[i] =
circleCenter.plus(startOffset.rotate(rotationNormal, rotation * i));
}
@@ -350,14 +356,21 @@
// less than or equal to 180 degrees to a reflex angle
if (invert) {
arcAngle = 2 * Math.PI - arcAngle;
- segmentAngle = -segmentAngle;
}
int halfIncrements = Math.abs((int) (arcAngle / segmentAngle /
2));
- // Add 2 to include the start and end points
- Vector3[] arcCoordinates = new Vector3[2 * halfIncrements + 2];
- Vector3 rotationNormal = startOffset.cross(endOffset);
+ // The number of points includes the start and end points, but
the number is odd
+ // to keep from calculating the middle point twice
+ Vector3[] arcCoordinates = new Vector3[2 * halfIncrements + 1];
+ Vector3 rotationNormal;
+
+ // Self-edge suspected, use default normal to avoid division by 0
+ if (start.distanceSquared(end) < MIN_LENGTH) {
+ rotationNormal = startOffset.cross(new Vector3(0, -1,
0));
+ } else {
+ rotationNormal = startOffset.cross(endOffset);
+ }
Vector3 centerCurvePointOffset = startOffset.rotate(
rotationNormal, arcAngle / 2);
@@ -365,18 +378,16 @@
// Manually add the first point
arcCoordinates[0] = start.copy();
- // TODO: Current implementation includes the middle point
twice, though it is not
- // noticeable
-
// Points between the first node and the center point
for (int i = 0; i < halfIncrements; i++) {
arcCoordinates[(halfIncrements - i)] =
circleCenter.plus(
centerCurvePointOffset.rotate(rotationNormal, -segmentAngle * i));
}
- // Points between the center point and the second node
- for (int i = 0; i < halfIncrements; i++) {
- arcCoordinates[(halfIncrements + i) + 1] =
circleCenter.plus(
+ // Points between the center point and the second node. Start
at i = 1
+ // to keep from calculating the middle point twice
+ for (int i = 1; i < halfIncrements; i++) {
+ arcCoordinates[(halfIncrements + i)] =
circleCenter.plus(
centerCurvePointOffset.rotate(rotationNormal, segmentAngle * i));
}
@@ -386,45 +397,7 @@
return arcCoordinates;
}
-
/**
- * Return a 2-tuple containing the appropriate radius for the circular
edge arc, as well
- * as how much it should be rotated in the node-to-node displacement
axis.
- *
- * @param container The EdgeViewContainer object holding additional
information about the
- * edge, including its index amongst the other edges that connect the
same pair of nodes
- * @param selfEdge Whether or not the edge leads from a node to itself
- */
- private double[] findArcEdgeMetrics(EdgeViewContainer container) {
-
- // Level 1 has 2^2 - 1^1 = 3 edges, level 2 has 3^3 - 2^2 = 5,
level 3 has 7
- int edgeLevel = (int) (Math.sqrt((double)
container.edgeNumber));
- int maxLevel = (int) (Math.sqrt((double)
container.totalCoincidentEdges));
-
- int edgesInLevel = edgeLevel * 2 + 1;
-
-
- double curvedEdgeRadius;
-
- if (container.selfEdge) {
- // For self-edges, want greater edge level -> greater
radius
- curvedEdgeRadius = ARC_EDGE_MINIMUM_RADIUS / (0.5 +
(double) 1.5 / Math.pow(edgeLevel, 2));
- } else {
- // For regular edges, want greater edge level ->
smaller radius (more curvature)
- curvedEdgeRadius =
container.start.distance(container.end) * (0.5 + (double) 1.5 /
Math.pow(edgeLevel, 2));
- }
-
- // The outmost level is usually not completed
- if (edgeLevel == maxLevel) {
- edgesInLevel = (int) (container.totalCoincidentEdges -
Math.pow(maxLevel, 2) + 1);
- }
-
- double edgeRadialAngle = (double) (container.edgeNumber -
Math.pow(edgeLevel, 2)) / edgesInLevel * Math.PI * 2;
-
- return new double[]{curvedEdgeRadius, edgeRadialAngle};
- }
-
- /**
* Finds the center of a circle passing through 2 points, rotated about
the displacement axis
* by a certain angle.
*
@@ -440,7 +413,8 @@
double angle = edgeMetrics[1];
if (container.selfEdge) {
- Vector3 offset =
Z_UNIT_VECTOR.multiply(radius).rotate(Y_UNIT_VECTOR, angle);
+ Vector3 offset = (new Vector3(1, 0,
0)).multiply(radius).rotate(
+ (new Vector3(0, 1, 0)), angle);
return container.start.plus(offset);
} else {
@@ -462,7 +436,7 @@
double nearCornerAngle = Math.PI / 2 - (arcAngle / 2);
// Set the angle of rotation along the node-to-node
displacement axis
- Vector3 targetDirection = new Vector3(0, 0, 1);
+ Vector3 targetDirection = new Vector3(0, 1, 0);
targetDirection = targetDirection.rotate(displacement,
angle);
// Offset vector that points from first node to the
circle's center
@@ -474,6 +448,48 @@
}
}
+ /**
+ * Return a 2-tuple containing the appropriate radius for the circular
edge arc, as well
+ * as how much it should be rotated in the node-to-node displacement
axis.
+ *
+ * @param container The EdgeViewContainer object holding additional
information about the
+ * edge, including its index amongst the other edges that connect the
same pair of nodes
+ * @param selfEdge Whether or not the edge leads from a node to itself
+ */
+ private double[] findArcEdgeMetrics(EdgeViewContainer container) {
+
+ // Level 1 has 2^2 - 1^1 = 3 edges, level 2 has 3^3 - 2^2 = 5,
level 3 has 7
+ int edgeLevel = (int) (Math.sqrt((double)
container.edgeNumber));
+ int maxLevel = (int) (Math.sqrt((double)
container.totalCoincidentEdges));
+
+ int edgesInLevel = edgeLevel * 2 + 1;
+
+ double curvedEdgeRadius;
+
+ if (container.selfEdge) {
+ // For self-edges, want greater edge level -> greater
radius
+ curvedEdgeRadius = ARC_SELF_EDGE_MINIMUM_RADIUS
+ + ARC_SELF_EDGE_RADIUS_FACTOR *
Math.pow(edgeLevel, 1.2);
+ } else {
+ // For regular edges, want greater edge level ->
smaller radius (more curvature)
+ curvedEdgeRadius =
container.start.distance(container.end) * (0.5 + (double) 1.5 /
Math.pow(edgeLevel, 2));
+ }
+
+ // The outmost level is usually not completed
+ if (edgeLevel == maxLevel) {
+ edgesInLevel = (int) (container.totalCoincidentEdges -
Math.pow(maxLevel, 2) + 1);
+ }
+
+ double edgeRadialAngle = (double) (container.edgeNumber -
Math.pow(edgeLevel, 2)) / edgesInLevel * Math.PI * 2;
+
+ // Flip the angle by 180 degrees for every other edge level for
aesthetic effect
+ if (edgeLevel % 2 == 0) {
+ edgeRadialAngle = Math.PI - edgeRadialAngle;
+ }
+
+ return new double[]{curvedEdgeRadius, edgeRadialAngle};
+ }
+
private void drawRegularArc(GL2 gl, Vector3[] points) {
Vector3 displacement;
Modified:
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/shapes/EdgeShapeDrawer.java
===================================================================
---
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/shapes/EdgeShapeDrawer.java
2012-01-30 22:07:39 UTC (rev 28157)
+++
csplugins/trunk/toronto/yuedong/paperwing-impl/src/main/java/org/cytoscape/paperwing/internal/rendering/shapes/EdgeShapeDrawer.java
2012-01-30 23:09:23 UTC (rev 28158)
@@ -14,7 +14,7 @@
private static int REGULAR_CYLINDER_SLICES = 4;
private static int REGULAR_CYLINDER_STACKS = 1;
- private static int DASHED_CYLINDER_SLICES = 4;
+ private static int DASHED_CYLINDER_SLICES = 3;
private static int DASHED_CYLINDER_STACKS = 1;
public static enum EdgeShapeType {
@@ -100,8 +100,7 @@
double length = 1.0 / Math.sqrt(2);
gl.glNewList(listIndex, GL2.GL_COMPILE);
- glu.gluCylinder(quadric, length, length, length,
- 4, 1);
+ glu.gluSphere(quadric, length / 2, 4, 4);
gl.glEndList();
segmentLists.put(EdgeShapeType.DOTTED, listIndex);
--
You received this message because you are subscribed to the Google Groups
"cytoscape-cvs" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/cytoscape-cvs?hl=en.