package org.freehep.j3d; // Java3D import javax.media.j3d.Appearance; import javax.vecmath.Point3d; /** General Torus Segment. All angles are in degrees. * <img src="doc-files/TorusSegment.gif"> * @version 1.1.0 * @author <a href="mailto:Julius.Hrivnac@cern.ch">J.Hrivnac</a> */ public class TorusSegment extends Solid { // Constructors -------------------------------------------------------------- /** Create general torus segment. * @param rmin radius of inner torus' circle * @param rmax radous of outer torus' circle * @param rtor central radius * @param phimin starting azimutal angle [deg] * @param phimax ending azimutal angle [deg] * @param granularity number of segments of curves approximations * @param appearance object' Appearance * @preconditions phimin > 0 && phimin < 360 * @preconditions phimax > 0 && phimax < 360 * @preconditions phimin < phimax * @preconditions rmin < rmax * @preconditions rtor < rmax * @preconditions granularity > 1 */ public TorusSegment(double rmin, double rmax, double rtor, double phimin, double phimax, int granularity, Appearance appearance) { construct(rmin, rmax, rtor, phimin, phimax, granularity, appearance); } /** Create full torus. */ public TorusSegment(double r, double rtor, int granularity, Appearance appearance) { construct(r, r, rtor, 0, 360, granularity, appearance); } // --------------------------------------------------------------------------- private void construct(double rmin, double rmax, double rtor, double phimin, double phimax, int granularity, Appearance appearance) { final int count1 = 4 * granularity; int count2; if (phimin == 0 && phimax == 360) { count2 = 4 * granularity * granularity; } else { count2 = 4 * granularity * (granularity - 1); } final double phimin0 = Math.toRadians(phimin); final double phimax0 = Math.toRadians(phimax); Point3d[][] pmin = new Point3d[granularity][granularity]; Point3d[][] pmax = new Point3d[granularity][granularity]; Point3d[] outCoordinates = new Point3d[count2]; Point3d[] inCoordinates = new Point3d[count2]; Point3d[] topCoordinates = new Point3d[count1]; Point3d[] bottomCoordinates = new Point3d[count1]; // Prepare points double phi = phimin0; double psi; for (int i = 0; i < granularity; i++) { psi = 0; for (int j = 0; j < granularity; j++) { pmin[i][j] = new Point3d((rtor + rmin * Math.cos(psi)) * Math.cos(phi), (rtor + rmin * Math.cos(psi)) * Math.sin(phi), rmin * Math.sin(psi)); pmax[i][j] = new Point3d((rtor + rmax * Math.cos(psi)) * Math.cos(phi), (rtor + rmax * Math.cos(psi)) * Math.sin(phi), rmax * Math.sin(psi)); psi += 2 * Math.PI / granularity; } phi += (phimax0 - phimin0) / granularity; } // Construct tubes int k = 0; int i1; int j1; for (int i = 0; i < granularity; i++) { if (i != granularity - 1 || (phimin == 0 && phimax == 360)) { i1 = ((i == granularity - 1) ? 0 : (i + 1)); for (int j = 0; j < granularity; j++) { j1 = ((j == granularity - 1) ? 0 : (j + 1)); // Out outCoordinates [k ] = new Point3d(pmax[i ][j ]); outCoordinates [k + 1] = new Point3d(pmax[i1][j ]); outCoordinates [k + 2] = new Point3d(pmax[i1][j1]); outCoordinates [k + 3] = new Point3d(pmax[i ][j1]); // In if (rmin > 0) { inCoordinates [k + 3] = new Point3d(pmin[i ][j ]); inCoordinates [k + 2] = new Point3d(pmin[i1][j ]); inCoordinates [k + 1] = new Point3d(pmin[i1][j1]); inCoordinates [k ] = new Point3d(pmin[i ][j1]); } // k += 4; } } } // Construct sides if (phimin != 0 || phimax != 360) { k = 0; for (int j = 0; j < granularity; j++) { j1 = ((j == granularity - 1) ? 0 : (j + 1)); // Top topCoordinates [k ] = new Point3d(pmin[0 ][j ]); topCoordinates [k + 1] = new Point3d(pmax[0 ][j ]); topCoordinates [k + 2] = new Point3d(pmax[0 ][j1]); topCoordinates [k + 3] = new Point3d(pmin[0 ][j1]); // Bottom bottomCoordinates [k + 3] = new Point3d(pmin[granularity - 1][j ]); bottomCoordinates [k + 2] = new Point3d(pmax[granularity - 1][j ]); bottomCoordinates [k + 1] = new Point3d(pmax[granularity - 1][j1]); bottomCoordinates [k ] = new Point3d(pmin[granularity - 1][j1]); // k += 4; } } // Geometries addCoordinates(outCoordinates); if (rmin > 0) { addCoordinates(inCoordinates); } if (phimin != 0 || phimax != 360) { addCoordinates(topCoordinates); addCoordinates(bottomCoordinates); } // Appearance setAppearance(appearance); } }