mev-4.0.01/source/org/tigr/microarray/mev/cluster/gui/impl/terrain/LinksShape.java

Code
Comments
Other
Rev Date Author Line
2 26 Feb 07 jari 1 /*
2 26 Feb 07 jari 2 Copyright @ 1999-2003, The Institute for Genomic Research (TIGR).
2 26 Feb 07 jari 3 All rights reserved.
2 26 Feb 07 jari 4 */
2 26 Feb 07 jari 5 /*
2 26 Feb 07 jari 6  * $RCSfile: LinksShape.java,v $
2 26 Feb 07 jari 7  * $Revision: 1.3 $
2 26 Feb 07 jari 8  * $Date: 2005/03/10 20:33:21 $
2 26 Feb 07 jari 9  * $Author: braistedj $
2 26 Feb 07 jari 10  * $State: Exp $
2 26 Feb 07 jari 11  */
2 26 Feb 07 jari 12 package org.tigr.microarray.mev.cluster.gui.impl.terrain;
2 26 Feb 07 jari 13
2 26 Feb 07 jari 14 import java.awt.geom.Rectangle2D;
2 26 Feb 07 jari 15
2 26 Feb 07 jari 16 import javax.media.j3d.Appearance;
2 26 Feb 07 jari 17 import javax.media.j3d.Geometry;
2 26 Feb 07 jari 18 import javax.media.j3d.GeometryArray;
2 26 Feb 07 jari 19 import javax.media.j3d.LineArray;
2 26 Feb 07 jari 20 import javax.media.j3d.LineAttributes;
2 26 Feb 07 jari 21 import javax.media.j3d.Material;
2 26 Feb 07 jari 22 import javax.media.j3d.Shape3D;
2 26 Feb 07 jari 23 import javax.vecmath.Point2f;
2 26 Feb 07 jari 24
2 26 Feb 07 jari 25 import org.tigr.microarray.mev.cluster.gui.impl.util.FloatArray;
2 26 Feb 07 jari 26
2 26 Feb 07 jari 27 public class LinksShape extends Shape3D {
2 26 Feb 07 jari 28
2 26 Feb 07 jari 29     private int[][] subnets;
2 26 Feb 07 jari 30     private float[][] weights;
2 26 Feb 07 jari 31     private float[][] locations;
2 26 Feb 07 jari 32
2 26 Feb 07 jari 33     private Point2f left_up = new Point2f(0f,0f);
2 26 Feb 07 jari 34     private Point2f right_bottom = new Point2f(1f,1f);
2 26 Feb 07 jari 35     private float threshold = 0.8f;
2 26 Feb 07 jari 36     private boolean visible = false;
2 26 Feb 07 jari 37     private static final float[][] EMPTY_BUF = new float[][] {{0,0,0,0,0,0} , {0,0,0,0,0,0}};
2 26 Feb 07 jari 38
2 26 Feb 07 jari 39     public LinksShape(int[][] subnets, float[][] weights, float[][] locations) {
2 26 Feb 07 jari 40         setCapability(ALLOW_GEOMETRY_READ);
2 26 Feb 07 jari 41         setCapability(ALLOW_GEOMETRY_WRITE);
2 26 Feb 07 jari 42         setCapability(ALLOW_APPEARANCE_READ);
2 26 Feb 07 jari 43         this.subnets = subnets;
2 26 Feb 07 jari 44         this.weights = weights;
2 26 Feb 07 jari 45         this.locations = locations;
2 26 Feb 07 jari 46         updateGeometry();
2 26 Feb 07 jari 47         setAppearance(createAppearance());
2 26 Feb 07 jari 48     }
2 26 Feb 07 jari 49
2 26 Feb 07 jari 50     public void setZoom(Point2f left_up, Point2f right_bottom) {
2 26 Feb 07 jari 51         this.left_up.set(left_up);
2 26 Feb 07 jari 52         this.right_bottom.set(right_bottom);
2 26 Feb 07 jari 53         updateGeometry();
2 26 Feb 07 jari 54     }
2 26 Feb 07 jari 55
2 26 Feb 07 jari 56     public void setThreshold(float threshold) {
2 26 Feb 07 jari 57         this.threshold = threshold;
2 26 Feb 07 jari 58         updateGeometry();
2 26 Feb 07 jari 59     }
2 26 Feb 07 jari 60
2 26 Feb 07 jari 61     public float getThreshold() {
2 26 Feb 07 jari 62         return this.threshold;
2 26 Feb 07 jari 63     }
2 26 Feb 07 jari 64
2 26 Feb 07 jari 65     public void setVisible(boolean value) {
2 26 Feb 07 jari 66         if (this.visible == value)
2 26 Feb 07 jari 67             return;
2 26 Feb 07 jari 68         this.visible = value;
2 26 Feb 07 jari 69         updateGeometry();
2 26 Feb 07 jari 70     }
2 26 Feb 07 jari 71
2 26 Feb 07 jari 72     public void setLinksWidth(float value) {
2 26 Feb 07 jari 73         Appearance appearance = getAppearance();
2 26 Feb 07 jari 74         LineAttributes la = appearance.getLineAttributes();
2 26 Feb 07 jari 75         la.setLineWidth(value);
2 26 Feb 07 jari 76     }
2 26 Feb 07 jari 77
2 26 Feb 07 jari 78     public float getLinksWidth() {
2 26 Feb 07 jari 79         Appearance appearance = getAppearance();
2 26 Feb 07 jari 80         LineAttributes la = appearance.getLineAttributes();
2 26 Feb 07 jari 81         return la.getLineWidth();
2 26 Feb 07 jari 82     }
2 26 Feb 07 jari 83
2 26 Feb 07 jari 84     private void updateGeometry() {
2 26 Feb 07 jari 85         setGeometry(createGeometry());
2 26 Feb 07 jari 86     }
2 26 Feb 07 jari 87
2 26 Feb 07 jari 88     private Geometry createGeometry() {
2 26 Feb 07 jari 89         float[][] vertCoords = createLinksCoordinaties();
2 26 Feb 07 jari 90         GeometryArray geometry = new LineArray(vertCoords[0].length/3, GeometryArray.COORDINATES | GeometryArray.COLOR_3);
2 26 Feb 07 jari 91         geometry.setCoordinates(0, vertCoords[0]);
2 26 Feb 07 jari 92         geometry.setColors(0, vertCoords[1]);
2 26 Feb 07 jari 93         geometry.setCapability(Geometry.ALLOW_INTERSECT);           
2 26 Feb 07 jari 94         geometry.setCapability(GeometryArray.ALLOW_COUNT_READ);     
2 26 Feb 07 jari 95         geometry.setCapability(GeometryArray.ALLOW_FORMAT_READ);    
2 26 Feb 07 jari 96         geometry.setCapability(GeometryArray.ALLOW_COORDINATE_READ);
2 26 Feb 07 jari 97         return geometry;
2 26 Feb 07 jari 98     }
2 26 Feb 07 jari 99
2 26 Feb 07 jari 100     private float[][] createLinksCoordinaties() {
2 26 Feb 07 jari 101         if (!this.visible)
2 26 Feb 07 jari 102             return EMPTY_BUF;
2 26 Feb 07 jari 103         Point2f p1 = new Point2f();
2 26 Feb 07 jari 104         Point2f p2 = new Point2f();
2 26 Feb 07 jari 105         Point2f n1 = new Point2f();
2 26 Feb 07 jari 106         Point2f n2 = new Point2f();
2 26 Feb 07 jari 107         Rectangle2D.Float bounds = new Rectangle2D.Float(0,0,1,1);
2 26 Feb 07 jari 108         float scale = 1f/Math.max(right_bottom.x-left_up.x, right_bottom.y-left_up.y);
2 26 Feb 07 jari 109         int coordPos = 0;
2 26 Feb 07 jari 110         FloatArray coords = new FloatArray(100);
2 26 Feb 07 jari 111         FloatArray colors = new FloatArray(100);
2 26 Feb 07 jari 112         for (int i=0; i<subnets.length; i++)
2 26 Feb 07 jari 113             if (subnets[i].length > 1) {
2 26 Feb 07 jari 114                 float x1 = (locations[i][0]-left_up.x)*scale;
2 26 Feb 07 jari 115                 float y1 = (locations[i][1]-left_up.y)*scale;
2 26 Feb 07 jari 116                 if (x1>=0f && x1<=1f && y1>=0f && y1<=1f)
2 26 Feb 07 jari 117                     for (int j=1; j<subnets[i].length; j++) {
2 26 Feb 07 jari 118                         float x2 = (locations[subnets[i][j]][0]-left_up.x)*scale;
2 26 Feb 07 jari 119                         float y2 = (locations[subnets[i][j]][1]-left_up.y)*scale;
2 26 Feb 07 jari 120                         p1.set(x1, y1);
2 26 Feb 07 jari 121                         p2.set(x2, y2);
2 26 Feb 07 jari 122                         if (Math.abs(weights[i][j]) > threshold && isLineIntersects(bounds, p1, p2, n1, n2)) {
2 26 Feb 07 jari 123                             coords.add(n1.x);
2 26 Feb 07 jari 124                             coords.add(0);
2 26 Feb 07 jari 125                             coords.add(n1.y);
2 26 Feb 07 jari 126                             coords.add(n2.x);
2 26 Feb 07 jari 127                             coords.add(0);
2 26 Feb 07 jari 128                             coords.add(n2.y);
2 26 Feb 07 jari 129                             colors.add(weights[i][j]);
2 26 Feb 07 jari 130                             colors.add(0);
2 26 Feb 07 jari 131                             colors.add(1-weights[i][j]);
2 26 Feb 07 jari 132                             colors.add(weights[i][j]);
2 26 Feb 07 jari 133                             colors.add(0);
2 26 Feb 07 jari 134                             colors.add(1-weights[i][j]);
2 26 Feb 07 jari 135                         }
2 26 Feb 07 jari 136                     }
2 26 Feb 07 jari 137             }
2 26 Feb 07 jari 138         if (coords.getSize() == 0)
2 26 Feb 07 jari 139             return EMPTY_BUF;
2 26 Feb 07 jari 140         float[][] result = new float[2][];
2 26 Feb 07 jari 141         result[0] = coords.toArray();
2 26 Feb 07 jari 142         result[1] = colors.toArray();
2 26 Feb 07 jari 143         return result;
2 26 Feb 07 jari 144     }
2 26 Feb 07 jari 145
2 26 Feb 07 jari 146     /**
2 26 Feb 07 jari 147      * Checkes if (p1, p2) line intersects with vertical (x, y1, y2) one.
2 26 Feb 07 jari 148      * @return point the intersection coordinate.
2 26 Feb 07 jari 149      */
2 26 Feb 07 jari 150     private final boolean isIntersectVerticalLine(Point2f p1, Point2f p2, float x, float y1, float y2, Point2f point) {
2 26 Feb 07 jari 151         if ((p1.x < x && p2.x < x) || ((p1.x > x && p2.x > x))) {
2 26 Feb 07 jari 152             return false;
2 26 Feb 07 jari 153         }
2 26 Feb 07 jari 154         float tan = (p2.y - p1.y)/(p2.x - p1.x);
2 26 Feb 07 jari 155         float delta = tan*(x - p1.x);
2 26 Feb 07 jari 156         point.x = x;
2 26 Feb 07 jari 157         point.y = p1.y + delta;
2 26 Feb 07 jari 158         return point.y > Math.min(y1, y2) && point.y < Math.max(y1, y2);
2 26 Feb 07 jari 159     }
2 26 Feb 07 jari 160
2 26 Feb 07 jari 161     /**
2 26 Feb 07 jari 162      * Checkes if (p1, p2) line intersects with horizontal (y, x1, x2) one.
2 26 Feb 07 jari 163      * @return point the intersection coordinate.
2 26 Feb 07 jari 164      */
2 26 Feb 07 jari 165     private final boolean isIntersectHorizontalLine(Point2f p1, Point2f p2, float y, float x1, float x2, Point2f point) {
2 26 Feb 07 jari 166         if ((p1.y < y && p2.y < y) || ((p1.y > y && p2.y > y))) {
2 26 Feb 07 jari 167             return false;
2 26 Feb 07 jari 168         }
2 26 Feb 07 jari 169         float tan = (p2.y - p1.y)/(p2.x - p1.x);
2 26 Feb 07 jari 170         float delta = (y - p1.y)/tan;
2 26 Feb 07 jari 171         point.x = p1.x + delta;
2 26 Feb 07 jari 172         point.y = y;
2 26 Feb 07 jari 173         return point.x > Math.min(x1, x2) && point.x < Math.max(x1, x2);
2 26 Feb 07 jari 174     }
2 26 Feb 07 jari 175
2 26 Feb 07 jari 176     /**
2 26 Feb 07 jari 177      * Checkes if points p1 or p2 are an internal point of a rect.
2 26 Feb 07 jari 178      * @return n the coordinaties of an internal point.
2 26 Feb 07 jari 179      */
2 26 Feb 07 jari 180     private final boolean isInternalPoint(Rectangle2D.Float rect, Point2f p1, Point2f p2, Point2f n) {
2 26 Feb 07 jari 181         boolean p1b = rect.contains(p1.x, p1.y);
2 26 Feb 07 jari 182         boolean p2b = rect.contains(p2.x, p2.y);
2 26 Feb 07 jari 183         if (p1b) {
2 26 Feb 07 jari 184             n.set(p1);
2 26 Feb 07 jari 185             return true;
2 26 Feb 07 jari 186         }
2 26 Feb 07 jari 187         if (p2b) {
2 26 Feb 07 jari 188             n.set(p2);
2 26 Feb 07 jari 189             return true;
2 26 Feb 07 jari 190         }
2 26 Feb 07 jari 191         return false;
2 26 Feb 07 jari 192     }
2 26 Feb 07 jari 193
2 26 Feb 07 jari 194     /**
2 26 Feb 07 jari 195      * Checkes if (p1, p2) line intersects rect.
2 26 Feb 07 jari 196      * @return n1, n2 points which is intersection of the line and the rect.
2 26 Feb 07 jari 197      */
2 26 Feb 07 jari 198     private final boolean isLineIntersects(Rectangle2D.Float rect, Point2f p1, Point2f p2, Point2f n1, Point2f n2) {
2 26 Feb 07 jari 199         n1.set(p1);
2 26 Feb 07 jari 200         n2.set(p2);
2 26 Feb 07 jari 201         if (rect.contains(p1.x, p1.y) && rect.contains(p2.x, p2.y)) {
2 26 Feb 07 jari 202             return true;
2 26 Feb 07 jari 203         }
2 26 Feb 07 jari 204         if (p1.x < rect.x && p2.x < rect.x) {
2 26 Feb 07 jari 205             return false;
2 26 Feb 07 jari 206         }
2 26 Feb 07 jari 207         if (p1.y < rect.y && p2.y < rect.y) {
2 26 Feb 07 jari 208             return false;
2 26 Feb 07 jari 209         }
2 26 Feb 07 jari 210         if (p1.x > rect.x+rect.width && p2.x > rect.x+rect.width) {
2 26 Feb 07 jari 211             return false;
2 26 Feb 07 jari 212         }
2 26 Feb 07 jari 213         if (p1.y > rect.y+rect.height && p2.y > rect.y+rect.height) {
2 26 Feb 07 jari 214             return false;
2 26 Feb 07 jari 215         }
2 26 Feb 07 jari 216         if (p1.x == p2.x) {
2 26 Feb 07 jari 217             // vertical line
2 26 Feb 07 jari 218             if (p1.y < rect.y) {
2 26 Feb 07 jari 219                 n1.y = rect.y;
2 26 Feb 07 jari 220             } else if (p1.y > rect.y+rect.height) {
2 26 Feb 07 jari 221                 n1.y = rect.y+rect.height;
2 26 Feb 07 jari 222             }
2 26 Feb 07 jari 223             if (p2.y < rect.y) {
2 26 Feb 07 jari 224                 n2.y = rect.y;
2 26 Feb 07 jari 225             } else if (p2.y > rect.y+rect.height) {
2 26 Feb 07 jari 226                 n2.y = rect.y+rect.height;
2 26 Feb 07 jari 227             }
2 26 Feb 07 jari 228             return true;
2 26 Feb 07 jari 229         }
2 26 Feb 07 jari 230         if (p1.y == p2.y) {
2 26 Feb 07 jari 231             // horizontal line
2 26 Feb 07 jari 232             if (p1.x < rect.x) {
2 26 Feb 07 jari 233                 n1.x = rect.x;
2 26 Feb 07 jari 234             } else if (p1.x > rect.x+rect.width) {
2 26 Feb 07 jari 235                 n1.x = rect.x+rect.width;
2 26 Feb 07 jari 236             }
2 26 Feb 07 jari 237             if (p2.x < rect.x) {
2 26 Feb 07 jari 238                 n2.x = rect.x;
2 26 Feb 07 jari 239             } else if (p2.x > rect.x+rect.width) {
2 26 Feb 07 jari 240                 n2.x = rect.x+rect.width;
2 26 Feb 07 jari 241             }
2 26 Feb 07 jari 242             return true;
2 26 Feb 07 jari 243         }
2 26 Feb 07 jari 244         if (isIntersectVerticalLine(p1, p2, rect.x, rect.y, rect.y+rect.height, n1)) {
2 26 Feb 07 jari 245             if (isIntersectVerticalLine(p1, p2, rect.x+rect.width, rect.y, rect.y+rect.height, n2)) {
2 26 Feb 07 jari 246             } else if (isIntersectHorizontalLine(p1, p2, rect.y, rect.x, rect.x+rect.width, n2)) {
2 26 Feb 07 jari 247             } else if (isIntersectHorizontalLine(p1, p2, rect.y+rect.height, rect.x, rect.x+rect.width, n2)) {
2 26 Feb 07 jari 248             } else if (isInternalPoint(rect, p1, p2, n2)) {
2 26 Feb 07 jari 249             } else {
2 26 Feb 07 jari 250                 return false;
2 26 Feb 07 jari 251             }
2 26 Feb 07 jari 252             return true;
2 26 Feb 07 jari 253         } else if (isIntersectVerticalLine(p1, p2, rect.x+rect.width, rect.y, rect.y+rect.height, n1)) {
2 26 Feb 07 jari 254             if (isIntersectHorizontalLine(p1, p2, rect.y+rect.height, rect.x, rect.x+rect.width, n2)) {
2 26 Feb 07 jari 255             } else if (isIntersectHorizontalLine(p1, p2, rect.y, rect.x, rect.x+rect.width, n2)) {
2 26 Feb 07 jari 256             } else if (isInternalPoint(rect, p1, p2, n2)) {
2 26 Feb 07 jari 257             } else {
2 26 Feb 07 jari 258                 return false;
2 26 Feb 07 jari 259             }
2 26 Feb 07 jari 260             return true;
2 26 Feb 07 jari 261         } else if (isIntersectHorizontalLine(p1, p2, rect.y, rect.x, rect.x+rect.width, n1)) {
2 26 Feb 07 jari 262             if (isIntersectHorizontalLine(p1, p2, rect.y+rect.height, rect.x, rect.x+rect.width, n2)) {
2 26 Feb 07 jari 263             } else if (isInternalPoint(rect, p1, p2, n2)) {
2 26 Feb 07 jari 264             } else {
2 26 Feb 07 jari 265                 return false;
2 26 Feb 07 jari 266             }
2 26 Feb 07 jari 267             return true;
2 26 Feb 07 jari 268         } else if (isIntersectHorizontalLine(p1, p2, rect.y+rect.height, rect.x, rect.x+rect.width, n1)) {
2 26 Feb 07 jari 269             if (isInternalPoint(rect, p1, p2, n2)) {
2 26 Feb 07 jari 270             } else {
2 26 Feb 07 jari 271                 return false;
2 26 Feb 07 jari 272             }
2 26 Feb 07 jari 273             return true;
2 26 Feb 07 jari 274         }
2 26 Feb 07 jari 275         return false;
2 26 Feb 07 jari 276     }
2 26 Feb 07 jari 277
2 26 Feb 07 jari 278     /**
2 26 Feb 07 jari 279      * Creates the LinksShape appearance.
2 26 Feb 07 jari 280      */
2 26 Feb 07 jari 281     protected Appearance createAppearance() {
2 26 Feb 07 jari 282         LineAttributes la = new LineAttributes();
2 26 Feb 07 jari 283         la.setCapability(LineAttributes.ALLOW_WIDTH_READ);
2 26 Feb 07 jari 284         la.setCapability(LineAttributes.ALLOW_WIDTH_WRITE);
2 26 Feb 07 jari 285
2 26 Feb 07 jari 286         Appearance appearance = new Appearance();
2 26 Feb 07 jari 287         appearance.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_READ);
2 26 Feb 07 jari 288         appearance.setCapability(Appearance.ALLOW_LINE_ATTRIBUTES_WRITE);
2 26 Feb 07 jari 289         appearance.setLineAttributes(la);
2 26 Feb 07 jari 290         appearance.setMaterial(new Material());
2 26 Feb 07 jari 291         return appearance;
2 26 Feb 07 jari 292     }
2 26 Feb 07 jari 293 }