Author: kono
Date: 2012-05-08 16:48:36 -0700 (Tue, 08 May 2012)
New Revision: 29163
Modified:
core3/impl/trunk/ding-impl/ding-presentation-impl/src/main/java/org/cytoscape/ding/impl/HandleImpl.java
core3/impl/trunk/edge-bundler-impl/src/main/java/org/cytoscape/edge/bundler/internal/EdgeBundlerRunner.java
core3/impl/trunk/edge-bundler-impl/src/main/java/org/cytoscape/edge/bundler/internal/EdgeBundlerTask.java
Log:
fixes #961 NaN problem caused by rounding error had been fixed. Now handles
are always set to valid locations.
Modified:
core3/impl/trunk/ding-impl/ding-presentation-impl/src/main/java/org/cytoscape/ding/impl/HandleImpl.java
===================================================================
---
core3/impl/trunk/ding-impl/ding-presentation-impl/src/main/java/org/cytoscape/ding/impl/HandleImpl.java
2012-05-08 23:46:01 UTC (rev 29162)
+++
core3/impl/trunk/ding-impl/ding-presentation-impl/src/main/java/org/cytoscape/ding/impl/HandleImpl.java
2012-05-08 23:48:36 UTC (rev 29163)
@@ -18,9 +18,9 @@
private static final String DELIMITER =",";
- private Double cosTheta = 0.5d;
- private Double sinTheta = 0.5d;
- private Double ratio = 0.5;
+ private double cosTheta = Double.NaN;
+ private double sinTheta = Double.NaN;
+ private double ratio = Double.NaN;
// Original handle location
private double x = 0;
@@ -89,13 +89,15 @@
// Distance from source to target (Edge length)
final double v1x = tX - sX;
final double v1y = tY - sY;
- final double dist1 = Math.sqrt(Math.pow(v1x, 2) + Math.pow(v1y,
2));
+// final double dist1 = Math.sqrt(Math.pow(v1x, 2) + Math.pow(v1y,
2));
+ final double dist1 = Point2D.Double.distance(sX, sY, tX, tY);
// Vector v2
// Distance from source to current handle
final double v2x = hX - sX;
final double v2y = hY - sY;
- final double dist2 = Math.sqrt(Math.pow(v2x, 2) + Math.pow(v2y,
2));
+// final double dist2 = Math.sqrt(Math.pow(v2x, 2) + Math.pow(v2y,
2));
+ final double dist2 = Point2D.Double.distance(sX, sY, hX, hY);
// Ratio of vector lengths
ratio = dist2/dist1;
@@ -104,8 +106,12 @@
final double dotProduct = (v1x * v2x) + (v1y * v2y);
cosTheta = dotProduct/(dist1*dist2);
+ // Avoid rounding problem
+ if(cosTheta>1.0d)
+ cosTheta = 1.0d;
+
// Theta is the angle between v1 and v2
- final double theta = Math.acos(cosTheta);
+ double theta = Math.acos(cosTheta);
sinTheta = Math.sin(theta);
// System.out.println("\n\n## Dot prod = " + dotProduct);
@@ -116,6 +122,10 @@
final Point2D validate = convert(sX, sY, tX, tY);
if(Math.abs(validate.getX()-hX) > 2 ||
Math.abs(validate.getY()-hY) > 2)
sinTheta = -sinTheta;
+
+ // Validate
+ if(theta == Double.NaN ||sinTheta == Double.NaN)
+ throw new IllegalStateException("Invalid angle: " +
theta +". Cuased by cos(theta) = " + cosTheta);
}
/**
@@ -129,7 +139,6 @@
*/
private Point2D convert(double sX, double sY,double tX, double tY ) {
final Point2D newPoint = new Point2D.Double();
-
// Original edge vector v = (vx, vy). (from source to target)
final double vx = tX - sX;
final double vy = tY - sY;
@@ -150,7 +159,6 @@
return newPoint;
}
-
/**
@@ -158,20 +166,18 @@
*/
@Override
public String getSerializableString() {
- if(cosTheta == null || sinTheta == null || ratio == null)
- return null;
- return cosTheta.toString() + DELIMITER + sinTheta.toString() +
DELIMITER + ratio;
+ return cosTheta + DELIMITER + sinTheta + DELIMITER + ratio;
}
- private void setCos(final Double cos) {
+ private void setCos(final double cos) {
this.cosTheta = cos;
}
- private void setSin(final Double sin) {
+ private void setSin(final double sin) {
this.sinTheta = sin;
}
- private void setRatio(final Double ratio) {
+ private void setRatio(final double ratio) {
this.ratio = ratio;
}
@@ -189,9 +195,9 @@
return null;
try {
- final Double cos = Double.parseDouble(parts[0]);
- final Double sin = Double.parseDouble(parts[1]);
- final Double ratio = Double.parseDouble(parts[2]);
+ final double cos = Double.valueOf(parts[0]);
+ final double sin = Double.valueOf(parts[1]);
+ final double ratio = Double.valueOf(parts[2]);
HandleImpl handle = new HandleImpl(0, 0);
handle.setSin(sin);
Modified:
core3/impl/trunk/edge-bundler-impl/src/main/java/org/cytoscape/edge/bundler/internal/EdgeBundlerRunner.java
===================================================================
---
core3/impl/trunk/edge-bundler-impl/src/main/java/org/cytoscape/edge/bundler/internal/EdgeBundlerRunner.java
2012-05-08 23:46:01 UTC (rev 29162)
+++
core3/impl/trunk/edge-bundler-impl/src/main/java/org/cytoscape/edge/bundler/internal/EdgeBundlerRunner.java
2012-05-08 23:48:36 UTC (rev 29163)
@@ -1,6 +1,6 @@
package org.cytoscape.edge.bundler.internal;
-public class EdgeBundlerRunner implements Runnable{
+public class EdgeBundlerRunner implements Runnable {
private final int ni;
private final int numNubs;
Modified:
core3/impl/trunk/edge-bundler-impl/src/main/java/org/cytoscape/edge/bundler/internal/EdgeBundlerTask.java
===================================================================
---
core3/impl/trunk/edge-bundler-impl/src/main/java/org/cytoscape/edge/bundler/internal/EdgeBundlerTask.java
2012-05-08 23:46:01 UTC (rev 29162)
+++
core3/impl/trunk/edge-bundler-impl/src/main/java/org/cytoscape/edge/bundler/internal/EdgeBundlerTask.java
2012-05-08 23:48:36 UTC (rev 29163)
@@ -4,6 +4,7 @@
package org.cytoscape.edge.bundler.internal;
+import java.awt.geom.Point2D;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@@ -18,6 +19,7 @@
import static org.cytoscape.view.presentation.property.BasicVisualLexicon.*;
import org.cytoscape.view.vizmap.VisualMappingFunctionFactory;
import org.cytoscape.view.vizmap.VisualMappingManager;
+import org.cytoscape.view.vizmap.VisualStyle;
import org.cytoscape.view.vizmap.mappings.DiscreteMapping;
import org.cytoscape.work.TaskMonitor;
import org.cytoscape.work.Tunable;
@@ -73,6 +75,8 @@
this.selection = selection;
}
+
+ @Override
public void run(TaskMonitor tm) {
// Check tunables
@@ -140,7 +144,7 @@
edgeLength = new double[numEdges];
ei = 0;
- for (View<CyEdge> e : edges) {
+ for (final View<CyEdge> e : edges) {
// System.out.println("SUID: "+e.getModel().getSUID());
View<CyNode> eSource =
view.getNodeView(e.getModel().getSource());
@@ -154,13 +158,6 @@
edgePos[1][0][ei] =
eTarget.getVisualProperty(NODE_X_LOCATION);
edgePos[1][1][ei] =
eTarget.getVisualProperty(NODE_Y_LOCATION);
- // if (edgePos[0][0][ei]>edgePos[1][0][ei]) {double
temp =
- // edgePos[0][0][ei]; edgePos[0][0][ei] =
edgePos[1][0][ei];
- // edgePos[1][0][ei] = temp;}
- // if (edgePos[0][1][ei]>edgePos[1][1][ei]) {double
temp =
- // edgePos[0][1][ei]; edgePos[0][1][ei] =
edgePos[1][1][ei];
- // edgePos[1][1][ei] = temp;}
-
double diffx = edgePos[1][0][ei] - edgePos[0][0][ei];
double diffy = edgePos[1][1][ei] - edgePos[0][1][ei];
@@ -174,13 +171,12 @@
ei++;
}
- // networkScale = computeNetworkScale();
computeEdgeCompatability();
// Simulating physics
tm.setStatusMessage("Simulating physics");
double time = System.nanoTime();
- double[][][] forces = new double[numNubs][2][numEdges]; // Nub,
X/Y,
+ final double[][][] forces = new double[numNubs][2][numEdges];
// Nub, X/Y,
// edgeIndex
for (int iteri = 0; iteri < maxIterations; iteri++) {
if (this.cancelled) {
@@ -212,62 +208,9 @@
}
render(edges);
-
- // double minX = 0;
- // double maxX = 0;
- // double minY = 0;
- // double maxY = 0;
- //
- //
- // for (ei=0;ei<edgeLength.length;ei++)
- // for (int ni=0;ni<numNubs;ni++)
- // {
- // double x = nubs[ni][0][ei];
- // double y = nubs[ni][1][ei];
- //
- // if (x<minX) minX = x;
- // if (x>maxX) maxX = x;
- // if (y<minY) minY = y;
- // if (y>maxY) maxY = y;
- //
- // if (Double.isInfinite(x) || Double.isInfinite(y) ||
Double.isNaN(x)
- // || Double.isNaN(y))
- // System.out.println("Infinite or NaN positions detected!");
- // }
- //
- // System.out.println(minX+":"+maxX+", "+minY+":"+maxY);
}
- private double computeNetworkScale() {
- double centerX = 0;
- double centerY = 0;
- for (int ei = 0; ei < edgeLength.length; ei++) {
- centerX += edgePos[0][0][ei] + edgePos[1][0][ei];
- centerY += edgePos[0][1][ei] + edgePos[1][1][ei];
- }
-
- centerX /= 2.0 * edgeLength.length;
- centerY /= 2.0 * edgeLength.length;
-
- double[] dist = new double[2 * edgeLength.length];
-
- for (int ei = 0; ei < edgeLength.length; ei++) {
- double diff0x = edgePos[0][0][ei] - centerX;
- double diff0y = edgePos[0][1][ei] - centerY;
- double diff1x = edgePos[1][0][ei] - centerX;
- double diff1y = edgePos[1][1][ei] - centerY;
-
- dist[2 * ei] = Math.sqrt(diff0x * diff0x + diff0y *
diff0y);
- dist[2 * ei + 1] = Math.sqrt(diff1x * diff1x + diff1y *
diff1y);
- }
-
- Arrays.sort(dist);
- double scale = dist[dist.length / 2];
-
- return scale;
- }
-
private boolean isConverged(double[][][] forces, double threshold) {
for (int ei = 0; ei < edgeLength.length; ei++)
for (int ni = 0; ni < numNubs; ni++)
@@ -280,37 +223,37 @@
return true;
}
- private void render(Collection<View<CyEdge>> edges) {
- DiscreteMapping<Long, Bend> function = (DiscreteMapping<Long,
Bend>) discreteFactory
+ private final void render(final Collection<View<CyEdge>> edges) {
+ // Create new discrete mapping for edge SUID to Edge Bend
+ final DiscreteMapping<Long, Bend> function =
(DiscreteMapping<Long, Bend>) discreteFactory
.createVisualMappingFunction(CyTable.SUID,
Long.class, null, EDGE_BEND);
int ei = 0;
- for (View<CyEdge> e : edges) {
- View<CyNode> eSource =
view.getNodeView(e.getModel().getSource());
- View<CyNode> eTarget =
view.getNodeView(e.getModel().getTarget());
+ for (final View<CyEdge> edge : edges) {
+ final View<CyNode> eSource =
view.getNodeView(edge.getModel().getSource());
+ final View<CyNode> eTarget =
view.getNodeView(edge.getModel().getTarget());
+ // Ignore self-edge
if (eSource.getSUID().equals(eTarget.getSUID()))
continue;
- Bend b = bf.createBend();
- List<Handle> hlist = b.getAllHandles();
-
+ final Bend bend = bf.createBend();
+ final List<Handle> hlist = bend.getAllHandles();
for (int ni = 0; ni < numNubs; ni++) {
- double x = nubs[ni][0][ei];
- double y = nubs[ni][1][ei];
-
- Handle h = hf.createHandle(0, 0);
- h.defineHandle(view, e, x, y);
+ final double x = nubs[ni][0][ei];
+ final double y = nubs[ni][1][ei];
+ final Handle h = hf.createHandle(0, 0);
+ h.defineHandle(view, edge, x, y);
hlist.add(h);
}
-
- function.putMapValue(e.getModel().getSUID(), b);
+
+ function.putMapValue(edge.getModel().getSUID(), bend);
ei++;
}
- vmm.getVisualStyle(view).addVisualMappingFunction(function);
-
- vmm.getVisualStyle(view).apply(view);
+ final VisualStyle style = vmm.getVisualStyle(view);
+ style.addVisualMappingFunction(function);
+ style.apply(view);
view.updateView();
}
@@ -461,7 +404,7 @@
return new double[] { x, y };
}
- private void updateForces(double[][][] forces) {
+ private void updateForces(final double[][][] forces) {
// Spring forces
for (int ei = 0; ei < edgeLength.length; ei++)
for (int ni = 0; ni < numNubs; ni++) {
--
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.