Changeset 2249
 Timestamp:
 02/08/07 19:18:15 (13 years ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

trunk/loci/visbio/overlays/FreeformTool.java
r2246 r2249 26 26 import loci.visbio.data.TransformEvent; 27 27 import loci.visbio.util.MathUtil; 28 import loci.visbio.util.DisplayUtil; 28 29 import java.awt.event.InputEvent; 29 30 import java.util.Vector; 30 31 import visad.DisplayEvent; 32 import visad.DisplayImpl; 31 33 32 34 /** FreeformTool is the tool for creating freeform objects. */ … … 42 44 43 45 /** 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; 45 47 46 48 /** … … 48 50 * invoke extend mode or reconnect a tendril. 49 51 */ 50 protected static final double RECONNECT_THRESH = 0.5;52 protected static final double RECONNECT_THRESH = 1.0; 51 53 52 54 /** Constant for "erase" edit mode. */ … … 95 97 float dx, float dy, int[] pos, int mods) 96 98 { 99 //  housekeeping 97 100 boolean ctl = (mods & InputEvent.CTRL_MASK) != 0; 101 DisplayImpl display = (DisplayImpl) e.getDisplay(); 102 103 double dpx = (double) px; 104 double dpy = (double) py; 98 105 99 OverlayFreeform target = getClosestFreeform(dx, dy); 106 //  main 107 // find closest freeform 108 OverlayFreeform target = getClosestFreeform(display, dpx, dpy); 100 109 if (target != null) { 101 110 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); 103 116 double dist = distSegWt[0]; 104 117 int seg = (int) distSegWt[1]; … … 170 183 boolean ctl = (mods & InputEvent.CTRL_MASK) != 0; 171 184 185 DisplayImpl display = (DisplayImpl) e.getDisplay(); 186 187 double dpx = (double) px; 188 double dpy = (double) py; 189 172 190 if (ctl && mode == DRAW) { 173 191 freeform.truncateNodeArray(); … … 186 204 float[] tail = f.getNodeCoords(f.getNumNodes()1); 187 205 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); 194 221 195 222 boolean isHead = hdist < tdist ? true : false; … … 210 237 else { 211 238 // compute distance from last node 239 // DISTANCE COMPUTATION: compare floats and ints 212 240 float lastX = freeform.getLastNodeX(); 213 241 float lastY = freeform.getLastNodeY(); … … 216 244 double dist = Math.sqrt (distX*distX + distY*distY); 217 245 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) { 219 254 freeform.setNextNode(dx, dy); 220 255 double len = freeform.getCurveLength(); 221 256 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 223 259 // method, but updating realtime for erasing requires an O(n) 224 // operationevery time a node is deleted.260 // scan of the nodes every time a node is deleted. 225 261 freeform.setBoundaries(dx, dy); 226 262 } … … 230 266 else if (mode == ERASE) { 231 267 if (freeform == null) { 232 OverlayFreeform target = getClosestFreeform(dx, dy); 268 // DISTANCE COMPUTATION compare floats with floats 269 OverlayFreeform target = getClosestFreeform(display, dpx, dpy); 233 270 if (target != null) freeform = target; 234 271 } … … 238 275 float[] end = freeform.getNodeCoords (freeform.getNumNodes()  1); 239 276 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); 246 288 247 289 boolean closerToEnd = edist < bdist ? true : false; … … 251 293 if (!closerToEnd) freeform.reverseNodes(); 252 294 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; 255 297 double delta; 256 298 int index; 257 if (closerToEnd) nearest = end d;258 else nearest = beg d;299 if (closerToEnd) nearest = endDbl; 300 else nearest = begDbl; 259 301 260 302 // adjust curve length 261 303 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); 267 311 freeform.setCurveLength(freeform.getCurveLength()  delta); 268 312 … … 283 327 // extend tendril and or reconnect 284 328 // get coords of prev node 285 float[] p coordsf;329 float[] prvCrdsFlt; 286 330 if (tendril.tip >= 0) { 287 331 // previous node is tendril.tip 288 p coordsf= freeform.getNodeCoords(tendril.tip);332 prvCrdsFlt = freeform.getNodeCoords(tendril.tip); 289 333 } 290 334 else { 291 335 // 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 296 343 // 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); 299 346 300 347 // 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); 303 354 304 355 boolean equalsCase = false; … … 325 376 } 326 377 else { // later drags 327 freeform.insertNode(tendril.tip+1, p coordsf[0], pcoordsf[1]);378 freeform.insertNode(tendril.tip+1, prvCrdsFlt[0], prvCrdsFlt[1]); 328 379 freeform.insertNode(tendril.tip+1, dx, dy); 329 380 tendril.tip++; … … 567 618 // distance to freeform (slower) 568 619 double[] distSegWt = 620 // DISTANCE COMPUTATION 621 // compare float[][] with ints 569 622 MathUtil.getDistSegWt(currentFreeform.getNodes(), dx, dy); 570 623 double distance = distSegWt[0]; … … 580 633 } 581 634 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 582 673 /** 583 674 * Computes a point along the line segment … … 593 684 } 594 685 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 595 698 /** Prints node array of current freeform; for debugging */ 596 699 private void printNodes(float[][] nodes) {
Note: See TracChangeset
for help on using the changeset viewer.