package org.freehep.j3d;
// Java3D
import javax.media.j3d.Appearance;
import javax.vecmath.Point3d;
/** General Sphere Segment. All angles are in degrees.
* <img src="doc-files/SphereSegment.gif">
* @version 1.1.0
* @author <a href="mailto:Julius.Hrivnac@cern.ch">J.Hrivnac</a> */
public class SphereSegment extends Solid {
// Constructors --------------------------------------------------------------
/** Create general sphere segment.
* @param rmin inner radius
* @param rmax outer radius
* @param phimin starting azimutal angle [deg]
* @param phimax ending azimutal angle [deg]
* @param thetamin starting polar angle [deg]
* @param thetamax ending polar 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 thetamin > 0 && thetamin < 360
* @preconditions thetamax > 0 && thetamax < 360
* @preconditions thetamin < thetamax
* @preconditions rmin < rmax
* @preconditions granularity > 1 */
public SphereSegment(double rmin,
double rmax,
double phimin,
double phimax,
double thetamin,
double thetamax,
int granularity,
Appearance appearance) {
construct(rmin,
rmax,
phimin,
phimax,
thetamin,
thetamax,
granularity,
appearance);
}
/** Create full sphere. */
public SphereSegment(double r,
int granularity,
Appearance appearance) {
construct(r,
0,
0,
360,
-90,
90,
granularity,
appearance);
}
// ---------------------------------------------------------------------------
private void construct(double rmin,
double rmax,
double phimin,
double phimax,
double thetamin,
double thetamax,
int granularity,
Appearance appearance) {
final int count1 = 4 * granularity;
final int count2 = 4 * granularity * granularity;
final double phimin0 = Math.toRadians(phimin);
final double phimax0 = Math.toRadians(phimax);
final double thetamin0 = Math.toRadians(thetamin);
final double thetamax0 = Math.toRadians(thetamax);
Point3d[][] pmin = new Point3d[granularity + 1][granularity + 1];
Point3d[][] pmax = new Point3d[granularity + 1][granularity + 1];
Point3d[] outCoordinates = new Point3d[count2];
Point3d[] inCoordinates = new Point3d[count2];
Point3d[] topCoordinates = new Point3d[count1];
Point3d[] bottomCoordinates = new Point3d[count1];
Point3d[] leftCoordinates = new Point3d[count1];
Point3d[] rightCoordinates = new Point3d[count1];
// Prepare points
double phi = phimin0;
double theta;
for (int i = 0; i < granularity + 1; i++) {
theta = thetamin0;
for (int j = 0; j < granularity + 1; j++) {
pmin[i][j] = new Point3d(rmin * Math.cos(theta) * Math.cos(phi),
rmin * Math.cos(theta) * Math.sin(phi),
rmin * Math.sin(theta));
pmax[i][j] = new Point3d(rmax * Math.cos(theta) * Math.cos(phi),
rmax * Math.cos(theta) * Math.sin(phi),
rmax * Math.sin(theta));
theta += (thetamax0 - thetamin0) / granularity;
}
phi += (phimax0 - phimin0) / granularity;
}
// Construct quatratic arrays
int k = 0;
for (int i = 0; i < granularity; i++) {
for (int j = 0; j < granularity; j++) {
// Out
outCoordinates [k ] = new Point3d(pmax[i ][j ]);
outCoordinates [k + 1] = new Point3d(pmax[i + 1][j ]);
outCoordinates [k + 2] = new Point3d(pmax[i + 1][j + 1]);
outCoordinates [k + 3] = new Point3d(pmax[i ][j + 1]);
// In
if (rmin > 0) {
inCoordinates [k + 3] = new Point3d(pmin[i ][j ]);
inCoordinates [k + 2] = new Point3d(pmin[i + 1][j ]);
inCoordinates [k + 1] = new Point3d(pmin[i + 1][j + 1]);
inCoordinates [k ] = new Point3d(pmin[i ][j + 1]);
}
//
k += 4;
}
}
// Construct linear arrays
k = 0;
for (int i = 0; i < granularity; i++) {
// Top
if (thetamax < 90) {
topCoordinates [k + 3] = new Point3d(pmax[i ][0]);
topCoordinates [k + 2] = new Point3d(pmax[i + 1][0]);
topCoordinates [k + 1] = new Point3d(pmin[i + 1][0]);
topCoordinates [k ] = new Point3d(pmin[i ][0]);
}
// Bottom
if (thetamin > -90) {
bottomCoordinates [k ] = new Point3d(pmax[i ][granularity]);
bottomCoordinates [k + 1] = new Point3d(pmax[i + 1][granularity]);
bottomCoordinates [k + 2] = new Point3d(pmin[i + 1][granularity]);
bottomCoordinates [k + 3] = new Point3d(pmin[i ][granularity]);
}
if (phimin > 0 || phimax < 360) {
// Left
leftCoordinates [k ] = new Point3d(pmax[0][i ]);
leftCoordinates [k + 1] = new Point3d(pmax[0][i + 1]);
leftCoordinates [k + 2] = new Point3d(pmin[0][i + 1]);
leftCoordinates [k + 3] = new Point3d(pmin[0][i ]);
// Right
rightCoordinates [k + 3] = new Point3d(pmax[granularity][i ]);
rightCoordinates [k + 2] = new Point3d(pmax[granularity][i + 1]);
rightCoordinates [k + 1] = new Point3d(pmin[granularity][i + 1]);
rightCoordinates [k ] = new Point3d(pmin[granularity][i ]);
}
//
k += 4;
}
// Geometries
addCoordinates(outCoordinates);
if (rmin > 0) {
addCoordinates(inCoordinates);
}
if (thetamax < 90) {
addCoordinates(topCoordinates);
}
if (thetamin > -90) {
addCoordinates(bottomCoordinates);
}
if (phimin > 0 || phimax < 360) {
addCoordinates(leftCoordinates);
addCoordinates(rightCoordinates);
}
// Appearance
setAppearance(appearance);
}
}