Changeset 2863


Ignore:
Timestamp:
06/13/07 12:01:18 (13 years ago)
Author:
sorber
Message:

Improved method for calculating bisector vector. Regrouped methods.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/visbio/util/MathUtil.java

    r2855 r2863  
    330330 
    331331  /** Creates the vector p2-(minus) p1. */ 
    332   public static float[] vector(float[] p1, float[] p2) { 
     332  public static float[] vector(float[] p2, float[] p1) { 
    333333    // assumes p1, p2 have same lengths 
    334     if (p1.length != p2.length) return null; 
    335     int len = p1.length; 
     334    if (p2.length != p1.length) return null; 
     335    int len = p2.length; 
    336336    float[] v = new float[len]; 
    337337    for (int i=0; i<len; i++) { 
    338       v[i] = p1[i] - p2[i]; 
     338      v[i] = p2[i] - p1[i]; 
    339339    } 
    340340    return v; 
    341341  } 
     342 
     343  /** Adds two N-D vectors. */ 
     344  public static float[] add(float[] v1, float[] v2) { 
     345    // v1 and v2 should have same lengths 
     346    if (v1.length != v2.length) return null; 
     347    int len = v1.length; 
     348    float[] r = new float[v1.length]; 
     349    for (int i=0; i<v1.length; i++) { 
     350      r[i] = v1[i] + v2[i]; 
     351    } 
     352    return r; 
     353  } 
     354 
     355  /** Multiplies an N-D vector by a scalar. */ 
     356  public static float[] scalarMultiply(float[] v, float s) { 
     357    int len = v.length; 
     358    float[] r = new float[len]; 
     359    for (int i=0; i<len; i++) { 
     360      r[i] = v[i] * s; 
     361    } 
     362    return r; 
     363  } 
     364 
     365  // -- Computational Geometry Methods -- 
    342366 
    343367  /** Whether the point a is inside the N-D box implied by points 
     
    345369   *  b1-b2; in 3D, whether a is inside the cube with diagonal b1-b2). 
    346370   */  
    347   public static boolean between(float[] a, float[] b1, float[] b2) { 
     371  public static boolean inside(float[] a, float[] b1, float[] b2) { 
    348372    // assumes a, b1, b2 have same lengths 
    349373    boolean between = true; 
     
    360384  } 
    361385 
     386  /** Obtains the z-coordinate of the cross product of the 2D vectors 
     387   *  p2-p1 and p3-p2, useful for determining whether the curve  
     388   *  p1->p2->p3 is curving to the right or left. */ 
     389  public static float orient2D(float[] p1, float[] p2, float[] p3) { 
     390    float x1 = p1[0]; float y1 = p1[1]; 
     391    float x2 = p2[0]; float y2 = p2[1]; 
     392    float x3 = p3[0]; float y3 = p3[1]; 
     393    // z coord. of cross product of p2-(minus)p1 and p3-p2  
     394    float z = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2); 
     395    return z; 
     396  } 
     397 
     398  /** Gets a vector perpendicular to the vector p2-p1, pointing to the right  
     399   *  with respect to the direction of p2-p1. */ 
     400  public static float[] getRightPerpendicularVector2D(float[] p2, float[] p1) { 
     401    float[] v = vector(p2, p1); 
     402    float[] vPerp = {v[1], -v[0]}; 
     403    return unit(vPerp); 
     404  } 
     405 
    362406  /** Gets a unit vector which bisects (p1 - p2) and (p3 - p2).  */ 
    363   public static float[] getBisectorVector2D(float[] p1, float[] p2, float[] p3) 
     407  public static float[] getRightBisectorVector2D(float[] p1, float[] p2, 
     408      float[] p3) 
    364409  {  
    365     System.out.println("entering getBisectorVector2D ..."); //TEMP 
     410    // System.out.println("entering getBisectorVector2D ..."); //TEMP 
     411    // Always retrieves the bisector vector on the right (as opposed to left) 
     412    // side of the angle made by the two vectors. 
     413 
     414    // z coord. of cross product of p2-(minus)p1 and p3-p2  
     415    float z = orient2D(p1, p2, p3); 
     416 
    366417    float[] v1 = vector(p1, p2); 
    367418    float[] v2 = vector(p3, p2); 
     
    369420    float[] v2Hat = unit(v2); 
    370421    float[] vAvg = {(v1Hat[0] + v2Hat[0]) / 2f, (v1Hat[1] + v2Hat[1]) / 2f}; 
    371      
    372     float[] bisector; 
    373     if (vAvg[0] == 0 && vAvg[1] == 0) { 
    374       float[] aBisector = new float[]{-v1[1], v1[0]}; 
    375       bisector = unit(aBisector); 
    376     } 
    377     else { 
    378       bisector = unit(vAvg); 
    379     } 
     422 
     423    float[] aBisector = null; // ... says what? 
     424    if ((vAvg[0] == 0 && vAvg[1] == 0) || z == 0) { 
     425      // Sometimes, z can have a very small nonzero value even when  
     426      // the points have the same x=coordinate 
     427      // (Apparently due to floating point arithmetic?) 
     428      // To handle that case, test for parallel vectors without referring to z, 
     429      // by comparing vAvg to <0, 0>. 
     430      float[] v = MathUtil.vector(p2, p1); 
     431      aBisector = new float[]{v[1], -v[0]}; 
     432    } 
     433    else if (z < 0) { 
     434      // the curve is curving to the right--vAvg points right 
     435      aBisector = vAvg; 
     436    } 
     437    else if (z > 0) { 
     438      // the curve is curving to the left--vAvg points left 
     439      aBisector = new float[]{-vAvg[0], -vAvg[1]}; 
     440    } 
     441 
     442    System.out.println("z = " + z); 
     443    System.out.println("vAvg = " + vAvg[0] + ", " + vAvg[1]); 
     444 
     445    float[] bisector = unit(aBisector); 
    380446       
    381     // System.out.println("v1 = " + v1[0] + " " + v1[1]); 
    382     // System.out.println("v2 = " + v2[0] + " " + v2[1]); 
    383     // System.out.println("v1Hat = " + v1Hat[0] + " " + v1Hat[1]); 
    384     // System.out.println("v2Hat = " + v2Hat[0] + " " + v2Hat[1]); 
    385     // System.out.println("vAvg = " + vAvg[0] + " " + vAvg[1]); 
    386     // System.out.println("bisector = " + bisector[0] + " " + bisector[1]); 
    387     // System.out.println("p1a = " + p1a[0] + " " + p1a[1]); 
    388     // System.out.println("p2a = " + p2a[0] + " " + p2a[1]); 
    389     // System.out.println("p4a = " + p4a[0] + " " + p4a[1]); 
    390     // System.out.println("v42 = " + v42[0] + " " + v42[1]); 
    391     // System.out.println("v42Hat = " +v42Hat[0] + " " + v42Hat[1]); 
    392447    return bisector; 
    393448  } 
    394449 
    395   /** Adds two N-D vectors. */ 
    396   public static float[] add(float[] v1, float[] v2) { 
    397     // v1 and v2 should have same lengths 
    398     if (v1.length != v2.length) return null; 
    399     int len = v1.length; 
    400     float[] r = new float[v1.length]; 
    401     for (int i=0; i<v1.length; i++) { 
    402       r[i] = v1[i] + v2[i]; 
    403     } 
    404     return r; 
    405   } 
    406  
    407   /** Multiplies an N-D vector by a scalar. */ 
    408   public static float[] scalarMultiply(float[] v, float s) { 
    409     int len = v.length; 
    410     float[] r = new float[len]; 
    411     for (int i=0; i<len; i++) { 
    412       r[i] = v[i] * s; 
    413     } 
    414     return r; 
    415   } 
    416450 
    417451} 
Note: See TracChangeset for help on using the changeset viewer.