Changeset 2249


Ignore:
Timestamp:
02/08/07 19:18:15 (13 years ago)
Author:
sorber
Message:

Changed FreeformTool to use pixel coordinates instead of domain coordinates for thresholding (to noun a verb).

File:
1 edited

Legend:

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

    r2246 r2249  
    2626import loci.visbio.data.TransformEvent; 
    2727import loci.visbio.util.MathUtil; 
     28import loci.visbio.util.DisplayUtil; 
    2829import java.awt.event.InputEvent; 
    2930import java.util.Vector; 
    3031import visad.DisplayEvent; 
     32import visad.DisplayImpl; 
    3133 
    3234/** FreeformTool is the tool for creating freeform objects. */ 
     
    4244 
    4345  /** Threshhold within which click must occur to invoke edit mode. */ 
    44   protected static final double EDIT_THRESH = 5.0; 
     46  protected static final double EDIT_THRESH = 6.0; 
    4547 
    4648  /** 
     
    4850   * invoke extend mode or reconnect a tendril. 
    4951   */ 
    50   protected static final double RECONNECT_THRESH = 0.5; 
     52  protected static final double RECONNECT_THRESH = 1.0; 
    5153 
    5254  /** Constant for "erase" edit mode. */ 
     
    9597    float dx, float dy, int[] pos, int mods) 
    9698  { 
     99    // -- housekeeping 
    97100    boolean ctl = (mods & InputEvent.CTRL_MASK) != 0; 
     101    DisplayImpl display = (DisplayImpl) e.getDisplay(); 
     102 
     103    double dpx = (double) px; 
     104    double dpy = (double) py; 
    98105     
    99     OverlayFreeform target = getClosestFreeform(dx, dy); 
     106    // -- main 
     107    // find closest freeform 
     108    OverlayFreeform target = getClosestFreeform(display, dpx, dpy); 
    100109    if (target != null) { 
    101110      freeform = target; 
    102       double[] distSegWt = MathUtil.getDistSegWt(freeform.getNodes(), dx, dy); 
     111      // DISTANCE COMPUTATION (all in double precision) 
     112      // need to compare pair of ints with float[][] 
     113      // ACS why am I doing this here?  Can this be in domain space 
     114      double[][] nodesDbl = floatsToPixelDoubles(display, freeform.getNodes()); 
     115      double[] distSegWt = MathUtil.getDistSegWt(nodesDbl, dpx, dpy); 
    103116      double dist = distSegWt[0]; 
    104117      int seg = (int) distSegWt[1]; 
     
    170183    boolean ctl = (mods & InputEvent.CTRL_MASK) != 0; 
    171184 
     185    DisplayImpl display = (DisplayImpl) e.getDisplay(); 
     186 
     187    double dpx = (double) px; 
     188    double dpy = (double) py; 
     189 
    172190    if (ctl && mode == DRAW) { 
    173191        freeform.truncateNodeArray(); 
     
    186204        float[] tail = f.getNodeCoords(f.getNumNodes()-1); 
    187205 
    188         double[] headd = {(double) head[0], (double) head[1]}; 
    189         double[] taild = {(double) tail[0], (double) tail[1]}; 
    190         double[] drag = {(double) dx, (double) dy}; 
    191  
    192         double hdist = MathUtil.getDistance(drag, headd); 
    193         double tdist = MathUtil.getDistance(drag, taild); 
     206        double[] headDbl = {(double) head[0], (double) head[1]}; 
     207        double[] tailDbl = {(double) tail[0], (double) tail[1]}; 
     208        //double[] drag = {(double) dx, (double) dy}; 
     209        int[] headPxl = DisplayUtil.domainToPixel(display, headDbl); 
     210        int[] tailPxl = DisplayUtil.domainToPixel(display, tailDbl); 
     211        double[]  headPxlDbl = new double[] {(double) headPxl[0],  
     212          (double) headPxl[1]}; 
     213        double[] tailPxlDbl = new double[] {(double) tailPxl[0], 
     214          (double) tailPxl[1]}; 
     215        double[] drag = {dpx, dpy}; 
     216 
     217        // DISTANCE computation  
     218        // compare pair of ints with pair of floats 
     219        double hdist = MathUtil.getDistance(drag, headPxlDbl); 
     220        double tdist = MathUtil.getDistance(drag, tailPxlDbl); 
    194221 
    195222        boolean isHead = hdist < tdist ? true : false; 
     
    210237      else { 
    211238        // compute distance from last node 
     239        // DISTANCE COMPUTATION: compare floats and ints 
    212240        float lastX = freeform.getLastNodeX(); 
    213241        float lastY = freeform.getLastNodeY(); 
     
    216244        double dist = Math.sqrt (distX*distX + distY*distY); 
    217245 
    218         if (dist > DRAW_THRESH) { 
     246        double[] last = new double[]{(double) lastX, (double) lastY}; 
     247        int[] lastPxl = DisplayUtil.domainToPixel(display, last); 
     248 
     249        double dxPxl = dpx - (double) lastPxl[0]; 
     250        double dyPxl = dpy - (double) lastPxl[1]; 
     251        double distPxl = Math.sqrt (dxPxl*dxPxl + dyPxl*dyPxl); 
     252 
     253        if (distPxl > DRAW_THRESH) { 
    219254          freeform.setNextNode(dx, dy); 
    220255          double len = freeform.getCurveLength(); 
    221256          freeform.setCurveLength(len + dist); 
    222           // I debated whether to update this realtime.  This is an efficient 
     257          // I debated whether to call setBoundaries with every mouseDrag. 
     258          // This is an efficient 
    223259          // method, but updating realtime for erasing requires an O(n) 
    224           // operation every time a node is deleted. 
     260          // scan of the nodes every time a node is deleted. 
    225261          freeform.setBoundaries(dx, dy); 
    226262        } 
     
    230266    else if (mode == ERASE) { 
    231267      if (freeform == null) { 
    232         OverlayFreeform target = getClosestFreeform(dx, dy); 
     268        // DISTANCE COMPUTATION compare floats with floats 
     269        OverlayFreeform target = getClosestFreeform(display, dpx, dpy); 
    233270        if (target != null) freeform = target; 
    234271      } 
     
    238275      float[] end = freeform.getNodeCoords (freeform.getNumNodes() - 1); 
    239276 
    240       double[] drag = {(double) dx, (double) dy}; 
    241       double[] begd = {(double) beg[0], (double) beg[1]}; 
    242       double[] endd = {(double) end[0], (double) end[1]}; 
    243  
    244       double bdist = MathUtil.getDistance(drag, begd); 
    245       double edist = MathUtil.getDistance(drag, endd); 
     277      double[] drag = {dpx, dpy}; 
     278      double[] begDbl = {(double) beg[0], (double) beg[1]}; 
     279      double[] endDbl = {(double) end[0], (double) end[1]}; 
     280      int[] begPxl = DisplayUtil.domainToPixel(display, begDbl); 
     281      int[] endPxl = DisplayUtil.domainToPixel(display, endDbl); 
     282      double[] begPxlDbl = {(double) begPxl[0], (double) begPxl[1]}; 
     283      double[] endPxlDbl = {(double) endPxl[0], (double) endPxl[1]}; 
     284 
     285      //DISTANCE COMPUTATION ints and floats 
     286      double bdist = MathUtil.getDistance(drag, begPxlDbl); 
     287      double edist = MathUtil.getDistance(drag, endPxlDbl); 
    246288 
    247289      boolean closerToEnd = edist < bdist ? true : false; 
     
    251293        if (!closerToEnd) freeform.reverseNodes(); 
    252294        if (ctl) { 
    253           double[] nearest = new double[2], pd = new double[2]; 
    254           float[] p; 
     295          double[] nearest = new double[2], lastDbl = new double[2]; 
     296          float[] last; 
    255297          double delta; 
    256298          int index; 
    257           if (closerToEnd) nearest = endd; 
    258           else nearest = begd; 
     299          if (closerToEnd) nearest = endDbl; 
     300          else nearest = begDbl; 
    259301 
    260302          // adjust curve length 
    261303          index = freeform.getNumNodes()-1; // last node in freef 
    262           p = freeform.getNodeCoords(index); 
    263           pd[0] = (double) p[0]; 
    264           pd[1] = (double) p[1]; 
    265  
    266           delta = MathUtil.getDistance (nearest, pd); 
     304          last = freeform.getNodeCoords(index); 
     305          lastDbl[0] = (double) last[0]; 
     306          lastDbl[1] = (double) last[1]; 
     307 
     308          // DISTANCE COMPUTATION  
     309          // floats and doubles 
     310          delta = MathUtil.getDistance (nearest, lastDbl); 
    267311          freeform.setCurveLength(freeform.getCurveLength() - delta); 
    268312 
     
    283327      // extend tendril and or reconnect 
    284328      // get coords of prev node 
    285       float[] pcoordsf; 
     329      float[] prvCrdsFlt; 
    286330      if (tendril.tip >= 0) { 
    287331        // previous node is tendril.tip 
    288         pcoordsf = freeform.getNodeCoords(tendril.tip); 
     332        prvCrdsFlt = freeform.getNodeCoords(tendril.tip); 
    289333      } 
    290334      else { 
    291335        // previous node is tendril.start 
    292         pcoordsf = freeform.getNodeCoords(tendril.start); 
    293       } 
    294  
    295       double[] pcoordsd = {(double) pcoordsf[0], (double) pcoordsf[1]}; 
     336        prvCrdsFlt = freeform.getNodeCoords(tendril.start); 
     337      } 
     338 
     339      double[] prvCrdsDbl= {(double) prvCrdsFlt[0], (double) prvCrdsFlt[1]}; 
     340      int[] prvCrdsPxl = DisplayUtil.domainToPixel(display, prvCrdsDbl); 
     341      double[] prvCrdsPxlDbl = {(double) prvCrdsPxl[0], (double) prvCrdsPxl[1]}; 
     342       
    296343      // coords of this mouseDrag event 
    297       double[] thiscoords = {(double) dx, (double) dy}; 
    298       double dragDist = MathUtil.getDistance(pcoordsd, thiscoords); 
     344      double[] drag = {dpx, dpy}; 
     345      double dragDist = MathUtil.getDistance(drag, prvCrdsPxlDbl); 
    299346 
    300347      // compute distance to pre, post chunks of curve 
    301       double[] distSegWtPre = MathUtil.getDistSegWt(pre, dx, dy); 
    302       double[] distSegWtPost = MathUtil.getDistSegWt(post, dx, dy); 
     348      // floats and ints 
     349      double[][] preDbl = floatsToPixelDoubles(display, pre); 
     350      double[][] postDbl = floatsToPixelDoubles(display, post); 
     351 
     352      double[] distSegWtPre = MathUtil.getDistSegWt(preDbl, dpx, dpy); 
     353      double[] distSegWtPost = MathUtil.getDistSegWt(postDbl, dpx, dpy); 
    303354 
    304355      boolean equalsCase = false; 
     
    325376          } 
    326377          else { // later drags 
    327             freeform.insertNode(tendril.tip+1, pcoordsf[0], pcoordsf[1]); 
     378            freeform.insertNode(tendril.tip+1, prvCrdsFlt[0], prvCrdsFlt[1]); 
    328379            freeform.insertNode(tendril.tip+1, dx, dy); 
    329380            tendril.tip++; 
     
    567618            // distance to freeform (slower) 
    568619            double[] distSegWt = 
     620              // DISTANCE COMPUTATION  
     621              // compare float[][] with ints 
    569622              MathUtil.getDistSegWt(currentFreeform.getNodes(), dx, dy); 
    570623            double distance = distSegWt[0]; 
     
    580633  } 
    581634 
     635  /** Returns the closest (subject to a threshhold) OverlayFreeform object to 
     636   *  the given point 
     637   */ 
     638  protected OverlayFreeform getClosestFreeform(DisplayImpl display, double dpx,  
     639      double dpy) { 
     640    // returns only objects at the current dimensional position 
     641    OverlayObject[] objects = overlay.getObjects(); 
     642    // Q: Hey, are all of these OverlayFreeforms? 
     643    // A: No, it returns OverlayObjects of all types 
     644 
     645    OverlayFreeform closestFreeform = null; 
     646    if (objects != null) { 
     647      double minDistance = Double.MAX_VALUE; 
     648      for (int i = 0; i < objects.length; i++) { 
     649        OverlayObject currentObject = objects[i]; 
     650        if (currentObject instanceof OverlayFreeform) { 
     651          OverlayFreeform currentFreeform = (OverlayFreeform) currentObject; 
     652          // performance opportunity: 
     653          // I removed the check on the bounding box 
     654          // Should the getDistance method return a distance in  
     655          // pixel coordinates? 
     656          double[][] nodesDbl = floatsToPixelDoubles(display,  
     657              currentFreeform.getNodes()); 
     658          double[] distSegWt = 
     659            // DISTANCE COMPUTATION  
     660            // compare float[][] with ints 
     661            MathUtil.getDistSegWt(nodesDbl, dpx, dpy); 
     662          double distance = distSegWt[0]; 
     663          if (distance < EDIT_THRESH && distance < minDistance) { 
     664            minDistance = distance; 
     665            closestFreeform = currentFreeform; 
     666          } 
     667        } // end (.. < EDIT_THRESH) 
     668      } // end for 
     669    } // end if 
     670    return closestFreeform; 
     671  } 
     672 
    582673  /** 
    583674   * Computes a point along the line segment 
     
    593684  } 
    594685 
     686  /** Casts an array of floats to doubles */ 
     687  private double[][] floatsToPixelDoubles(DisplayImpl d, float[][] nodes) { 
     688    double[][] nodesDbl = new double[nodes.length][nodes[0].length]; 
     689    for (int j=0; j<nodes[0].length; j++) { 
     690      int[] c = DisplayUtil.domainToPixel(d, new double[]{ 
     691        (double) nodes[0][j], (double) nodes[1][j]}); 
     692      nodesDbl[0][j] = (double) c[0]; 
     693      nodesDbl[1][j] = (double) c[1]; 
     694    } 
     695    return nodesDbl; 
     696  } 
     697 
    595698  /** Prints node array of current freeform; for debugging */ 
    596699  private void printNodes(float[][] nodes) { 
Note: See TracChangeset for help on using the changeset viewer.