/* * ShapeOps.cpp * * Created on: Jun 18, 2010 * Author: crueger */ #include "Shapes/ShapeOps.hpp" #include "Shapes/ShapeOps_impl.hpp" #include "Helpers/Assert.hpp" /*************** Base case ***********************/ ShapeOpsBase_impl::ShapeOpsBase_impl(const Shape::impl_ptr &_arg) : arg(_arg){} ShapeOpsBase_impl::~ShapeOpsBase_impl(){} bool ShapeOpsBase_impl::isInside(const Vector &point){ return arg->isInside(translateIn(point)); } bool ShapeOpsBase_impl::isOnSurface(const Vector &point){ return arg->isOnSurface(translateIn(point)); } Vector ShapeOpsBase_impl::getNormal(const Vector &point) throw (NotOnSurfaceException){ Vector helper = translateIn(point); if(!arg->isOnSurface(helper)){ throw NotOnSurfaceException(__FILE__,__LINE__); } return translateOutNormal(arg->getNormal(helper)); } Shape::impl_ptr ShapeOpsBase_impl::getArg(){ return arg; } /********************* Resize ********************/ Resize_impl::Resize_impl(const Shape::impl_ptr &_arg,double _size) : ShapeOpsBase_impl(_arg), size(_size) { ASSERT(size>0,"Cannot resize a Shape to size zero or below"); } Resize_impl::~Resize_impl(){} Vector Resize_impl::translateIn(const Vector& point){ return (1/size) * point; } Vector Resize_impl::translateOutPos(const Vector& point){ return size * point; } Vector Resize_impl::translateOutNormal(const Vector& point){ return point; } string Resize_impl::toString(){ stringstream sstr; sstr << "resize(" << getArg()->toString() << "," << size << ")"; return sstr.str(); } Shape resize(const Shape &arg,double size){ Shape::impl_ptr impl = Shape::impl_ptr(new Resize_impl(getShapeImpl(arg),size)); return Shape(impl); } /*************************** translate *******************/ Translate_impl::Translate_impl(const Shape::impl_ptr &_arg, const Vector &_offset) : ShapeOpsBase_impl(_arg),offset(_offset) {} Translate_impl::~Translate_impl(){} Vector Translate_impl::translateIn(const Vector& point){ return point-offset; } Vector Translate_impl::translateOutPos(const Vector& point){ return point+offset; } Vector Translate_impl::translateOutNormal(const Vector& point){ return point; } string Translate_impl::toString(){ stringstream sstr; sstr << "translate(" << getArg()->toString() << "," << offset << ")"; return sstr.str(); } Shape translate(const Shape &arg, const Vector &offset){ Shape::impl_ptr impl = Shape::impl_ptr(new Translate_impl(getShapeImpl(arg),offset)); return Shape(impl); } /*********************** stretch ******************/ Stretch_impl::Stretch_impl(const Shape::impl_ptr &_arg, const Vector &_factors) : ShapeOpsBase_impl(_arg),factors(_factors) { ASSERT(factors[0]>0,"cannot stretch a shape by a negative amount"); ASSERT(factors[1]>0,"cannot stretch a shape by a negative amount"); ASSERT(factors[2]>0,"cannot stretch a shape by a negative amount"); for(int i = NDIM;i--;){ reciFactors[i] = 1/factors[i]; } } Stretch_impl::~Stretch_impl(){} Vector Stretch_impl::translateIn(const Vector& point){ Vector helper=point; helper.ScaleAll(reciFactors); return helper; } Vector Stretch_impl::translateOutPos(const Vector& point){ Vector helper=point; helper.ScaleAll(factors); return helper; } Vector Stretch_impl::translateOutNormal(const Vector& point){ Vector helper=point; // the normalFactors are derived from appearances of the factors // with in the vectorproduct Vector normalFactors; normalFactors[0]=factors[1]*factors[2]; normalFactors[1]=factors[0]*factors[2]; normalFactors[2]=factors[0]*factors[1]; helper.ScaleAll(normalFactors); return helper; } string Stretch_impl::toString(){ stringstream sstr; sstr << "stretch(" << getArg()->toString() << "," << factors << ")"; return sstr.str(); } Shape stretch(const Shape &arg, const Vector &factors){ Shape::impl_ptr impl = Shape::impl_ptr(new Stretch_impl(getShapeImpl(arg),factors)); return Shape(impl); } /************************* transform *****************/ Transform_impl::Transform_impl(const Shape::impl_ptr &_arg, const Matrix &_transformation) : ShapeOpsBase_impl(_arg),transformation(_transformation) { transformationInv = transformation.invert(); } Transform_impl::~Transform_impl(){} Vector Transform_impl::translateIn(const Vector& point){ return transformationInv * point; } Vector Transform_impl::translateOutPos(const Vector& point){ return transformation * point; } Vector Transform_impl::translateOutNormal(const Vector& point){ Matrix mat = transformation.determinant() * transformation.invert().transpose(); return mat * point; } string Transform_impl::toString(){ stringstream sstr; sstr << "transform(" << getArg()->toString() << "," << transformation << ")"; return sstr.str(); } Shape transform(const Shape &arg, const Matrix &transformation){ Shape::impl_ptr impl = Shape::impl_ptr(new Transform_impl(getShapeImpl(arg),transformation)); return Shape(impl); }