Exemple #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);
  }
  /*
   * 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;
  }
  /**
   * 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;
  }
 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;
   }
 }
  public void rotateAroundPointer(double x_rot, double y_rot) {
    if (hTerrain < 0) hTerrain = 0;
    if (Math.abs(point_dist * Math.sin(x_rot)) > hTerrain / 10)
      x_rot = Math.asin(hTerrain / point_dist / 10) * (x_rot >= 0 ? 1 : -1);
    if (Math.abs(point_dist * Math.sin(y_rot)) > hTerrain / 10)
      y_rot = Math.asin(hTerrain / point_dist / 10) * (y_rot >= 0 ? 1 : -1);

    // translateSideway(dist*Math.sin(x_rot))
    double d_x = point_dist * Math.sin(x_rot);
    lla = globe.getEllipsoid().forwGeodesic(lat, lon, -d_x * Math.cos(ha), az + Math.PI / 2., lla);
    lat = lla.lat;
    lon = lla.lon;
    az = Ellipsoid.adjlonPos(lla.az + Math.PI / 2.);

    // translateUpDown(dist*Math.sin(y_rot));
    double d_y = point_dist * Math.sin(y_rot);
    hEllps += d_y * Math.sin(Math.PI / 2. + ha);
    lla = globe.getEllipsoid().forwGeodesic(lat, lon, d_y * Math.cos(Math.PI / 2. + ha), az, lla);
    lat = lla.lat;
    lon = lla.lon;
    az = Ellipsoid.adjlonPos(lla.az + Math.PI);

    // translateForward(dist*(1-Math.cos(x_rot))*(1-Math.cos(y_rot)));
    double d_xy = point_dist * (1 - Math.cos(x_rot)) * (1 - Math.cos(y_rot));
    hEllps += d_xy * Math.sin(ha);
    lla = globe.getEllipsoid().forwGeodesic(lat, lon, d_xy * Math.cos(ha), az, lla);
    lat = lla.lat;
    lon = lla.lon;
    az = Ellipsoid.adjlonPos(lla.az + Math.PI + x_rot);

    ha -= y_rot;
    if (ha > Math.PI / 2) ha = Math.PI / 2;
    if (ha < -Math.PI / 2) ha = -Math.PI / 2;
    ele_changed = lat_changed = lon_changed = az_changed = ha_changed = true;
    h = Double.MAX_VALUE;
  }
  /**
   * 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
  }
 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 #10
0
  private RayShapeIntersection calculateIntersection(Ray ray, Triangle triangle) {
    RayShapeIntersection intersection = new RayShapeIntersection();
    Vector3f u = new Vector3f();
    Vector3f v = new Vector3f();
    u.sub(triangle.mY, triangle.mX);
    v.sub(triangle.mZ, triangle.mX);

    Vector3f n = new Vector3f();
    n.cross(u, v);

    if (n.epsilonEquals(mZeroVector, mEpsilon)) {
      // Triangle is either a point or a line (degenerate)
      // Don't deal with this case
      return intersection;
    }

    Vector3f w0 = new Vector3f();
    w0.sub(ray.getOrigin(), triangle.mX);

    float a = -n.dot(w0);
    float b = n.dot(ray.getDirection());
    if (Math.abs(b) < mEpsilon) { // ray is parallel to triangle plane
      if (a == 0) {
        // ray lies in triangle plane
        return intersection;
      } else {
        // ray disjoint from plane
        return intersection;
      }
    }

    float r = a / b;
    if (r < 0.f) {
      // ray goes away from triangle
      return intersection;
    }

    intersection.hit = true;
    intersection.hitPoint = new Vector3f();
    intersection.hitPoint.scaleAdd(r, ray.getDirection(), ray.getOrigin());

    // Is intersection inside the triangle?
    Vector3f w = new Vector3f();
    w.sub(intersection.hitPoint, triangle.mX);
    float uu, uv, vv, wu, wv, D;
    uu = u.dot(u);
    uv = u.dot(v);
    vv = v.dot(v);
    wu = w.dot(u);
    wv = w.dot(v);
    D = uv * uv - uu * vv;

    // get and test parametric coordinates
    float s, t;
    s = (uv * wv - vv * wu) / D;
    if (s < 0.f || s > 1) {
      // I is outside T
      intersection.hit = false;
      intersection.hitPoint = null;
      return intersection;
    }

    t = (uv * wu - uu * wv) / D;
    if (t < 0.0 || (s + t) > 1.0) {
      // I is outside T
      intersection.hit = false;
      intersection.hitPoint = null;
      return intersection;
    }

    return intersection;
  }
  /**
   * Returns a transformation matrix that rotates refPoints to match coordPoints
   *
   * @param refPoints the points to be aligned
   * @param referenceVectors
   * @return
   */
  private Matrix4d alignAxes(Vector3d[] axisVectors, Vector3d[] referenceVectors) {
    Matrix4d m1 = new Matrix4d();
    AxisAngle4d a = new AxisAngle4d();
    Vector3d axis = new Vector3d();

    // calculate rotation matrix to rotate refPoints[0] into coordPoints[0]
    Vector3d v1 = new Vector3d(axisVectors[0]);
    Vector3d v2 = new Vector3d(referenceVectors[0]);
    double dot = v1.dot(v2);
    if (Math.abs(dot) < 0.999) {
      axis.cross(v1, v2);
      axis.normalize();
      a.set(axis, v1.angle(v2));
      m1.set(a);
      // make sure matrix element m33 is 1.0. It's 0 on Linux.
      m1.setElement(3, 3, 1.0);
    } else if (dot > 0) {
      // parallel axis, nothing to do -> identity matrix
      m1.setIdentity();
    } else if (dot < 0) {
      // anti-parallel axis, flip around x-axis
      m1.set(flipX());
    }

    // apply transformation matrix to all refPoints
    m1.transform(axisVectors[0]);
    m1.transform(axisVectors[1]);

    // calculate rotation matrix to rotate refPoints[1] into coordPoints[1]
    v1 = new Vector3d(axisVectors[1]);
    v2 = new Vector3d(referenceVectors[1]);
    Matrix4d m2 = new Matrix4d();
    dot = v1.dot(v2);
    if (Math.abs(dot) < 0.999) {
      axis.cross(v1, v2);
      axis.normalize();
      a.set(axis, v1.angle(v2));
      m2.set(a);
      // make sure matrix element m33 is 1.0. It's 0 on Linux.
      m2.setElement(3, 3, 1.0);
    } else if (dot > 0) {
      // parallel axis, nothing to do -> identity matrix
      m2.setIdentity();
    } else if (dot < 0) {
      // anti-parallel axis, flip around z-axis
      m2.set(flipZ());
    }

    // apply transformation matrix to all refPoints
    m2.transform(axisVectors[0]);
    m2.transform(axisVectors[1]);

    // combine the two rotation matrices
    m2.mul(m1);

    // the RMSD should be close to zero
    Point3d[] axes = new Point3d[2];
    axes[0] = new Point3d(axisVectors[0]);
    axes[1] = new Point3d(axisVectors[1]);
    Point3d[] ref = new Point3d[2];
    ref[0] = new Point3d(referenceVectors[0]);
    ref[1] = new Point3d(referenceVectors[1]);
    if (SuperPosition.rmsd(axes, ref) > 0.1) {
      System.out.println(
          "Warning: AxisTransformation: axes alignment is off. RMSD: "
              + SuperPosition.rmsd(axes, ref));
    }

    return m2;
  }
