/**
   * 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;
  }
  public static Vector3f rotate(Vector3f v, Vector3f axis, float angle) {
    // Rotate the point (x,y,z) around the vector (u,v,w)
    // Function RotatePointAroundVector(x#,y#,z#,u#,v#,w#,a#)
    float ux = axis.x * v.x;
    float uy = axis.x * v.y;
    float uz = axis.x * v.z;
    float vx = axis.y * v.x;
    float vy = axis.y * v.y;
    float vz = axis.y * v.z;
    float wx = axis.z * v.x;
    float wy = axis.z * v.y;
    float wz = axis.z * v.z;
    float sa = (float) Math.sin(angle);
    float ca = (float) Math.cos(angle);
    float x =
        axis.x * (ux + vy + wz)
            + (v.x * (axis.y * axis.y + axis.z * axis.z) - axis.x * (vy + wz)) * ca
            + (-wy + vz) * sa;
    float y =
        axis.y * (ux + vy + wz)
            + (v.y * (axis.x * axis.x + axis.z * axis.z) - axis.y * (ux + wz)) * ca
            + (wx - uz) * sa;
    float z =
        axis.z * (ux + vy + wz)
            + (v.z * (axis.x * axis.x + axis.y * axis.y) - axis.z * (ux + vy)) * ca
            + (-vx + uy) * sa;

    return new Vector3f(x, y, z);
  }
Exemple #3
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);
  }
Exemple #4
0
 public void brighter() {
   float[] rgb = color.get().getRGBComponents(null);
   rgb[0] = (float) Math.min(rgb[0] + 0.1, 1.0);
   rgb[1] = (float) Math.min(rgb[1] + 0.1, 1.0);
   rgb[2] = (float) Math.min(rgb[2] + 0.1, 1.0);
   color = new Color3f(rgb);
   updateLight();
 }
Exemple #5
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());
  }
}
  /*
   * Modifies the rotation part of the transformation axis for
   * a Cn symmetric complex, so that the narrower end faces the
   * viewer, and the wider end faces away from the viewer. Example: 3LSV
   */
  private void calcZDirection() {
    calcBoundaries();

    // if the longer part of the structure faces towards the back (-z direction),
    // rotate around y-axis so the longer part faces the viewer (+z direction)
    if (Math.abs(minBoundary.z) > Math.abs(maxBoundary.z)) {
      Matrix4d rot = flipY();
      rot.mul(transformationMatrix);
      transformationMatrix.set(rot);
    }
  }
  public Region getTranslatedRegion(Vector3f trans) {
    RectangularBox newBox =
        new RectangularBox(
            this.getLowestXValue() + trans.x,
            this.getLowestYValue() + trans.y,
            this.getLowestZValue() + trans.z,
            Math.abs(this.parameterList[3].value),
            Math.abs(this.parameterList[4].value),
            Math.abs(this.parameterList[5].value));

    return newBox;
  }
  /** Move up/down a given distance. */
  public void translateUpDown(double d) {
    if (globe == null || d == 0) return;
    double hDist = d * Math.cos(Math.PI / 2. + ha);
    double vDist = d * Math.sin(Math.PI / 2. + ha);

    lla = globe.getEllipsoid().forwGeodesic(lat, lon, hDist, az, lla);
    lat = lla.lat;
    lon = lla.lon;
    az = Ellipsoid.adjlonPos(lla.az + Math.PI);
    hEllps += vDist;
    ele_changed = lat_changed = lon_changed = az_changed = true;
    h = Double.MAX_VALUE;
  }
  /**
   * 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);
  }
  public void translate(double d, double t_az, double t_ha, boolean correct_az) {
    if (globe == null || d == 0) return;
    double hDist = d * Math.cos(t_ha);
    double vDist = d * Math.sin(t_ha);

    lla = globe.getEllipsoid().forwGeodesic(lat, lon, hDist, t_az, lla);
    lat = lla.lat;
    lon = lla.lon;
    hEllps += vDist;
    if (correct_az) {
      az = Ellipsoid.adjlonPos(az + lla.az + Math.PI - t_az);
      az_changed = true;
    }
    ele_changed = lat_changed = lon_changed = true;
    h = Double.MAX_VALUE;
  }
Exemple #11
0
 protected void computeCircle() {
   Vector3d center = new Vector3d((Vector3d) get(0));
   Vector3d p2 = new Vector3d((Vector3d) get(1));
   p2.sub(center);
   double radius = p2.length();
   removeAllElements();
   double angle = 0;
   double incAngle = 2 * Math.PI / sides;
   for (int i = 0; i < sides; i++) {
     super.add(
         new Vector3d(
             center.x + radius * Math.cos(angle), center.y + radius * Math.sin(angle), 0));
     angle += incAngle;
   }
   super.add(new Vector3d(center.x + radius, center.y, 0));
 }
  public GlobeNavigator(GlobeElevationModel globe) {
    this.globe = globe;

    ha = Math.toRadians(-90);
    hEllps = 12000000;

    gui_updater.schedule(
        new TimerTask() {
          public void run() {
            if (ha_changed
                || az_changed
                || ele_changed
                || lon_changed
                || lat_changed
                || point_changed) {
              for (GlobeNavigatorUpdateListener l : navigatorUpdateListeners)
                l.updateNavigatorChanges(GlobeNavigator.this);
              ha_changed =
                  az_changed = ele_changed = lon_changed = lat_changed = point_changed = false;
            }
          }
        },
        0,
        200);
  }
  /**
   * Returns the default reference vector for the alignment of Cn structures
   *
   * @return
   */
  private Vector3d getReferenceAxisCylic() {
    // get principal axis vector that is perpendicular to the principal
    // rotation vector
    Vector3d vmin = null;
    double dotMin = 1.0;
    for (Vector3d v : principalAxesOfInertia) {
      if (Math.abs(principalRotationVector.dot(v)) < dotMin) {
        dotMin = Math.abs(principalRotationVector.dot(v));
        vmin = new Vector3d(v);
      }
    }
    if (principalRotationVector.dot(vmin) < 0) {
      vmin.negate();
    }

    return vmin;
  }
 // map num from [0, 1emax] to [0, 1]
 public static float exp(int num, int max) {
   int i = 0;
   float ratio = 0;
   for (; i <= max; i++) {
     ratio = (float) (num / Math.pow(10, i));
     if (ratio >= 0 && ratio < 10) break;
   }
   return (float) i / max + 1.0f / max * ratio / 10;
 }
