Example #1
0
  /**
   * Input W must be initialized to a nonzero vector, output is {U,V,W}, an orthonormal basis. A
   * hint is provided about whether or not W is already unit length.
   *
   * @param kU DOCUMENT ME!
   * @param kV DOCUMENT ME!
   * @param kW DOCUMENT ME!
   * @param bUnitLengthW DOCUMENT ME!
   */
  static void generateOrthonormalBasis(
      MjVector3f kU, MjVector3f kV, MjVector3f kW, boolean bUnitLengthW) {

    if (!bUnitLengthW) {
      kW.normalizeSafe();
    }

    float fInvLength;

    if (Math.abs(kW.x) >= Math.abs(kW.y)) {

      // W.x or W.z is the largest magnitude component, swap them
      fInvLength = 1.0f / (float) Math.sqrt((kW.x * kW.x) + (kW.z * kW.z));
      kU.x = -kW.z * fInvLength;
      kU.y = 0.0f;
      kU.z = +kW.x * fInvLength;
    } else {

      // W.y or W.z is the largest magnitude component, swap them
      fInvLength = 1.0f / (float) Math.sqrt((kW.y * kW.y) + (kW.z * kW.z));
      kU.x = 0.0f;
      kU.y = +kW.z * fInvLength;
      kU.z = -kW.y * fInvLength;
    }

    kV.cross(kW, kU);
  }
Example #2
0
public class Tetrahedron extends Shape3D {
  private static final float sqrt3 = (float) Math.sqrt(3.0);
  private static final float sqrt3_3 = sqrt3 / 3.0f;
  private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f;

  private static final float ycenter = 0.5f * sqrt24_3;
  private static final float zcenter = -sqrt3_3;

  private static final Point3f p1 = new Point3f(-1.0f, -ycenter, -zcenter);
  private static final Point3f p2 = new Point3f(1.0f, -ycenter, -zcenter);
  private static final Point3f p3 = new Point3f(0.0f, -ycenter, -sqrt3 - zcenter);
  private static final Point3f p4 = new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f);

  private static final Point3f[] verts = {
    p1, p2, p4, // front face
    p1, p4, p3, // left, back face
    p2, p3, p4, // right, back face
    p1, p3, p2, // bottom face
  };

  private Point2f texCoord[] = {
    new Point2f(0.0f, 0.0f), new Point2f(1.0f, 0.0f), new Point2f(0.5f, sqrt3 / 2.0f),
  };

  public Tetrahedron() {
    int i;

    TriangleArray tetra =
        new TriangleArray(
            12,
            TriangleArray.COORDINATES | TriangleArray.NORMALS | TriangleArray.TEXTURE_COORDINATE_2);

    tetra.setCoordinates(0, verts);
    for (i = 0; i < 12; i++) {
      tetra.setTextureCoordinate(i, texCoord[i % 3]);
    }

    int face;
    Vector3f normal = new Vector3f();
    Vector3f v1 = new Vector3f();
    Vector3f v2 = new Vector3f();
    Point3f[] pts = new Point3f[3];
    for (i = 0; i < 3; i++) pts[i] = new Point3f();

    for (face = 0; face < 4; face++) {
      tetra.getCoordinates(face * 3, pts);
      v1.sub(pts[1], pts[0]);
      v2.sub(pts[2], pts[0]);
      normal.cross(v1, v2);
      normal.normalize();
      for (i = 0; i < 3; i++) {
        tetra.setNormal((face * 3 + i), normal);
      }
    }
    this.setGeometry(tetra);
    this.setAppearance(new Appearance());
  }
}
  /**
   * Calculates the min and max boundaries of the structure after it has been transformed into its
   * canonical orientation.
   */
  private void calcBoundaries() {
    minBoundary.x = Double.MAX_VALUE;
    maxBoundary.x = Double.MIN_VALUE;
    minBoundary.y = Double.MAX_VALUE;
    maxBoundary.x = Double.MIN_VALUE;
    minBoundary.z = Double.MAX_VALUE;
    maxBoundary.z = Double.MIN_VALUE;
    xzRadiusMax = Double.MIN_VALUE;

    Point3d probe = new Point3d();

    for (Point3d[] list : subunits.getTraces()) {
      for (Point3d p : list) {
        probe.set(p);
        transformationMatrix.transform(probe);

        minBoundary.x = Math.min(minBoundary.x, probe.x);
        maxBoundary.x = Math.max(maxBoundary.x, probe.x);
        minBoundary.y = Math.min(minBoundary.y, probe.y);
        maxBoundary.y = Math.max(maxBoundary.y, probe.y);
        minBoundary.z = Math.min(minBoundary.z, probe.z);
        maxBoundary.z = Math.max(maxBoundary.z, probe.z);
        xzRadiusMax = Math.max(xzRadiusMax, Math.sqrt(probe.x * probe.x + probe.z * probe.z));
      }
    }
    //		System.out.println("MinBoundary: " + minBoundary);
    //		System.out.println("MaxBoundary: " + maxBoundary);
    //		System.out.println("zxRadius: " + xzRadiusMax);
  }
  /**
   * Return a midpoint of a helix, calculated from three positions of three adjacent subunit
   * centers.
   *
   * @param p1 center of first subunit
   * @param p2 center of second subunit
   * @param p3 center of third subunit
   * @return midpoint of helix
   */
  private Point3d getMidPoint(Point3d p1, Point3d p2, Point3d p3) {
    Vector3d v1 = new Vector3d();
    v1.sub(p1, p2);
    Vector3d v2 = new Vector3d();
    v2.sub(p3, p2);
    Vector3d v3 = new Vector3d();
    v3.add(v1);
    v3.add(v2);
    v3.normalize();

    // calculat the total distance between to subunits
    double dTotal = v1.length();
    // calculate the rise along the y-axis. The helix axis is aligned with y-axis,
    // therfore, the rise between subunits is the y-distance
    double rise = p2.y - p1.y;
    // use phythagorean theoremm to calculate chord length between two subunit centers
    double chord = Math.sqrt(dTotal * dTotal - rise * rise);
    //		System.out.println("Chord d: " + dTotal + " rise: " + rise + "chord: " + chord);
    double angle = helixLayers.getByLargestContacts().getAxisAngle().angle;

    // using the axis angle and the chord length, we can calculate the radius of the helix
    // http://en.wikipedia.org/wiki/Chord_%28geometry%29
    double radius = chord / Math.sin(angle / 2) / 2; // can this go to zero?
    //		System.out.println("Radius: " + radius);

    // project the radius onto the vector that points toward the helix axis
    v3.scale(radius);
    v3.add(p2);
    //		System.out.println("Angle: " +
    // Math.toDegrees(helixLayers.getByLowestAngle().getAxisAngle().angle));
    Point3d cor = new Point3d(v3);
    return cor;
  }
