package java3d;
public class BoundingSphere extends Bounds {
public Point3d center = new Point3d();
public double radius;
public BoundingSphere(Point3d center, double r) {
boundId = BOUNDING_SPHERE;
this.center = center;
this.radius = r;
}
public BoundingSphere() {
boundId = BOUNDING_SPHERE;
center.x = 0;
center.y = 0;
center.z = 0;
radius = 1;
}
public void combine(BoundingSphere bs) {
double r1 = this.radius;
double r2 = bs.radius;
Point3d c1 = new Point3d(center);
Point3d c2 = new Point3d(bs.center);
double d = center.distance(bs.center);
if (d + r2 <= r1) {
// this が bs を包含する場合、何もしない
} else if (d + r1 < r2) {
// bs が this を包含する場合、bsをコピー
this.radius = bs.radius;
this.center.set(bs.center);
} else {
// this と bs のいずれも他方を包含しない場合
this.radius = (r1 + r2 + d) / 2.0;
double a1 = this.radius - r1;
double a2 = this.radius - r2;
c1.scale(a2);
c2.scale(a1);
c1.add(c2);
c1.scale(1 / d);
center.set(c1);
}
}
public void transform(Transform3D trans) {
Vector4d v = new Vector4d(center.x, center.y, center.z, 1.0);
trans.transform(v);
center.set(v.x, v.y, v.z);
double max = 0.0;
for(int i = 0; i < trans.scales.length; i++) {
if (max < trans.scales[i]) {
max = trans.scales[i];
}
}
radius *= max;
}
@Override
public Object clone() {
return new BoundingSphere(new Point3d(this.center), this.radius);
}
@Override
public void combine(Bounds boundsObject) {
if( boundsObject instanceof BoundingSphere) {
combine((BoundingSphere) boundsObject);
}
}
@Override
public boolean intersect(Bounds boundsObject) {
if (boundsObject instanceof BoundingSphere) {
BoundingSphere bs = (BoundingSphere) boundsObject;
double r = this.radius + bs.radius;
double x = center.x - bs.center.x;
double y = center.y - bs.center.y;
double z = center.z - bs.center.z;
double d = x * x + y * y + z * z;
if (d <= r * r) {
return true;
}
}
return false;
}
}