Exemple #1
0
 public boolean intersects(Circle circle) {
   // using Vector Projection
   // https://en.wikipedia.org/wiki/Vector_projection
   Vector c = Vector.create(circle.x(), circle.y());
   Vector a = Vector.create(x1, y1);
   Vector cMinusA = c.minus(a);
   float radiusSquared = circle.radius() * circle.radius();
   if (x1 == x2 && y1 == y2) {
     return cMinusA.modulusSquared() <= radiusSquared;
   } else {
     Vector b = Vector.create(x2, y2);
     Vector bMinusA = b.minus(a);
     float bMinusAModulus = bMinusA.modulus();
     float lambda = cMinusA.dot(bMinusA) / bMinusAModulus;
     // if projection is on the segment
     if (lambda >= 0 && lambda <= bMinusAModulus) {
       Vector dMinusA = bMinusA.times(lambda / bMinusAModulus);
       // calculate distance to line from c using pythagoras' theorem
       return cMinusA.modulusSquared() - dMinusA.modulusSquared() <= radiusSquared;
     } else {
       // return true if and only if an endpoint is within radius of
       // centre
       return cMinusA.modulusSquared() <= radiusSquared
           || c.minus(b).modulusSquared() <= radiusSquared;
     }
   }
 }
  public void testMinus() throws Exception {
    Vector val = test.minus(test);
    assertEquals("size", test.size(), val.size());
    for (int i = 0; i < test.size(); i++) {
      assertEquals("get [" + i + ']', 0.0, val.get(i));
    }

    val = test.minus(test).minus(test);
    assertEquals("cardinality", test.size(), val.size());
    for (int i = 0; i < test.size(); i++) {
      assertEquals("get [" + i + ']', 0.0, val.get(i) + test.get(i));
    }

    Vector val1 = test.plus(1);
    val = val1.minus(test);
    for (int i = 0; i < test.size(); i++) {
      assertEquals("get [" + i + ']', 1.0, val.get(i));
    }

    val1 = test.plus(-1);
    val = val1.minus(test);
    for (int i = 0; i < test.size(); i++) {
      assertEquals("get [" + i + ']', -1.0, val.get(i));
    }
  }
  // intersectRayAndTriangle(): intersect a ray with a 3D triangle
  // Input: a ray R, and a triangle T
  // Output: *I = intersection point (when it exists)
  // Return: -1 = triangle is degenerate (a segment or point)
  // 0 = disjoint (no intersect)
  // 1 = intersect in unique point I1
  // 2 = are in the same plane
  public static int intersectRayAndTriangle(Ray R, Triangle T, float[] I) {
    float[] u, v, n; // triangle vectors
    float[] dir, w0, w; // ray vectors
    float r, a, b; // params to calc ray-plane intersect

    // get triangle edge vectors and plane normal
    u = Vector.minus(T.V1, T.V0);
    v = Vector.minus(T.V2, T.V0);
    n = Vector.crossProduct(u, v); // cross product

    if (Arrays.equals(n, new float[] {0.0f, 0.0f, 0.0f})) { // triangle is degenerate
      return -1; // do not deal with this case
    }
    dir = Vector.minus(R.P1, R.P0); // ray direction vector
    w0 = Vector.minus(R.P0, T.V0);
    a = -Vector.dot(n, w0);
    b = Vector.dot(n, dir);
    if (Math.abs(b) < SMALL_NUM) { // ray is parallel to triangle plane
      if (a == 0) { // ray lies in triangle plane
        return 2;
      } else {
        return 0; // ray disjoint from plane
      }
    }

    // get intersect point of ray with triangle plane
    r = a / b;
    if (r < 0.0f) { // ray goes away from triangle
      return 0; // => no intersect
    }
    // for a segment, also test if (r > 1.0) => no intersect

    float[] tempI =
        Vector.addition(R.P0, Vector.scalarProduct(r, dir)); // intersect point of ray and a plane

    I[0] = tempI[0];
    I[1] = tempI[1];
    I[2] = tempI[2];

    // is I inside T?
    float uu, uv, vv, wu, wv, D;
    uu = Vector.dot(u, u);
    uv = Vector.dot(u, v);
    vv = Vector.dot(v, v);
    w = Vector.minus(I, T.V0);
    wu = Vector.dot(w, u);
    wv = Vector.dot(w, v);
    D = (uv * uv) - (uu * vv);

    // get and test parametric coords
    float s, t;
    s = ((uv * wv) - (vv * wu)) / D;
    if (s < 0.0f || s > 1.0f) // I is outside T
    return 0;
    t = (uv * wu - uu * wv) / D;
    if (t < 0.0f || (s + t) > 1.0f) // I is outside T
    return 0;

    return 1; // I is in T
  }
 public void testGetDistanceSquared() {
   Vector other = new RandomAccessSparseVector(test.size());
   other.set(1, -2);
   other.set(2, -5);
   other.set(3, -9);
   other.set(4, 1);
   double expected = test.minus(other).getLengthSquared();
   assertTrue(
       "a.getDistanceSquared(b) != a.minus(b).getLengthSquared",
       Math.abs(expected - test.getDistanceSquared(other)) < 10.0E-7);
 }