public Point3d calcCenterOfRotation() { List<Integer> line = getLongestLayerLine(); // can't determine center of rotation if there are only 2 points // TODO does this ever happen?? if (line.size() < 3) { return subunits.getCentroid(); } Point3d centerOfRotation = new Point3d(); List<Point3d> centers = subunits.getOriginalCenters(); // calculate helix mid points for each set of 3 adjacent subunits for (int i = 0; i < line.size() - 2; i++) { Point3d p1 = new Point3d(centers.get(line.get(i))); Point3d p2 = new Point3d(centers.get(line.get(i + 1))); Point3d p3 = new Point3d(centers.get(line.get(i + 2))); transformationMatrix.transform(p1); transformationMatrix.transform(p2); transformationMatrix.transform(p3); centerOfRotation.add(getMidPoint(p1, p2, p3)); } // average over all midpoints to find best center of rotation centerOfRotation.scale(1 / (line.size() - 2)); // since helix is aligned along the y-axis, with an origin at y = 0, place the center of // rotation there centerOfRotation.y = 0; // transform center of rotation to the original coordinate frame reverseTransformationMatrix.transform(centerOfRotation); // System.out.println("center of rotation: " + centerOfRotation); return centerOfRotation; }
private double[] getSubunitZDepth() { int n = subunits.getSubunitCount(); double[] depth = new double[n]; Point3d probe = new Point3d(); // transform subunit centers into z-aligned position and calculate // z-coordinates (depth) along the z-axis. for (int i = 0; i < n; i++) { Point3d p = subunits.getCenters().get(i); probe.set(p); transformationMatrix.transform(probe); depth[i] = probe.z; } return depth; }
/** * 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); }
/** * Returns a list of list of subunit ids that form an "orbit", i.e. they are transformed into each * other during a rotation around the principal symmetry axis (z-axis) * * @return */ private List<List<Integer>> calcOrbits() { int n = subunits.getSubunitCount(); List<List<Integer>> orbits = new ArrayList<List<Integer>>(); for (int i = 0; i < n; i++) { orbits.add(Collections.singletonList(i)); } return orbits; }
private void calcPrincipalAxes() { MomentsOfInertia moi = new MomentsOfInertia(); for (Point3d[] list : subunits.getTraces()) { for (Point3d p : list) { moi.addPoint(p, 1.0); } } principalAxesOfInertia = moi.getPrincipalAxes(); }
public HelixAxisAligner(QuatSymmetryResults results) { this.subunits = results.getSubunits(); this.helixLayers = results.getHelixLayers(); if (subunits == null) { throw new IllegalArgumentException("HelixAxisTransformation: Subunits are null"); } else if (helixLayers == null) { throw new IllegalArgumentException("HelixAxisTransformation: HelixLayers is null"); } else if (subunits.getSubunitCount() == 0) { throw new IllegalArgumentException("HelixAxisTransformation: Subunits is empty"); } else if (helixLayers.size() == 0) { throw new IllegalArgumentException("HelixAxisTransformation: HelixLayers is empty"); } }
private void calcTransformationBySymmetryAxes() { Vector3d[] axisVectors = new Vector3d[2]; axisVectors[0] = new Vector3d(principalRotationVector); axisVectors[1] = new Vector3d(referenceVector); // y,z axis centered at the centroid of the subunits Vector3d[] referenceVectors = new Vector3d[2]; referenceVectors[0] = new Vector3d(Z_AXIS); referenceVectors[1] = new Vector3d(Y_AXIS); transformationMatrix = alignAxes(axisVectors, referenceVectors); // combine with translation Matrix4d combined = new Matrix4d(); combined.setIdentity(); Vector3d trans = new Vector3d(subunits.getCentroid()); trans.negate(); combined.setTranslation(trans); transformationMatrix.mul(combined); // for helical geometry, set a canonical view for the Z direction calcZDirection(); }
/* (non-Javadoc) * @see org.biojava.nbio.structure.quaternary.core.AxisAligner#getCentroid() */ @Override public Point3d getCentroid() { return new Point3d(subunits.getCentroid()); }