/* --------------------------------------------------------- *
* __________ D E L T A S C R I P T *
* (_________() *
* / === / - A fast, dynamic scripting language *
* | == | - Version 4.13.11.0 *
* / === / - Developed by Adam R. Nelson *
* | = = | - 2011-2013 *
* / === / - Distributed under GNU LGPL v3 *
* (________() - http://github.com/ar-nelson/deltascript *
* *
* --------------------------------------------------------- */
package com.sector91.delta.script.objects.geom;
import java.util.Arrays;
import com.sector91.delta.script.annotations.DSDynamicField;
import com.sector91.delta.script.annotations.DSInaccessible;
import com.sector91.delta.script.annotations.DSName;
import com.sector91.delta.script.annotations.DSType;
import com.sector91.delta.script.objects.DS_Object;
import com.sector91.delta.script.objects.DS_Vector;
import com.sector91.delta.script.objects.reflect.DS_JavaClass;
import com.sector91.geom.Box;
import com.sector91.geom.DimensionMismatchException;
import com.sector91.geom.Shape;
import com.sector91.geom.Vector;
import com.sector91.geom.algorithms.Algorithms;
@DSType("BoxND")
public class DS_BoxND extends DS_Box
{
public static final String TYPE_NAME = "BoxND";
private static final DS_JavaClass DSCLASS = DS_JavaClass.fromClass(
DS_BoxND.class);
private final DS_Vector origin, span;
@DSInaccessible
public DS_BoxND(DeltaScriptGeometry geom, DS_Vector origin, DS_Vector span)
{
super(geom);
DimensionMismatchException.check("Box", origin, span);
this.origin = origin;
this.span = span;
}
@DSName("dimensions") @DSDynamicField
public final int dimensions()
{return origin.dimensions();}
@DSName("origin") @DSDynamicField
@Override public final DS_Vector origin()
{return origin;}
@DSName("span") @DSDynamicField
@Override public final DS_Vector span()
{return span;}
@DSName("originAt")
public Box originAt(Vector newOrigin)
{return geom.box(newOrigin, span);}
@DSName("centeredAt")
public Box centeredAt(Vector newCenter)
{return geom.box(newCenter.sub(span.div(2)), span);}
@DSName("vertices") @DSDynamicField
public DS_Vector[] vertices()
{
// First, build a rectangle...
final DS_Vector[] rectPoints = new DS_Vector[] {
geom.vec(min(Vector.X), min(Vector.Y)),
geom.vec(max(Vector.X), min(Vector.Y)),
geom.vec(max(Vector.X), max(Vector.Y)),
geom.vec(min(Vector.X), max(Vector.Y))
};
// ...then, recursively duplicate it in each extra dimension necessary.
if (dimensions() > 2) return projectVertices(rectPoints, 2);
else return rectPoints;
}
private DS_Vector[] projectVertices(DS_Vector[] points, int nextD)
{
final DS_Vector[] newPoints = new DS_Vector[points.length*2];
for (int i=0; i<newPoints.length; i+=2)
{
final float[]
oldVec = points[i/2].toArray(),
newVec1 = new float[oldVec.length+1],
newVec2 = new float[oldVec.length+1];
System.arraycopy(oldVec, 0, newVec1, 0, oldVec.length);
System.arraycopy(oldVec, 0, newVec2, 0, oldVec.length);
newVec1[oldVec.length] = min(nextD);
newVec2[oldVec.length] = max(nextD);
newPoints[i] = geom.vec(newVec1);
newPoints[i+1] = geom.vec(newVec2);
}
if (nextD+1 < dimensions()) return projectVertices(newPoints, nextD+1);
else return newPoints;
}
@DSName("intersects")
public boolean intersects(Box other)
{return Algorithms.testBoxIntersection(this, other);}
@DSName("contains")
@Override public boolean contains(Box other)
{return Algorithms.testBoxContains(this, other);}
@DSName("congruentTo")
public boolean congruentTo(Shape other)
{
return (other.dimensions() == dimensions() &&
other.curved() == false &&
Arrays.equals(other.vertices(), vertices()));
}
@DSName("transform")
public Shape transform(Vector matrix)
{
throw new UnsupportedOperationException("Transformation of solid" +
" shapes in more than two dimensions is not yet implemented.");
}
@Override public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + origin.hashCode();
result = prime * result + span.hashCode();
return result;
}
public boolean equals(DS_Object obj)
{
if (this == obj) return true;
if (getClass() != obj.getClass()) return false;
DS_BoxND other = (DS_BoxND)obj;
return origin.equals(other.origin) && span.equals(other.span);
}
public String getTypeName()
{return TYPE_NAME;}
@Override protected DS_JavaClass getDeltaScriptClass()
{return DSCLASS;}
}