Example #5
0
  /**
   * Normalize this vector in place. If the vector is very close to zero length, then this vector is
   * stored as the zero vector.
   */
  void normalizeSafe() {
    float fLengthSquared = lengthSquared();

    if (0.0f == fLengthSquared) {
      set(ZERO);
    } else {
      scale(1.0f / (float) Math.sqrt(fLengthSquared));
    }
  }
Example #6
0
 /**
  * calculates z and adjusts for border conditions
  *
  * @param x
  * @param y
  * @return
  */
 private float calculateZ(float x, float y) {
   float z = 0;
   z = 1 - x * x - y * y;
   if (z > 0) {
     z = (float) Math.sqrt(z);
   } else {
     z = 0;
   }
   return z;
 }
Example #7
0
 public void vec2FieldMagnitude(Field field, AffineTransform ftoi) {
   AffineTransform itof = null;
   try {
     itof = ftoi.createInverse();
   } catch (NoninvertibleTransformException niv) {
     TDebug.println(0, "NoninvertibleTransformException: " + niv);
   }
   Vector3d v = new Vector3d();
   Point2D.Double p = new Point2D.Double();
   for (int j = 0, k = 0; j < height; ++j)
     for (int i = 0; i < width; ++i, ++k) {
       p.x = i;
       p.y = j;
       itof.transform(p, p);
       v = field.get(p.x, p.y, 0.0);
       f[k] = (float) Math.sqrt(v.x * v.x + v.y * v.y);
     }
 }
Example #8
0
  boolean intersect(Ray r, Hit h, Range range) {
    // ToDo:
    boolean retVal = false;
    double Aq = r.getDirection().dot(r.getDirection());
    double Bq =
        2
            * r.getDirection()
                .dot(
                    new Vector3d(
                        r.getOrigin().x - center.x,
                        r.getOrigin().y - center.y,
                        r.getOrigin().z - center.z));
    double Cq =
        (Math.pow(r.getOrigin().x - center.x, 2)
                + Math.pow(r.getOrigin().y - center.y, 2)
                + Math.pow(r.getOrigin().z - center.z, 2))
            - Math.pow(radius, 2);

    double discriminant = Math.pow(Bq, 2) - (4 * Aq * Cq);
    // Hay intersección, si se cumple esta condición... solo se ne
    // necesita el primer valor que es el de la primera intersección
    if (discriminant >= 0) {
      discriminant = Math.sqrt(discriminant);
      double firstT = (-Bq - discriminant) / (2 * Aq);
      if (firstT > range.minT && firstT < range.maxT) {
        h.setColor(this.color);
        range.maxT = firstT;
        h.setT(firstT);
        // se debe retornar T
      }
      retVal = true;
    }
    return retVal;

    // Compute the intersection of the ray with the
    // Sphere and update what needs to be updated
    // Valid values for t must be within the "range"

    // ...
  }