Shape.h

00001 // ----------------------------------------------------------------------------
00002 //
00003 // tagGame - Example code from the book:
00004 //
00005 //           Artficial Intelligence for Computer Games: An Introduction
00006 //           by John David Funge
00007 //
00008 //           www.ai4games.org
00009 //
00010 // Source code distributed under the Copyright (c) 2003-2007, John David Funge
00011 // Original author: John David Funge (www.jfunge.com)
00012 //
00013 // Licensed under the Academic Free License version 3.0 
00014 // (for details see LICENSE.txt in this directory).
00015 //
00016 // ----------------------------------------------------------------------------
00017 
00018 #ifndef TG_SHAPE_H
00019 #define TG_SHAPE_H
00020 
00021 #include "Util2D.h"
00022 
00023 namespace tagGame
00024 {
00025    class Circle;
00026    class Side;
00027    class Shape;
00028 
00029    typedef SharedPtr<Circle>::type CirclePtr;
00030    typedef SharedPtr<Side>::type SidePtr;
00031    typedef SharedPtr<Shape>::type ShapePtr;
00032 
00033    template<typename Function, typename Allocator = std::allocator<void> >
00034    class function;
00035 
00037    class Shape
00038    {
00039    public:
00040       inline Shape();
00041       inline virtual ~Shape();
00042 
00043       inline RealVec const& getPosition() const;
00044       inline void setPosition(RealVec const& position);
00045 
00046       inline RealVec const& getOrientation() const;
00047       inline void setOrientation(RealVec const& orientation);
00048 
00049       virtual std::ostream& output(std::ostream& out) const = 0;
00050 
00051       inline bool isTouching(Shape const& o) const;
00052 
00055       virtual RealVec nearestIntersection(RealVec const& p, RealVec const& v) const = 0;
00056 
00058       virtual RealVec normalTo(Shape const& o) const = 0;
00059       virtual RealVec normalTo(Circle const& c) const = 0;
00060 
00061       // Multiple dispatch is implemented using virtual functions
00062       // only, as described in "Item 31: Making functions virtual with
00063       // respect to more than one object" in "More Effective C++" by
00064       // Scott Meyers.  More sophisticated techniques are described in
00065       // the reference and also in the "Multimethods" chapter of
00066       // "Modern C++ Design" by Andrei Alexandrescu.
00067       virtual Real distanceTo(Shape const& o) const = 0;
00068       virtual Real distanceTo(Circle const& c) const = 0;
00069       virtual Real distanceTo(Side const& s) const = 0;
00070 
00071       inline Real distanceSquaredTo(Shape const& o) const;
00072 
00073    protected:
00074    private:
00075       RealVec position;
00076       RealVec orientation;
00077    };
00078 
00079    typedef std::vector<ShapePtr> ShapeList;
00080    typedef ShapeList::const_iterator ShapeIteratorConst;
00081    typedef ShapeList::iterator ShapeIterator;
00082 
00083    Shape::Shape() :
00084       position(Util2D::dim),
00085       orientation(Util2D::dim)
00086    {
00087       orientation[0] = 1;
00088    }
00089 
00090    Shape::~Shape()
00091    {
00092    }
00093 
00094    inline std::ostream& operator<<(std::ostream& out, Shape const& o)
00095    {
00096       return o.output(out);
00097    }
00098 
00099    RealVec const& Shape::getPosition() const
00100    {
00101       return position;
00102    }
00103 
00104    void Shape::setPosition(RealVec const& position)
00105    {
00106       this->position = position;
00107    }
00108 
00109    RealVec const& Shape::getOrientation() const
00110    {
00111       return orientation;
00112    }
00113 
00114    void Shape::setOrientation(RealVec const& orientation)
00115    {
00116       TG_ASSERT(MathUtil::isAlmostEq(1, orientation.length()));
00117 
00118       this->orientation = orientation;
00119    }
00120 
00121    bool Shape::isTouching(Shape const& o) const
00122    {
00123       return distanceTo(o) <= Real(0);
00124    }
00125 
00126    // TODO: re-implement distanceTo in terms of distanceSquaredTo (instead
00127    // of the other way around) so that
00128    // distanceSquaredTo avoids the square root and can be used whenever
00129    // possible in place of distanceTo.
00130    Real Shape::distanceSquaredTo(Shape const& o) const
00131    {
00132       Real const d(distanceTo(o));
00133 
00134       return d * d;
00135    }
00136 
00137 }
00138 
00139 #endif

Generated on Sat Mar 31 22:30:54 2007 for tagGame by  doxygen 1.5.1