/** * 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); }
/** * 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); }
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(); }
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; }
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; }
/** * 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; } }
/** * 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; }
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; } }
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); }
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); }
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]; } }
/** * 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); }
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 }
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; }
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" // ... }