Exemple #12
0
  public void analyze(boolean doit) {

    float min = Float.POSITIVE_INFINITY;
    float max = Float.NEGATIVE_INFINITY;
    for (int k = 0; k < size; k++) {
      //    	System.out.println(f[k]);
      /*
       * if (f[k] == Float.NaN) { System.out.println("NaN at k= "+k);
       * f[k] = 0f; }
       */
      if (Float.isNaN(f[k])) {
        System.out.println("NaN at k= " + k);
        f[k] = 0f;
        continue;
      }
      if (Float.isInfinite(f[k])) {
        if (f[k] < 0) {
          System.out.println("-Infinity at k= " + k);
          f[k] = 0f; // -1000f;
        } else {
          System.out.println("+Infinity at k= " + k);
          f[k] = 0f; // +1000f;
        }
        continue;
      }
      // System.out.print(k +"="+f[k]+ ", ");
      min = Math.min(min, f[k]);
      max = Math.max(max, f[k]);
    }

    int N = 256;
    float[] histogram = new float[N];

    for (int k = 0; k < size; k++) {
      int level = (int) (0.999f * (float) N * (f[k] - min) / (max - min));
      try {
        histogram[level]++;
      } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println("ArrayIndexOutOfBoundsException in ScalarImage.analyze(double) [A].");
      }
    }

    float[] cumulative = new float[N];
    if (histogram[0] > 0) {
      if (doit) {
        cumulative[0] = histogram[0];
      } else {
        cumulative[0] = 1; // histogram[0];
      }
    }
    for (int i = 1; i < N; i++) {
      if (histogram[i] > 0) {
        if (doit) {
          cumulative[i] = cumulative[i - 1] + histogram[i];
        } else {
          cumulative[i] = cumulative[i - 1] + 1; // histogram[i];
        }
      } else {
        cumulative[i] = cumulative[i - 1];
      }
    }

    /*		for(int k=0; k<size; k++) {
    			int level = (int) ( 0.999f*(float)N*(f[k]-min)/(max-min) );
    			try {
    				f[k]=(cumulative[level]-cumulative[0])/(cumulative[N-1]-cumulative[0]);
    			} catch( ArrayIndexOutOfBoundsException e) {
    				System.out.println("ArrayIndexOutOfBoundsException in ScalarImage.analyze(double) [B].");
    			}
    		}
    */
    for (int k = 0; k < size; k++) {
      float x, x1, x2, f1, f2;
      try {
        x = Math.abs((f[k] - min) / (max - min));
        x1 = (float) Math.floor((float) (N - 1) * x * 0.999f) / (float) (N - 1);
        x2 = (float) Math.ceil((float) (N - 1) * x * 0.999f) / (float) (N - 1);
        f1 =
            (cumulative[(int) Math.floor((float) (N - 1) * x * 0.999f)] - cumulative[0])
                / (cumulative[N - 1] - cumulative[0]);
        f2 =
            (cumulative[(int) Math.ceil((float) (N - 1) * x * 0.999f)] - cumulative[0])
                / (cumulative[N - 1] - cumulative[0]);
        f[k] = (f2 - f1) * (x - x1) / (x2 - x1) + f1;
      } catch (ArrayIndexOutOfBoundsException e) {
        System.out.println(
            "ArrayIndexOutOfBoundsException in ScalarImage.analyze(double) [C]. " + e.getMessage());
      }
    }

    return;

    /*
    		double offset = 0. - min;
    		if ((max - min) != 0f) {
    			scale /= (max - min);
    			offset *= scale;
    			rescale(scale, offset);
    		}
    		System.out.println("Normalizing using: min= " + min + " max= " + max
    				+ ", through scaleAdd(" + scale + ", " + offset + ").");
    		min = 1000f;
    		max = -1000f;
    		for (int k = 0; k < size; k++) {
    			if (Float.isNaN(f[k])) {
    				System.out.println("NaN at k= " + k + " after normalization.");
    				f[k] = 0f;
    				continue;
    			}
    			min = Math.min(min, f[k]);
    			max = Math.max(max, f[k]);
    		}
    		System.out.println("After normalization: min= " + min + " max= " + max);
    */
  }