Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Shapes/Shape.cpp

    r205d9b rc6f395  
    99#include "Shape_impl.hpp"
    1010
     11#include "Helpers/Assert.hpp"
     12
     13#include <string>
     14
     15using namespace std;
     16
    1117Shape::Shape(const Shape& src) :
    1218  impl(src.getImpl())
     
    1723bool Shape::isInside(const Vector &point) const{
    1824  return impl->isInside(point);
     25}
     26
     27bool Shape::isOnSurface(const Vector &point) const{
     28  return impl->isOnSurface(point);
     29}
     30
     31Vector Shape::getNormal(const Vector &point) const throw (NotOnSurfaceException){
     32  return impl->getNormal(point);
     33}
     34
     35LineSegmentSet Shape::getLineIntersections(const Line &line){
     36  return impl->getLineIntersections(line);
    1937}
    2038
     
    3048}
    3149
     50std::string Shape::toString() const{
     51  return impl->toString();
     52}
     53
    3254Shape::impl_ptr Shape::getImpl() const{
    3355  return impl;
     
    6587}
    6688
     89bool AndShape_impl::isOnSurface(const Vector &point){
     90  // check the number of surfaces that this point is on
     91  int surfaces =0;
     92  surfaces += lhs->isOnSurface(point);
     93  surfaces += rhs->isOnSurface(point);
     94
     95  switch(surfaces){
     96    case 0:
     97      return false;
     98      // no break necessary
     99    case 1:
     100      // if it is inside for the object where it does not lie on
     101      // the surface the whole point lies inside
     102      return (lhs->isOnSurface(point) && rhs->isInside(point)) ||
     103             (rhs->isOnSurface(point) && lhs->isInside(point));
     104      // no break necessary
     105    case 2:
     106      {
     107        // it lies on both Shapes... could be an edge or an inner point
     108        // test the direction of the normals
     109        Vector direction=lhs->getNormal(point)+rhs->getNormal(point);
     110        // if the directions are opposite we lie on the inside
     111        return !direction.IsZero();
     112      }
     113      // no break necessary
     114    default:
     115      // if this happens there is something wrong
     116      ASSERT(0,"Default case should have never been used");
     117  }
     118  return false; // never reached
     119}
     120
     121Vector AndShape_impl::getNormal(const Vector &point) throw (NotOnSurfaceException){
     122  Vector res;
     123  if(!isOnSurface(point)){
     124    throw NotOnSurfaceException(__FILE__,__LINE__);
     125  }
     126  res += lhs->isOnSurface(point)?lhs->getNormal(point):zeroVec;
     127  res += rhs->isOnSurface(point)?rhs->getNormal(point):zeroVec;
     128  res.Normalize();
     129  return res;
     130}
     131
     132LineSegmentSet AndShape_impl::getLineIntersections(const Line &line){
     133  return intersect(lhs->getLineIntersections(line),rhs->getLineIntersections(line));
     134}
     135
     136string AndShape_impl::toString(){
     137  return string("(") + lhs->toString() + string("&&") + rhs->toString() + string(")");
     138}
     139
    67140Shape operator&&(const Shape &lhs,const Shape &rhs){
    68141  Shape::impl_ptr newImpl = Shape::impl_ptr(new AndShape_impl(getShapeImpl(lhs),getShapeImpl(rhs)));
     
    82155}
    83156
     157bool OrShape_impl::isOnSurface(const Vector &point){
     158  // check the number of surfaces that this point is on
     159  int surfaces =0;
     160  surfaces += lhs->isOnSurface(point);
     161  surfaces += rhs->isOnSurface(point);
     162
     163  switch(surfaces){
     164    case 0:
     165      return false;
     166      // no break necessary
     167    case 1:
     168      // if it is inside for the object where it does not lie on
     169      // the surface the whole point lies inside
     170      return (lhs->isOnSurface(point) && !rhs->isInside(point)) ||
     171             (rhs->isOnSurface(point) && !lhs->isInside(point));
     172      // no break necessary
     173    case 2:
     174      {
     175        // it lies on both Shapes... could be an edge or an inner point
     176        // test the direction of the normals
     177        Vector direction=lhs->getNormal(point)+rhs->getNormal(point);
     178        // if the directions are opposite we lie on the inside
     179        return !direction.IsZero();
     180      }
     181      // no break necessary
     182    default:
     183      // if this happens there is something wrong
     184      ASSERT(0,"Default case should have never been used");
     185  }
     186  return false; // never reached
     187}
     188
     189Vector OrShape_impl::getNormal(const Vector &point) throw (NotOnSurfaceException){
     190  Vector res;
     191  if(!isOnSurface(point)){
     192    throw NotOnSurfaceException(__FILE__,__LINE__);
     193  }
     194  res += lhs->isOnSurface(point)?lhs->getNormal(point):zeroVec;
     195  res += rhs->isOnSurface(point)?rhs->getNormal(point):zeroVec;
     196  res.Normalize();
     197  return res;
     198}
     199
     200LineSegmentSet OrShape_impl::getLineIntersections(const Line &line){
     201  return merge(lhs->getLineIntersections(line),rhs->getLineIntersections(line));
     202}
     203
     204string OrShape_impl::toString(){
     205  return string("(") + lhs->toString() + string("||") + rhs->toString() + string(")");
     206}
     207
    84208Shape operator||(const Shape &lhs,const Shape &rhs){
    85209  Shape::impl_ptr newImpl = Shape::impl_ptr(new OrShape_impl(getShapeImpl(lhs),getShapeImpl(rhs)));
     
    99223}
    100224
     225bool NotShape_impl::isOnSurface(const Vector &point){
     226  return arg->isOnSurface(point);
     227}
     228
     229Vector NotShape_impl::getNormal(const Vector &point) throw(NotOnSurfaceException){
     230  return -1*arg->getNormal(point);
     231}
     232
     233LineSegmentSet NotShape_impl::getLineIntersections(const Line &line){
     234  return invert(arg->getLineIntersections(line));
     235}
     236
     237string NotShape_impl::toString(){
     238  return string("!") + arg->toString();
     239}
     240
    101241Shape operator!(const Shape &arg){
    102242  Shape::impl_ptr newImpl = Shape::impl_ptr(new NotShape_impl(getShapeImpl(arg)));
    103243  return Shape(newImpl);
    104244}
     245
     246/**************** global operations *********************************/
     247ostream &operator<<(ostream &ost,const Shape &shape){
     248  ost << shape.toString();
     249  return ost;
     250}
Note: See TracChangeset for help on using the changeset viewer.