package edu.stanford.rsl.conrad.geometry.shapes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import edu.stanford.rsl.conrad.geometry.AbstractCurve;
import edu.stanford.rsl.conrad.geometry.AbstractShape;
import edu.stanford.rsl.conrad.geometry.Axis;
import edu.stanford.rsl.conrad.geometry.bounds.AbstractBoundingCondition;
import edu.stanford.rsl.conrad.geometry.shapes.simple.PointND;
import edu.stanford.rsl.conrad.geometry.shapes.simple.SimpleSurface;
import edu.stanford.rsl.conrad.geometry.transforms.Transform;
/**
* Models an arbitrary shape centered at the origin using a base shape and bounding conditions
* An affine transform class is used to translate and orient shapes from object space in world space
* The affine transform of an arbitrary shape is always the same as that of its base shape;
*
* @author Rotimi X Ojo
*/
public class ArbitrarySurface extends SimpleSurface {
private static final long serialVersionUID = -3286378502393392770L;
private ArrayList<AbstractBoundingCondition> boundingClips = new ArrayList<AbstractBoundingCondition>();
private SimpleSurface baseSurface;
public ArbitrarySurface(SimpleSurface baseSurface,Collection<? extends AbstractBoundingCondition> clipSurfaces){
this.baseSurface = baseSurface;
this.boundingClips.addAll(boundingClips);
transform = baseSurface.getTransform();
}
public ArbitrarySurface(ArbitrarySurface surf) {
super(surf);
// deep copy the bounding clips
if (surf.boundingClips != null){
Iterator<AbstractBoundingCondition> it = surf.boundingClips.iterator();
boundingClips = new ArrayList<AbstractBoundingCondition>();
while (it.hasNext()) {
AbstractBoundingCondition cond = it.next();
boundingClips.add((cond!=null) ? cond.clone() : null);
}
}
else {
boundingClips = null;
}
// deep copy the base surface
baseSurface = (surf.baseSurface!=null) ? (SimpleSurface) surf.baseSurface.clone() : null;
}
@Override
public boolean isMember(PointND hit, boolean pointTransformed) {
if(!baseSurface.isMember(hit, pointTransformed)){
return false;
}
Iterator<AbstractBoundingCondition> clips = boundingClips.iterator();
while(clips.hasNext()){
if(!clips.next().isSatisfiedBy(hit)){
return false;
}
}
return true;
}
public ArrayList<PointND> getHits(AbstractCurve other){
return baseSurface.intersect(other);
}
@Override
public boolean isBounded() {
return true;
}
@Override
public PointND evaluate(PointND u) {
return u;
}
@Override
public int getDimension() {
return baseSurface.getDimension();
}
@Override
public int getInternalDimension() {
return baseSurface.getInternalDimension();
}
@Override
public void applyTransform(Transform t) {
baseSurface.applyTransform(t);
transform = baseSurface.getTransform();
}
@Override
public PointND[] getRasterPoints(int number) {
return null;
}
@Override
public Axis getPrincipalAxis() {
return baseSurface.getPrincipalAxis();
}
@Override
public PointND evaluate(double u, double v) {
return baseSurface.evaluate(u, v);
}
@Override
public AbstractShape tessellate(double accuracy) {
// TODO Auto-generated method stub
return null;
}
@Override
public AbstractShape clone() {
return new ArbitrarySurface(this);
}
}
/*
* Copyright (C) 2010-2014 Andreas Maier, Rotimi X Ojo
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/