Exemple #15
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));
    }
  }
 public void setPointer(double lon, double lat, double h, double dist) {
   if (lat != point_lat || lon != point_lon || h != point_h) {
     point_lat = lat;
     point_lon = lon;
     point_h = h;
     point_dist = Math.max(dist, 2);
     point_changed = true;
   }
 }
Exemple #17
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;
 }
Exemple #18
0
 public void actionPerformed(ActionEvent e) {
   // Invoked when an action occurs.
   if (e.getSource().equals(singleSizeUp)) {
     singleSize = singleSize * 2;
     singleSizeLabel.setText("Image height=" + singleSize);
   }
   if (e.getSource().equals(singleSizeDown)) {
     singleSize = Math.max(64, singleSize / 2);
     singleSizeLabel.setText("Image height=" + singleSize);
   }
   if (e.getSource().equals(seqSizeUp)) {
     seqSize = seqSize * 2;
     seqSizeLabel.setText("Image height=" + seqSize);
   }
   if (e.getSource().equals(seqSizeDown)) {
     seqSize = Math.max(64, seqSize / 2);
     seqSizeLabel.setText("Image height=" + seqSize);
   }
 }
 boolean transform(short mad, Atom atom, Vector3f vibrationVector) {
   float len = vibrationVector.length();
   // to have the vectors move when vibration is turned on
   if (Math.abs(len * vectorScale) < 0.01) return false;
   headScale = arrowHeadOffset;
   if (vectorScale < 0) headScale = -headScale;
   doShaft = (0.1 + Math.abs(headScale / len) < Math.abs(vectorScale));
   headOffsetVector.set(vibrationVector);
   headOffsetVector.scale(headScale / len);
   pointVectorEnd.scaleAdd(vectorScale, vibrationVector, atom);
   pointArrowHead.set(pointVectorEnd);
   pointArrowHead.add(headOffsetVector);
   screenArrowHead.set(viewer.transformPoint(pointArrowHead, vibrationVector));
   screenVectorEnd.set(viewer.transformPoint(pointVectorEnd, vibrationVector));
   diameter = (mad < 1 ? 1 : mad <= 20 ? mad : viewer.scaleToScreen(screenVectorEnd.z, mad));
   headWidthPixels = (int) (diameter * 2.0f);
   if (headWidthPixels < diameter + 2) headWidthPixels = diameter + 2;
   if (isGenerator) diameter = (mad < 1 ? 1 : mad); // may need tweaking
   return true;
 }
 /**
  * Create user interface
  *
  * @return
  */
 private void updateElevation() {
   double my_h = h;
   if (my_h == Double.MAX_VALUE)
     h = my_h = globe == null ? 0 : globe.getElevation(lon, lat) * globe.getElevationScale();
   if (Math.abs(hTerrain + my_h - hEllps) > 0.01) {
     hTerrain = hEllps - my_h;
     if (hTerrain < min_h) {
       hTerrain = min_h;
       hEllps = hTerrain + my_h;
     }
     ele_changed = true;
   }
 }
