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;
	}
	
}
