Пример #1
0
 public PointCloud3D addPoint(Vec3D p) {
   points.add(p);
   min.minSelf(p);
   max.maxSelf(p);
   centroid.set(min.add(max).scaleSelf(0.5f));
   radiusSquared = MathUtils.max(radiusSquared, p.distanceToSquared(centroid));
   return this;
 }
Пример #2
0
 /**
  * Recalculates the bounding box, bounding sphere and centroid of the cloud.
  *
  * @return itself
  */
 public PointCloud3D updateBounds() {
   min = Vec3D.MAX_VALUE.copy();
   max = Vec3D.NEG_MAX_VALUE.copy();
   for (Vec3D p : points) {
     min.minSelf(p);
     max.maxSelf(p);
   }
   centroid.set(min.add(max).scaleSelf(0.5f));
   radiusSquared = 0;
   for (ReadonlyVec3D p : points) {
     radiusSquared = MathUtils.max(radiusSquared, p.distanceToSquared(centroid));
   }
   return this;
 }
Пример #3
0
  @Override
  public Double intersect(Ray ray) {
    Vec3D o = worldToObject.multiplyPoint(ray.origin);
    o.setY(o.getY() + ymax + (ymin - ymax) * 0.5);
    Vec3D d = worldToObject.multiplyDirection(ray.direction);
    double sin2 = radius2 / (radius2 + height * height);
    double cos2 = 1 - sin2;
    double a = d.getX() * d.getX() * cos2 + d.getZ() * d.getZ() * cos2 - d.getY() * d.getY() * sin2;
    double b =
        2 * (o.getX() * d.getX() * cos2 + o.getZ() * d.getZ() * cos2 - o.getY() * d.getY() * sin2);
    double c = o.getX() * o.getX() * cos2 + o.getZ() * o.getZ() * cos2 - o.getY() * o.getY() * sin2;
    QuadraticRoots roots = Utils.solveQuadratic(a, b, c);
    boolean isect = false;
    double t0 = 0, t1 = 0, t = Double.POSITIVE_INFINITY;
    Vec3D n = new Vec3D();
    if (roots != null) {
      if (roots.x0 > roots.x1) {
        t0 = roots.x1;
        t1 = roots.x0;
      } else {
        t0 = roots.x0;
        t1 = roots.x1;
      }
      if (t0 < 0) {
        t0 = t1;
      }
      double y = o.getY() + t0 * d.getY();
      if (y > ymax || y < ymin) {
        t0 = t1;
        y = o.getY() + t0 * d.getY();
      }
      if (y >= ymin && y <= ymax && t0 >= 0) {
        isect = true;
        t = t0;
        Vec3D p = o.add(d.multiply(t0));
        Vec3D tangent = new Vec3D(0, 1, 0).crossProduct(new Vec3D(p.getX(), 0, p.getZ()));
        Vec3D bitangent = p.multiply(-1);
        n = objectToWorld.multiplyDirection(tangent.crossProduct(bitangent)).normalize();
      }
      t0 = (ymin - o.getY()) / d.getY();
      double xx = o.getX() + t0 * d.getX();
      double zz = o.getZ() + t0 * d.getZ();
      if (xx * xx + zz * zz <= radius2 && t0 < t && t0 >= 0) {
        isect = true;
        t = t0;
        n = objectToWorld.multiplyDirection(new Vec3D(0, -1, 0));
      }
      if (radius0 != 0) {
        t0 = (ymax - o.getY()) / d.getY();
        xx = o.getX() + t0 * d.getX();
        zz = o.getZ() + t0 * d.getZ();
        if (xx * xx + zz * zz <= radius0 * radius0 && t0 < t && t0 >= 0) {
          isect = true;
          t = t0;
          n = objectToWorld.multiplyDirection(new Vec3D(0, 1, 0));
        }
      }
    }
    if (isect) {
      normal = n;
      return t;
    }

    return null;
  }