Exemple #21
0
  public void accumulateBilinear(double x, double y, double s)
        /* Bilinearly accumulates 's' to the four integer grid points surrounding
         *   the continuous coordinate (x, y). */
      {
    double xpf = Math.floor(x);
    int xi = (int) xpf;
    double xf = x - xpf;

    double ypf = Math.floor(y);
    int yi = (int) ypf;
    double yf = y - ypf;

    double b;
    b = (1.0 - xf) * (1.0 - yf);
    accumulate(xi, yi, s * b);
    b = xf * (1.0 - yf);
    accumulate(xi + 1, yi, s * b);
    b = (1.0 - xf) * yf;
    accumulate(xi, yi + 1, s * b);
    b = xf * yf;
    accumulate(xi + 1, yi + 1, s * b);
  }
Exemple #22
0
  public void interactionForce(Particle other) {
    // ok, now for the fun stuff...
    Vector3d posDif = new Vector3d();
    posDif.sub(x, other.x);

    Vector3d velDif = new Vector3d();
    velDif.sub(v, other.v);

    double d = posDif.length();
    double dSquared = d * d;

    int m = 6;
    int n = 5;
    double r0 = 2 * PARTICLE_RADIUS;
    double cr = r0;
    double cd = r0;
    double b1 = 1;
    double b2 = b1; // *Math.pow(r0, n-m);
    double sumR = 2 * PARTICLE_RADIUS;
    double sr = 250;
    double sd = 70;

    /*sr = dSquared/(cr*cr*(sumR)*(sumR));
    sd = dSquared/(cd*cd*(sumR)*(sumR));

    sr = Math.max(0, 1 - sr);
    sd = Math.max(0, 1 - sd);*/

    Vector3d f = new Vector3d();
    f.set(posDif);
    f.normalize();

    double sf =
        -sr * (b1 / Math.pow(d / r0, m) - b2 / Math.pow(d / r0, n))
            + sd * (velDif.dot(f) / (d / r0));
    f.scale(sf);
    other.f.add(f);
  }
Exemple #23
0
  public double getBilinear(double x, double y)
        /* Returns: the bilinearly-interpolated value of the continuous field
         *   at (x, y).
         * Requires: (x, y) is inside the domain of the field */
      {
    if (!inBounds(x, y))
      throw new RuntimeException(
          "ScalarImage.getBilinear: RuntimeException at (" + x + "," + y + ")");

    int xi, yi;
    double xf, yf;
    if (x == (double) (width - 1)) {
      xi = width - 2;
      xf = 1.0;
    } else {
      double xpf = Math.floor(x);
      xi = (int) xpf;
      xf = x - xpf;
    }
    if (y == (double) (height - 1)) {
      yi = height - 2;
      yf = 1.0;
    } else {
      double ypf = Math.floor(y);
      yi = (int) ypf;
      yf = y - ypf;
    }

    double b1 = get(xi, yi);
    double b2 = get(xi + 1, yi);
    double b3 = get(xi, yi + 1);
    double b4 = get(xi + 1, yi + 1);

    double bb1 = b1 + xf * (b2 - b1);
    double bb2 = b3 + xf * (b4 - b3);

    return bb1 + yf * (bb2 - bb1);
  }
  /**
   * This is a callback to be executed before resampleSingle is executed. The bilinear interpolation
   * coefficients are computed here and vary with the single, active slice. The offset into the
   * intermediate image is also computed since this also varies with the active slice. If encoding
   * of transparent data has occurred in the renderer constructor, then the current slice of the
   * encoding table is initialized for use by resampleSingle.
   */
  protected void beforeResampleSingle() {

    // compute the 0-direction index ranges and weighting factors
    float fMin = (m_afShear[0] * m_iSlice) + m_afOffset[0];
    m_afA[0] = fMin - (float) Math.floor(fMin);
    m_afB[0] = 1.0f - m_afA[0];

    int iMin0 = (int) Math.ceil(fMin);

    // compute the 0-direction index ranges and weighting factors
    fMin = (m_afShear[1] * m_iSlice) + m_afOffset[1];
    m_afA[1] = fMin - (float) Math.floor(fMin);
    m_afB[1] = 1.0f - m_afA[1];

    int iMin1 = (int) Math.ceil(fMin);

    // offset into intermediate image of rendered voxel data
    m_iInterOffset = iMin0 + (m_iInterBound * iMin1);

    if (m_bDoEncodeSkip) {
      m_aasSliceEncode = m_aaasVolumeEncode[m_iSlice];
    }
  }
