package org.freehep.j3d; // Java3D import javax.media.j3d.Appearance; import javax.vecmath.Point3d; /** General PolyGone Segment. All angles are in degrees, all dimensions * are full dimensions (not half dimensions). * <img src="doc-files/PolyGoneSegment.gif"> * @version 1.1.0 * @author <a href="mailto:Julius.Hrivnac@cern.ch">J.Hrivnac</a> */ public class PolyGoneSegment extends Solid { // Constructors -------------------------------------------------------------- /** Create general polygone segment. * @param rmins array of tangent distances of inner surface * @param rmaxs array of tangent distances of outer surface * @param zs array of possitions of z-planes * @param phimin starting azimutal angle [deg] * @param phimax ending azimutal angle [deg] * @param sides number of sides * @param appearance object' Appearance * @preconditions phimin > 0 && phimin < 360 * @preconditions phimax > 0 && phimax < 360 * @preconditions phimin < phimax * @preconditions rmins.length >= zs.length * @preconditions rmaxs.length >= zs.length * @preconditions zs.length > 0 * @preconditions for (int i = 0; i < zs.length; i++) rmins[i] < rmaxs[i] * @preconditions sides > 2 */ public PolyGoneSegment(double[] rmins, double[] rmaxs, double[] zs, double phimin, double phimax, int sides, Appearance appearance) { construct(rmins, rmaxs, zs, phimin, phimax, sides, appearance); } // --------------------------------------------------------------------------- private void construct(double[] rmins, double[] rmaxs, double[] zs, double phimin, double phimax, int sides, Appearance appearance) { final double phimin0 = Math.toRadians(phimin); final double phimax0 = Math.toRadians(phimax); // Prepare points Point3d[][] inner = new Point3d[zs.length][sides + 1]; Point3d[][] outer = new Point3d[zs.length][sides + 1]; double phi; for (int j = 0; j < sides + 1; j++) { phi = 2 * j * Math.PI / sides; for (int i = 0; i < zs.length; i++) { outer[i][j] = new Point3d(rmaxs[i] * Math.cos(phi), rmaxs[i] * Math.sin(phi), zs[i]); inner[i][j] = new Point3d(rmins[i] * Math.cos(phi), rmins[i] * Math.sin(phi), zs[i]); } } // Find cutoff points final boolean cutoffMin = phimin > 0; final boolean cutoffMax = phimax < 360; final double delphi = 2 * Math.PI / sides; final int jmin = (int)(phimin0 / delphi); final int jmax = (int)(phimax0 / delphi); final double alphamin = delphi / 2 - (phimin0 - jmin * delphi); final double alphamax = delphi / 2 - (phimax0 - jmax * delphi); final double smin = Math.cos(delphi / 2) / Math.cos(alphamin); final double smax = Math.cos(delphi / 2) / Math.cos(alphamax); Point3d[] outermin = new Point3d[zs.length]; Point3d[] innermin = new Point3d[zs.length]; Point3d[] outermax = new Point3d[zs.length]; Point3d[] innermax = new Point3d[zs.length]; for (int i = 0; i < zs.length; i++) { outermin[i] = new Point3d(rmaxs[i] * smin * Math.cos(phimin0), rmaxs[i] * smin * Math.sin(phimin0), zs[i]); innermin[i] = new Point3d(rmins[i] * smin * Math.cos(phimin0), rmins[i] * smin * Math.sin(phimin0), zs[i]); outermax[i] = new Point3d(rmaxs[i] * smax * Math.cos(phimax0), rmaxs[i] * smax * Math.sin(phimax0), zs[i]); innermax[i] = new Point3d(rmins[i] * smax * Math.cos(phimax0), rmins[i] * smax * Math.sin(phimax0), zs[i]); } // Construct array Point3d[] coordinates0 = new Point3d[zs.length * sides * 10]; int j0; int k = 0; boolean skip; int jstart = jmin; if (cutoffMin) { jstart = jmin + 1; } for (int i = 0; i < zs.length; i++) { for (int j = jstart; j < jmax; j++) { skip = false; j0 = j + 1; // Front if (i == 0) { coordinates0[k + 3] = inner[i ][j ]; coordinates0[k + 2] = inner[i ][j0]; coordinates0[k + 1] = outer[i ][j0]; coordinates0[k ] = outer[i ][j ]; k += 4; } // Back if (i == zs.length - 1) { coordinates0[k ] = inner[i ][j ]; coordinates0[k + 1] = inner[i ][j0]; coordinates0[k + 2] = outer[i ][j0]; coordinates0[k + 3] = outer[i ][j ]; k += 4; } // Sides if (i > 0) { // Outer coordinates0[k ] = outer[i ][j ]; coordinates0[k + 1] = outer[i ][j0]; coordinates0[k + 2] = outer[i - 1][j0]; coordinates0[k + 3] = outer[i - 1][j ]; k += 4; // Inner coordinates0[k + 3] = inner[i ][j ]; coordinates0[k + 2] = inner[i ][j0]; coordinates0[k + 1] = inner[i - 1][j0]; coordinates0[k ] = inner[i - 1][j ]; k += 4; } } } if (cutoffMin) { // Front - phimin coordinates0[k ] = inner[ 0 ][jmin + 1]; coordinates0[k + 1] = innermin[0 ]; coordinates0[k + 2] = outermin[0 ]; coordinates0[k + 3] = outer[ 0 ][jmin + 1]; k += 4; // Back - phimin coordinates0[k + 3] = inner[ zs.length - 1][jmin + 1]; coordinates0[k + 2] = innermin[zs.length - 1]; coordinates0[k + 1] = outermin[zs.length - 1]; coordinates0[k ] = outer[ zs.length - 1][jmin + 1]; k += 4; } if (cutoffMax) { // Front - phimax coordinates0[k ] = innermax[0 ]; coordinates0[k + 1] = inner[ 0 ][jmax ]; coordinates0[k + 2] = outer[ 0 ][jmax ]; coordinates0[k + 3] = outermax[0 ]; k += 4; // Back - phimax coordinates0[k + 3] = innermax[zs.length - 1]; coordinates0[k + 2] = inner[ zs.length - 1][jmax ]; coordinates0[k + 1] = outer[ zs.length - 1][jmax ]; coordinates0[k ] = outermax[zs.length - 1]; k += 4; } // Sides for (int i = 1; i < zs.length; i++) { if (cutoffMin) { // Outer - phimin coordinates0[k + 3] = outer[ i ][jmin + 1]; coordinates0[k + 2] = outermin[i ]; coordinates0[k + 1] = outermin[i - 1]; coordinates0[k ] = outer[ i - 1][jmin + 1]; k += 4; // Inner - phimin coordinates0[k ] = inner[ i ][jmin + 1]; coordinates0[k + 1] = innermin[i ]; coordinates0[k + 2] = innermin[i - 1]; coordinates0[k + 3] = inner[ i - 1][jmin + 1]; k += 4; } if (cutoffMax) { // Outer - phimax coordinates0[k + 3] = outermax[i ]; coordinates0[k + 2] = outer[ i ][jmax ]; coordinates0[k + 1] = outer[ i - 1][jmax ]; coordinates0[k ] = outermax[i - 1]; k += 4; // Inner - phimax coordinates0[k ] = innermax[i ]; coordinates0[k + 1] = inner[ i ][jmax ]; coordinates0[k + 2] = inner[ i - 1][jmax ]; coordinates0[k + 3] = innermax[i - 1]; k += 4; } // Side - phimin coordinates0[k + 3] = outermin[i ]; coordinates0[k + 2] = innermin[i ]; coordinates0[k + 1] = innermin[i - 1]; coordinates0[k ] = outermin[i - 1]; k += 4; // Side - phimax coordinates0[k ] = outermax[i ]; coordinates0[k + 1] = innermax[i ]; coordinates0[k + 2] = innermax[i - 1]; coordinates0[k + 3] = outermax[i - 1]; k += 4; } // Create final array Point3d[] coordinates = new Point3d[k]; for (int i = 0; i < k; i++) { coordinates[i] = coordinates0[i]; } // Geometry addCoordinates(coordinates); // Appearance setAppearance(appearance); } }