/** * 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; }
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; }
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); */ }