Exemple #25
0
/**
 * Adjust the specified mins and maxs vectors so that they contain the specified point.
 * @param point Point being added
 * @param mins Min coordinates of the bounding box
 * @param maxs Max coordinates of the bounding box
 */
public static void addPointToBounds(Tuple3f point, Tuple3f mins, Tuple3f maxs) 
	{
	mins.x = Math.min(mins.x, point.x);
	mins.y = Math.min(mins.y, point.y);
	mins.z = Math.min(mins.z, point.z);
	
	maxs.x = Math.max(maxs.x, point.x);
	maxs.y = Math.max(maxs.y, point.y);
	maxs.z = Math.max(maxs.z, point.z);
	}
Exemple #26
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);
     }
 }
  /**
   * The top level rendering call. This function calls beforeResampleAll, resampleAll, and
   * mapIntermediateToFinal, all virtual functions that are implemented in derived classes.
   *
   * @param iDS The number of slices to increment during the resampling phase. The value should be
   *     one or larger. If one, all slices of the volume data are resampled. If two, only every
   *     other slice is resampled. An input larger than one is used to allow fast rendering during
   *     rotation of the volume data. Once the rotation terminates, a composite with input of one
   *     should be called.
   */
  public synchronized void composite(int iDS) {
    long startTime = 0, now = 0;
    double elapsedTime = 0d;

    // compute maximum component of the box direction vector
    float fMax = 0.0f;
    int i, iMax = -1;

    for (i = 0; i < 3; i++) {
      float fAbs = Math.abs(m_aafBox[2][i]);

      if (fAbs > fMax) {
        fMax = fAbs;
        iMax = i;
      }
    }

    startTime = System.currentTimeMillis();
    traceInit();

    // composite in the appropriate direction
    if (iMax == 0) {
      beforeResampleAll(1, 2, 0);
    } else if (iMax == 1) {
      beforeResampleAll(2, 0, 1);
    } else {
      beforeResampleAll(0, 1, 2);
    }

    resampleAll(iDS);
    mapIntermediateToFinal();
    now = System.currentTimeMillis();
    elapsedTime = (double) (now - startTime);

    if (elapsedTime <= 0) {
      elapsedTime = (double) 0.0;
    }

    Preferences.debug(
        "Shear elapse time = " + (double) (elapsedTime / 1000.0) + "\n"); // in seconds
  }
Exemple #28
0
    public void run() {
      adjustToScreenSize =
          (float)
              Math.min(
                  jframe.getWidth(),
                  jframe.getHeight()); // used here, since you can change the screen-Size

      Matrix4f newTranslation = new Matrix4f();
      newTranslation.setIdentity();

      Matrix4f oldcTranslation = new Matrix4f();
      oldcTranslation = camera.getCameraMatrix();

      // world z-Axis-turn
      if (mouseWorldTurn != null) {
        newTranslation.mul(mouseWorldTurn);
        mouseWorldTurn.setIdentity();
      }

      // camera x-Axis-turn
      if (mouseTurn != null) {
        newTranslation.mul(mouseTurn);
        mouseTurn.setIdentity();
      }

      // camera movement
      if (keyMove != null) {
        newTranslation.mul(keyMove);
        keyMove.setIdentity();
      }

      newTranslation.mul(oldcTranslation);

      camera.setCameraMatrix(newTranslation);
      // something still appears to be wrong while turning

      // Trigger redrawing of the render window
      renderPanel.getCanvas().repaint();
    }
 private Vector3d orthogonalize(Vector3d vector1, Vector3d vector2) {
   double dot = vector1.dot(vector2);
   Vector3d ref = new Vector3d(vector2);
   //		System.out.println("p.r: " + dot);
   //		System.out.println("Orig refVector: " + referenceVector);
   if (dot < 0) {
     vector2.negate();
   }
   if (Math.abs(dot) < 0.00001) {
     System.out.println("HelixAxisAligner: Warning: reference axis parallel");
   }
   vector2.cross(vector1, vector2);
   //		System.out.println("Intermed. refVector: " + vector2);
   vector2.normalize();
   //		referenceVector.cross(referenceVector, principalRotationVector);
   vector2.cross(vector1, vector2);
   vector2.normalize();
   if (ref.dot(vector2) < 0) {
     vector2.negate();
   }
   //		System.out.println("Mod. refVector: " + vector2);
   return vector2;
 }
Exemple #30
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"

    // ...
  }