Changeset 2714


Ignore:
Timestamp:
05/01/07 17:37:38 (13 years ago)
Author:
sorber
Message:

Fixed bug #104 (bad array length FieldException when filling some polylines)
Fixed bug in OverlayUtil.getNodedLayer() which sometimes produced invalid Gridded2DSets
Moved OverlayUtil to package visbio.overlays

Location:
trunk/loci/visbio/overlays
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/visbio/overlays/OverlayNodedObject.java

    r2667 r2714  
    167167    RealTupleType domain = overlay.getDomainType(); 
    168168    TupleType range = overlay.getRangeType(); 
    169  
    170     FlatField field = null; 
    171     Set fieldSet = null; 
    172169       
    173     // determine number of samples 
    174     boolean circleFilled = false; // only works if nodes are also filled 
    175     // (all sets in a union set must have same manifold dimension) 
    176     int arcLen = ARC[0].length; 
    177     int len = 2 * arcLen; 
    178     int hlen = circleFilled ? len : len + 1; 
    179     int totalSamples = maxNodes; 
    180     if (isHighlightNode() && !filled) totalSamples += hlen; 
    181  
    182     float[][] rangeSamples = new float[4][totalSamples]; 
    183  
    184170    // ****************************************************************** 
    185171    // build nodes set and assign nodes range samples 
    186172    // ****************************************************************** 
    187     SampledSet nodesSet = null; 
     173    SampledSet fieldSet = null; 
    188174    try { 
    189       nodesSet = new Gridded2DSet(domain, 
     175      fieldSet = new Gridded2DSet(domain, 
    190176        nodes, maxNodes, null, null, null, false); 
    191177       
     
    194180      if (filled && !isDrawing()) {   
    195181        Irregular2DSet roiSet = 
    196           DelaunayCustom.fillCheck((Gridded2DSet) nodesSet, false); 
    197         if (roiSet != null)  nodesSet = roiSet; 
    198       } 
    199  
    200       fieldSet = nodesSet; 
     182          DelaunayCustom.fillCheck((Gridded2DSet) fieldSet, false); 
     183        if (roiSet != null) fieldSet = roiSet; 
     184      } 
    201185    } 
    202186    catch (VisADException exc) { exc.printStackTrace(); } 
     
    208192    float b = col.getBlue() / 255f; 
    209193 
    210     Arrays.fill(rangeSamples[0], 0, maxNodes, r); 
    211     Arrays.fill(rangeSamples[1], 0, maxNodes, g); 
    212     Arrays.fill(rangeSamples[2], 0, maxNodes, b); 
    213     Arrays.fill(rangeSamples[3], 0, maxNodes, 1.0f); 
    214      
    215     // ************************************************************** 
    216     // make highlight set and fill highlight range samples 
    217     // ************************************************************** 
    218     if (isHighlightNode() && !filled) { 
    219       SampledSet highlightSet = null; 
    220       float rad = RADIUS;  
    221       // assemble highlight set samples 
    222       float[][] highlightSetSamples = new float[2][hlen]; 
    223       float[] c = getNodeCoords(getHighlightedNodeIndex()); 
    224  
    225       // top half of circle 
    226       for (int i=0; i<arcLen; i++) { 
    227         highlightSetSamples[0][i] = c[0] + rad * ARC[0][i]; 
    228         highlightSetSamples[1][i] = c[1] + rad * ARC[1][i]; 
    229       } 
    230  
    231       // bottom half of circle 
    232       for (int i=0; i<arcLen; i++) { 
    233         int ndx = circleFilled? arcLen + i : len - i - 1; 
    234         highlightSetSamples[0][ndx] = c[0] + rad * ARC[0][i]; 
    235         highlightSetSamples[1][ndx] = c[1] - rad * ARC[1][i]; 
    236       } 
    237  
    238       try { 
    239         // build highlight set  
    240         if (circleFilled) { 
    241           highlightSet = new Gridded2DSet(domain, highlightSetSamples, 
    242             arcLen, 2, null, null, null, false); 
    243         } 
    244         else { 
    245           highlightSetSamples[0][len] = highlightSetSamples[0][0]; 
    246           highlightSetSamples[1][len] = highlightSetSamples[1][0]; 
    247           highlightSet = new Gridded2DSet(domain, highlightSetSamples, 
    248               highlightSetSamples[0].length, null, null, null, false); 
    249         } 
    250       } 
    251       catch (VisADException exc) { exc.printStackTrace(); } 
    252        
    253       // fill highlight range samples 
    254       float hltR = highlightColor.getRed() / 255f; 
    255       float hltG = highlightColor.getGreen() / 255f; 
    256       float hltB = highlightColor.getBlue() / 255f; 
    257       float hltA = HLT_ALPHA; 
    258  
    259       Arrays.fill(rangeSamples[0], maxNodes, totalSamples, hltR); 
    260       Arrays.fill(rangeSamples[1], maxNodes, totalSamples, hltG); 
    261       Arrays.fill(rangeSamples[2], maxNodes, totalSamples, hltB); 
    262       Arrays.fill(rangeSamples[3], maxNodes, totalSamples, hltA); 
    263  
    264       try { 
    265         // assemble a UnionSet of nodes and circle 
    266         SampledSet[] sets = new SampledSet[]{nodesSet, highlightSet};   
    267         fieldSet = new UnionSet(domain, sets); 
    268       } 
    269       catch (VisADException exc) { exc.printStackTrace(); } 
    270     } 
    271      
    272     // ********************************************************** 
    273     // assemble ultimate field 
    274     // ********************************************************** 
     194    if (fieldSet == null) System.out.println("yow!"); 
     195    FlatField field = null; 
    275196    try { 
     197      float[][] rangeSamples = new float[4][fieldSet.getLength()]; 
     198      Arrays.fill(rangeSamples[0], r); 
     199      Arrays.fill(rangeSamples[1], g); 
     200      Arrays.fill(rangeSamples[2], b); 
     201      Arrays.fill(rangeSamples[3], 1.0f); 
     202 
    276203      FunctionType fieldType = new FunctionType(domain, range); 
    277204      field = new FlatField(fieldType, fieldSet); 
     
    283210      System.out.println("filled  = " + filled); 
    284211      System.out.println("Thread.currentThread()" + Thread.currentThread()); 
    285       System.out.println("totalSamples = " + totalSamples); 
    286       try { 
    287         System.out.println("nodesSet.getLength = " + nodesSet.getLength());  
    288       } 
    289       catch (VisADException exc2) {exc2.printStackTrace();} 
    290212      System.out.println("maxNodes = " + maxNodes);  
    291213      System.out.println("numNodes = " + numNodes); 
    292       System.out.println("rangeSamples[0].length " + rangeSamples[0].length); 
    293  
     214      try { 
     215        System.out.println("fieldSet.getLength = " + fieldSet.getLength());  
     216      } 
     217      catch (VisADException exc2) {exc2.printStackTrace();} 
    294218    } 
    295219    catch (RemoteException exc) { exc.printStackTrace(); } 
     
    362286  /** Highlight a node. */  
    363287  public void setHighlightNode(int i, Color c) { 
     288    // if (Thread.currentThread().getName().indexOf("ComputeDataThread") < 0) 
     289    // new Exception().printStackTrace(); 
    364290    highlightNode = true; 
    365291    highlightIndex = i; 
  • trunk/loci/visbio/overlays/OverlayTransform.java

    r2697 r2714  
    3636import loci.visbio.state.Dynamic; 
    3737import loci.visbio.util.ObjectUtil; 
    38 import loci.visbio.util.OverlayUtil; 
    3938import loci.visbio.view.DisplayWindow; 
    4039import loci.visbio.view.TransformLink; 
  • trunk/loci/visbio/overlays/PolylineTool.java

    r2667 r2714  
    5151  /** Maximum distance (in pixels) mouse can be from a node to be considered 
    5252   *  pointing to it. */ 
    53   protected static final double THRESH = 5.0; 
     53  protected static final double THRESH = 7.0; 
    5454 
    5555  /** Color for highlighting head or tail node of polyline when 'connecting' 
     
    6565  /** Curve currently being drawn or modified. */ 
    6666  protected OverlayPolyline line; 
    67  
    68   /** Curve close to the mouse when drawing is not occurring. */ 
    69   protected OverlayPolyline selectedPln; 
    7067 
    7168  /** Nearest node on selected PolyLine. */ 
     
    8380  public PolylineTool(OverlayTransform overlay) { 
    8481    super(overlay, "Polyline", "Polyline", "polyline.png"); 
    85     line = null; 
    8682    mode = WAIT; 
    8783    unselect(); 
     
    10096    //printMode("mouseDown"); 
    10197 
    102     if (overlay.hasToolChanged()) { 
    103       releaseLine(); 
    104       mode = WAIT; 
    105     } 
    106  
    107     if (mode == WAIT) { 
    108       deselectAll(); 
    109       line =  new OverlayPolyline(overlay, dx, dy, dx, dy); 
    110       line.setDrawing(true); 
    111       line.setSelected(true); 
    112       configureOverlay(line); 
    113       overlay.addObject(line, pos); 
    114       mode = PLACE; 
    115     } 
    116     else if (mode == PLACE) { 
    117       if (line.getNumNodes() > 1) { 
     98    synchronized (overlay) { 
     99      if (overlay.hasToolChanged()) { 
    118100        releaseLine(); 
    119       } 
    120       else {  
    121         overlay.removeObject(line); 
    122         line = null; 
    123       } 
    124       mode = WAIT; 
    125     } 
    126     else if (mode == SELECT) { 
    127       if (!ctl) { 
    128         // which node are you near? 
    129         if (selectedNode == line.getNumNodes() - 1) { 
    130           mode = SELECTED_TAIL; 
    131         } 
    132         else if (selectedNode == 0) { 
    133           // you're near the head node 
    134           line.reverseNodes(); 
    135           selectNode(display, line, line.getNumNodes() - 1); 
    136           mode = SELECTED_TAIL; 
    137         } 
    138         else { 
    139           mode = ADJUST; 
    140         } 
     101        mode = WAIT; 
     102      } 
     103 
     104      if (mode == WAIT) { 
     105        deselectAll(); 
     106        line =  new OverlayPolyline(overlay, dx, dy, dx, dy); 
    141107        line.setDrawing(true); 
    142       } 
    143       else { 
    144         // if node interior, create two new polylines 
    145         if (selectedNode > 0 && selectedNode < line.getNumNodes() - 1) { 
    146           split(line, selectedNode); 
     108        line.setSelected(true); 
     109        configureOverlay(line); 
     110        overlay.addObject(line, pos); 
     111        mode = PLACE; 
     112      } 
     113      else if (mode == PLACE) { 
     114        if (line.getNumNodes() > 1) { 
     115          releaseLine(); 
     116        } 
     117        else {  
    147118          overlay.removeObject(line); 
    148119          unselect(); 
    149           mode = WAIT; 
    150         } 
    151         else { 
    152           // else delete node 
    153           line.deleteNode(selectedNode); 
    154           releaseLine(); 
    155           unselect(); // TODO these are redundant  
    156           mode = WAIT; 
    157         } 
    158       } 
    159     } 
    160     else if (mode == EXTEND || mode == BEG_EXTEND) { 
    161       line.setLastNode(dx, dy); 
    162       mode = PLACE; 
    163     } 
    164     else if (mode == EXTEND_ON_TAIL) { 
    165       line.deleteNode(line.getNumNodes()-1); 
    166       releaseLine(); 
    167       unselect(); 
    168       mode = WAIT; 
    169     } 
     120        } 
     121        mode = WAIT; 
     122      } 
     123      else if (mode == SELECT) { 
     124        if (!ctl) { 
     125          // which node are you near? 
     126          if (selectedNode == line.getNumNodes() - 1) { 
     127            mode = SELECTED_TAIL; 
     128          } 
     129          else if (selectedNode == 0) { 
     130            // you're near the head node. 
     131            // flip nodes around in case user opts to extend polyline 
     132            line.reverseNodes(); 
     133            selectNode(line, line.getNumNodes() - 1); 
     134            mode = SELECTED_TAIL; 
     135          } 
     136          else { 
     137            // you're near some other node 
     138            mode = ADJUST; 
     139          } 
     140          line.setDrawing(true); 
     141        } 
     142        else { // erase 
     143          // if node interior, create two new polylines 
     144          if (selectedNode > 0 && selectedNode < line.getNumNodes() - 1) { 
     145            split(line, selectedNode); 
     146            overlay.removeObject(line); 
     147            unselect(); 
     148            mode = WAIT; 
     149          } 
     150          else { 
     151            // else delete node 
     152            line.deleteNode(selectedNode); 
     153            releaseLine(); 
     154            mode = WAIT; 
     155          } 
     156        } 
     157      } 
     158      else if (mode == EXTEND || mode == BEG_EXTEND) { 
     159        line.setLastNode(dx, dy); 
     160        mode = PLACE; 
     161      } 
     162      else if (mode == EXTEND_ON_TAIL) { 
     163        line.deleteNode(line.getNumNodes()-1); 
     164        releaseLine(); 
     165        mode = WAIT; 
     166      } 
     167    } // end synchronized (line) 
    170168 
    171169    overlay.notifyListeners(new TransformEvent(overlay)); 
     
    180178    //printMode("mouseDrag"); 
    181179 
    182     if (overlay.hasToolChanged()) { 
    183       releaseLine(); 
    184       mode = WAIT; 
    185     } 
    186     if (mode == ADJUST) { 
    187       line.setNodeCoords(selectedNode, dx, dy); 
    188       overlay.notifyListeners(new TransformEvent(overlay)); 
    189     }  
    190     else if (mode == SELECTED_TAIL) { 
    191       mode = ADJUST_TAIL; 
    192       mouseDrag(e, px, py, dx, dy, pos, mods); 
    193     } 
    194     else if (mode == ADJUST_TAIL || mode == CLOSE_LOOP) { 
    195       line.setNodeCoords(selectedNode, dx, dy); 
    196  
    197       // determine if near head 
    198       double dist = getDistanceToNode(0, px, py, display); 
    199        
    200       // if near, highlight head node  
    201       if (dist < THRESH) { 
    202         line.setHighlightNode(selectedNode, CON); 
    203         mode = CLOSE_LOOP; 
    204       } 
    205       else { 
    206         line.setHighlightNode(selectedNode, SEL); 
     180    synchronized (overlay) { 
     181      if (overlay.hasToolChanged()) { 
     182        releaseLine(); 
     183        mode = WAIT; 
     184      } 
     185      if (mode == ADJUST) { 
     186        line.setNodeCoords(selectedNode, dx, dy); 
     187        overlay.notifyListeners(new TransformEvent(overlay)); 
     188      }  
     189      else if (mode == SELECTED_TAIL) { 
    207190        mode = ADJUST_TAIL; 
    208       } 
    209  
    210       overlay.notifyListeners(new TransformEvent(overlay)); 
    211     } 
    212     else if (mode == PLACE || mode == EXTEND || mode == BEG_EXTEND || 
    213         mode == EXTEND_ON_TAIL) { 
    214       mouseMoved(e, px, py, dx, dy, pos, mods); 
    215     } 
     191        mouseDrag(e, px, py, dx, dy, pos, mods); 
     192      } 
     193      else if (mode == ADJUST_TAIL || mode == CLOSE_LOOP) { 
     194        line.setNodeCoords(selectedNode, dx, dy); 
     195 
     196        // determine if near head 
     197        double dist = getDistanceToNode(0, px, py, display); 
     198         
     199        // if near, highlight head node  
     200        if (dist < THRESH) { 
     201          line.setHighlightNode(selectedNode, CON); 
     202          mode = CLOSE_LOOP; 
     203        } 
     204        else { 
     205          line.setHighlightNode(selectedNode, SEL); 
     206          mode = ADJUST_TAIL; 
     207        } 
     208        overlay.notifyListeners(new TransformEvent(overlay)); 
     209      } 
     210      else if (mode == PLACE || mode == EXTEND || mode == BEG_EXTEND || 
     211        mode == EXTEND_ON_TAIL) 
     212      { 
     213        mouseMoved(e, px, py, dx, dy, pos, mods); 
     214      } 
     215    } // end synchronized (line) 
    216216  }  
    217217 
     
    223223    //printMode("mouseUp"); // TEMP 
    224224 
    225     if (overlay.hasToolChanged()) { 
    226       releaseLine(); 
    227       mode = WAIT; 
    228     } 
    229     if (mode == ADJUST) { 
    230       line.updateBoundingBox(); 
    231       line.computeLength(); 
    232       line.setDrawing(false); 
    233       mode = SELECT; 
    234     } 
    235     else if (mode == ADJUST_TAIL) { 
    236       line.updateBoundingBox(); 
    237       line.computeLength(); 
    238       line.setDrawing(false); 
    239       mode = SELECT; 
    240     } 
    241     else if (mode == SELECTED_TAIL) {  
    242       line.turnOffHighlighting(); 
    243       mode = PLACE; 
    244     } 
    245     else if (mode == CLOSE_LOOP) { 
    246       float[] c = line.getNodeCoords(0); 
    247       line.setLastNode(c[0], c[1]);  
    248       line.updateBoundingBox(); 
    249       line.computeLength(); 
    250       line.setDrawing(false); 
    251       selectNode(display, line, line.getNumNodes() - 1); 
    252       mode = SELECT; 
    253     } 
    254     else if (mode == EXTEND_ON_TAIL) { 
    255       mouseDown(e, px, py, dx, dy, pos, mods); 
    256       // basically delete last node and end line 
    257     } 
     225    synchronized (overlay) { 
     226      if (overlay.hasToolChanged()) { 
     227        releaseLine(); 
     228        mode = WAIT; 
     229      } 
     230      if (mode == ADJUST) { 
     231        line.updateBoundingBox(); 
     232        line.computeLength(); 
     233        line.setDrawing(false); 
     234        mode = SELECT; 
     235      } 
     236      else if (mode == ADJUST_TAIL) { 
     237        line.updateBoundingBox(); 
     238        line.computeLength(); 
     239        line.setDrawing(false); 
     240        mode = SELECT; 
     241      } 
     242      else if (mode == SELECTED_TAIL) {  
     243        line.turnOffHighlighting(); 
     244        mode = PLACE; 
     245      } 
     246      else if (mode == CLOSE_LOOP) { 
     247        float[] c = line.getNodeCoords(0); 
     248        line.setLastNode(c[0], c[1]);  
     249        line.updateBoundingBox(); 
     250        line.computeLength(); 
     251        line.setDrawing(false); 
     252        selectNode(line, line.getNumNodes() - 1); 
     253        mode = SELECT; 
     254      } 
     255      else if (mode == EXTEND_ON_TAIL) { 
     256        mouseDown(e, px, py, dx, dy, pos, mods); 
     257        // basically delete last node and end line 
     258      } 
     259    } // end synchronized (line) 
    258260  } 
    259261 
     
    263265    //System.out.println("moved mode = " + mode); 
    264266    DisplayImpl display = (DisplayImpl) e.getDisplay(); 
    265     double[] movePxl = {(double) px, (double) py};  
    266  
    267267    //printMode("mouseMoved"); 
    268268 
    269     if (overlay.hasToolChanged()) { 
    270       releaseLine(); 
    271       mode = WAIT; 
    272     } 
    273     if (mode == WAIT) { 
    274       OverlayObject[] objects = overlay.getObjects(); 
    275       int[] ndxNode =  getNearestNode(display, objects, px, py, THRESH); 
    276  
    277       if (ndxNode != null) { 
    278         int ndx = ndxNode[0]; 
    279         int node = ndxNode[1]; 
    280         //System.out.println("near node " + node + " of object " + obj); // TEMP  
    281         deselectAll(); 
    282         line = (OverlayPolyline) objects[ndx]; 
    283         selectNode(display, line, node); 
    284         mode = SELECT; 
    285       } 
    286     } 
    287     else if (mode == PLACE) { 
    288       line.setNextNode(dx, dy); 
    289        
    290       // keep track of curve length 
    291       // using frequent updates to curvelength in EXTEND, etc. instead 
    292       float[] c = line.getNodeCoords(line.getNumNodes()-2); 
    293       double[] cdub = {(double) c[0], (double) c[1]}; 
    294       double oldLen = line.getCurveLength(); 
    295       line.setCurveLength(oldLen + MathUtil.getDistance(cdub, 
    296             new double[]{dx, dy})); 
    297  
    298       mode = BEG_EXTEND; 
    299     } 
    300     else if (mode == EXTEND || mode == EXTEND_ON_TAIL) { 
    301       // update curve  
    302       adjustLastNode(line, dx, dy); 
    303              
    304       // determine if near head  
    305       double hdist = getDistanceToNode(0, px, py, display); 
    306       // determine if near last node placed  
    307       double ldist = getDistanceToNode(line.getNumNodes() - 2, px, py, display); 
    308        
    309       // if near ndx, highlight selected node differently  
    310       int flag = -1;  
    311       if (ldist < THRESH)  
    312         if (hdist < ldist) flag = 0; 
    313         else if (hdist > ldist) flag = 1; 
    314         else ; 
    315       else if (hdist < THRESH) flag = 0; 
    316  
    317       if (flag == 0) { 
    318         line.setHighlightNode(0, CON); 
    319         mode = CLOSE_LOOP; 
    320       } 
    321       else if (flag == 1) { 
    322         line.setHighlightNode(line.getNumNodes()-1, SEL); 
    323         mode = EXTEND_ON_TAIL; 
    324       } 
    325       else if (flag == -1) { 
    326         line.turnOffHighlighting(); 
    327         mode = EXTEND; 
    328       } 
    329     } 
    330     else if (mode == BEG_EXTEND) { 
    331       // update curve length 
    332       adjustLastNode(line, dx, dy); 
    333        
    334       // determine if near head  
    335       double hdist = getDistanceToNode(0, px, py, display); 
    336       // determine if near last node placed  
    337       double ldist = getDistanceToNode(line.getNumNodes() - 2, px, py, display); 
    338  
    339       // highlight first or last visible node if near 
    340       if (hdist < THRESH) { 
    341         line.setHighlightNode(line.getNumNodes()-1, CON); 
    342         mode = CLOSE_LOOP; 
    343       } 
    344       
    345       // switch modes if you've dragged far enough from last node placed 
    346       if (ldist > 10.0) { 
    347         mode = EXTEND; 
    348       } 
    349     } 
    350     else if (mode == CLOSE_LOOP) { 
    351       line.setLastNode(dx, dy); 
    352       // determine if near head:  
    353       double dist = getDistanceToNode(0, px, py, display); 
    354       
    355       // if not, turn off highlighting  
    356       if (dist > THRESH) { 
    357         line.turnOffHighlighting(); 
    358         mode = EXTEND;  
    359       } 
    360     } 
    361     else if (mode == SELECT) { 
    362       // get distance btw. pointer and selectedNode 
    363       float[] nodeFlt = line.getNodeCoords (selectedNode);  
    364       double[] nodeDbl = {(double) nodeFlt[0], (double) nodeFlt[1]}; 
    365       int[] nodePxl = CursorUtil.domainToPixel(display, nodeDbl);  
    366       double[] nodePxlDbl = {(double) nodePxl[0], (double) nodePxl[1]}; 
    367       double dist = MathUtil.getDistance(movePxl, nodePxlDbl);  
    368  
    369       double threshold = 2.0; 
    370       if (dist > threshold) { 
    371         line.turnOffHighlighting(); 
    372         unselect(); 
     269    synchronized (overlay) { 
     270      if (overlay.hasToolChanged()) { 
     271        releaseLine(); 
    373272        mode = WAIT; 
    374273      } 
    375     } 
    376     else if (mode == ADJUST) { 
    377     } 
    378     overlay.notifyListeners(new TransformEvent(overlay)); 
     274      if (mode == WAIT) { 
     275        OverlayObject[] objects = overlay.getObjects(); 
     276        int[] ndxNode =  getNearestNode(display, objects, px, py, THRESH); 
     277 
     278        if (ndxNode != null) { 
     279          int ndx = ndxNode[0]; 
     280          int node = ndxNode[1]; 
     281          //System.out.println("near node " + node + " of object " + obj); // TEMP  
     282          deselectAll(); 
     283          line = (OverlayPolyline) objects[ndx]; 
     284          selectNode(line, node); 
     285          mode = SELECT; 
     286        } 
     287      } 
     288      else if (mode == PLACE) { 
     289        line.setNextNode(dx, dy); 
     290         
     291        // keep track of curve length 
     292        // using frequent updates to curvelength in EXTEND, etc. instead 
     293        float[] c = line.getNodeCoords(line.getNumNodes()-2); 
     294        double[] cdub = {(double) c[0], (double) c[1]}; 
     295        double oldLen = line.getCurveLength(); 
     296        line.setCurveLength(oldLen + MathUtil.getDistance(cdub, 
     297              new double[]{dx, dy})); 
     298 
     299        mode = BEG_EXTEND; 
     300      } 
     301      else if (mode == EXTEND || mode == EXTEND_ON_TAIL) { 
     302        // update curve  
     303        adjustLastNode(line, dx, dy); 
     304               
     305        // determine if near head  
     306        double hdist = getDistanceToNode(0, px, py, display); 
     307        // determine if near last node placed  
     308        double ldist = getDistanceToNode(line.getNumNodes() - 2, px, py, display); 
     309         
     310        // if near ndx, highlight selected node differently  
     311        int flag = -1;  
     312        if (ldist < THRESH)  
     313          if (hdist < ldist) flag = 0; 
     314          else if (hdist > ldist) flag = 1; 
     315          else ; 
     316        else if (hdist < THRESH) flag = 0; 
     317 
     318        if (flag == 0) { 
     319          line.setHighlightNode(0, CON); 
     320          mode = CLOSE_LOOP; 
     321        } 
     322        else if (flag == 1) { 
     323          line.setHighlightNode(line.getNumNodes()-1, SEL); 
     324          mode = EXTEND_ON_TAIL; 
     325        } 
     326        else if (flag == -1) { 
     327          line.turnOffHighlighting(); 
     328          mode = EXTEND; 
     329        } 
     330      } 
     331      else if (mode == BEG_EXTEND) { 
     332        // update curve length 
     333        adjustLastNode(line, dx, dy); 
     334         
     335        // determine if near head  
     336        double hdist = getDistanceToNode(0, px, py, display); 
     337        // determine if near last node placed  
     338        double ldist = getDistanceToNode(line.getNumNodes() - 2, px, py, display); 
     339 
     340        // highlight first or last visible node if near 
     341        if (hdist < THRESH) { 
     342          line.setHighlightNode(line.getNumNodes()-1, CON); 
     343          mode = CLOSE_LOOP; 
     344        } 
     345        
     346        // switch modes if you've dragged far enough from last node placed 
     347        if (ldist > 10.0) { 
     348          mode = EXTEND; 
     349        } 
     350      } 
     351      else if (mode == CLOSE_LOOP) { 
     352        line.setLastNode(dx, dy); 
     353        // determine if near head:  
     354        double dist = getDistanceToNode(0, px, py, display); 
     355        
     356        // if not, turn off highlighting  
     357        if (dist > THRESH) { 
     358          line.turnOffHighlighting(); 
     359          mode = EXTEND;  
     360        } 
     361      } 
     362      else if (mode == SELECT) { 
     363        // get distance btw. pointer and selectedNode 
     364        double dist = getDistanceToNode(selectedNode, px, py, display); 
     365 
     366        double threshold = 2.0; 
     367        if (dist > threshold) { 
     368          line.turnOffHighlighting(); 
     369          unselect(); 
     370          mode = WAIT; 
     371        } 
     372      } 
     373      else if (mode == ADJUST) { 
     374      } 
     375      overlay.notifyListeners(new TransformEvent(overlay)); 
     376    }// end synchronized (line) 
    379377  } 
    380378 
     
    480478      line.setDrawing(false); 
    481479      line.setSelected(true); 
    482       line = null; 
    483       selectedNode = -1; 
     480      unselect(); 
    484481    } 
    485482  } 
     
    492489   
    493490  /** Selects a particular node */ 
    494   private void selectNode(DisplayImpl display, OverlayPolyline pln, int node) { 
     491  private void selectNode(OverlayPolyline pln, int node) { 
    495492    line.setDrawing(false); 
    496493    line.setSelected(true); 
    497494    selectedNode = node; 
    498495    pln.setHighlightNode(node, SEL); 
    499   } 
    500    
    501   /** Unhighlights all polylines in a list of OverlayObjects */ 
    502   private void unHighlightAllPolylines(OverlayObject[] objects) { 
    503     for (int i=0; i<objects.length; i++) { 
    504       if (objects[i] instanceof OverlayPolyline)  
    505         ((OverlayPolyline) objects[i]).turnOffHighlighting(); 
    506     } 
    507496  } 
    508497 
     
    548537    else return new int[]{nearestPline, nearestNode}; 
    549538  } 
    550   
    551   /** Casts an array of floats to doubles */ 
    552   private double[][] floatsToPixelDoubles(DisplayImpl d, float[][] nodes) { 
    553     double[][] nodesDbl = new double[nodes.length][nodes[0].length]; 
    554     for (int j=0; j<nodes[0].length; j++) { 
    555       int[] c = CursorUtil.domainToPixel(d, new double[]{ 
    556         (double) nodes[0][j], (double) nodes[1][j]}); 
    557       nodesDbl[0][j] = (double) c[0]; 
    558       nodesDbl[1][j] = (double) c[1]; 
    559     } 
    560     return nodesDbl; 
    561   } 
    562539 
    563540  /** Prints node array of current freeform; for debugging */ 
     
    586563    } 
    587564  } 
    588 } // end class FreeformTool 
     565} // end class PolylineTool  
Note: See TracChangeset for help on using the changeset viewer.