/** @file ConvexPolyhedron.h @maintainer Morgan McGuire, http://graphics.cs.williams.edu @created 2001-11-11 @edited 2006-04-10 Copyright 2000-2006, Morgan McGuire. All rights reserved. */ #ifndef G3D_CONVEXPOLYHEDRON_H #define G3D_CONVEXPOLYHEDRON_H #include "G3D/platform.h" #include "G3D/Vector3.h" #include "G3D/Vector2.h" #include "G3D/CoordinateFrame.h" #include "G3D/Plane.h" #include "G3D/Line.h" #include "G3D/Array.h" namespace G3D { class DirectedEdge { public: Vector3 start; Vector3 stop; }; class ConvexPolygon { private: friend class ConvexPolyhedron; Array _vertex; public: ConvexPolygon() {} ConvexPolygon(const Vector3& v0, const Vector3& v1, const Vector3& v2); ConvexPolygon(const Array& __vertex); virtual ~ConvexPolygon() {} /** Counter clockwise winding order. */ inline const Vector3& vertex(int i) const { return _vertex[i]; } inline void setVertex(int i, const Vector3& v) { _vertex[i] = v; } /** Zero vertices indicates an empty polygon (zero area). */ inline int numVertices() const { return _vertex.size(); } inline void setNumVertices(int n) { _vertex.resize(n); } /** O(n) in the number of edges */ bool isEmpty() const; /** Cuts the polygon at the plane. If the polygon is entirely above or below the plane, one of the returned polygons will be empty. @param above The part of the polygon above (on the side the normal points to or in the plane) the plane @param below The part of the polygon below the plane. @param newEdge If a new edge was introduced, this is that edge (on the above portion; the below portion is the opposite winding. */ void cut(const Plane& plane, ConvexPolygon &above, ConvexPolygon &below, DirectedEdge& newEdge); void cut(const Plane& plane, ConvexPolygon &above, ConvexPolygon &below); /** When a cut plane grazes a vertex in the polygon, two near-identical vertices may be created. The closeness of these two points can cause a number of problems, such as ConvexPolygon::normal() returning an infinite vector. It should be noted, however, that not all applications are sensitive to near-identical vertices. removeDuplicateVertices() detects and eliminates redundant vertices. */ void removeDuplicateVertices(); /** O(n) in the number of edges */ float getArea() const; inline Vector3 normal() const { debugAssert(_vertex.length() >= 3); return (_vertex[1] - _vertex[0]).cross(_vertex[2] - _vertex[0]).direction(); } /** Returns the same polygon with inverse winding. */ ConvexPolygon inverse() const; }; class ConvexPolyhedron { public: /** Zero faces indicates an empty polyhedron */ Array face; ConvexPolyhedron() {} ConvexPolyhedron(const Array& _face); /** O(n) in the number of edges */ bool isEmpty() const; /** O(n) in the number of edges */ float getVolume() const; /** Cuts the polyhedron at the plane. If the polyhedron is entirely above or below the plane, one of the returned polyhedra will be empty. @param above The part of the polyhedron above (on the side the normal points to or in the plane) the plane @param below The part of the polyhedron below the plane. */ void cut(const Plane& plane, ConvexPolyhedron &above, ConvexPolyhedron &below); }; /** */ class ConvexPolygon2D { private: Array m_vertex; public: ConvexPolygon2D() {} /** Points are counter-clockwise in a Y = down, X = right coordinate system. @param reverse If true, the points are reversed (i.e. winding direction is changed) before the polygon is created. */ ConvexPolygon2D(const Array& pts, bool reverse = false); inline int numVertices() const { return m_vertex.size(); } inline const Vector2& vertex(int index) const { debugAssert((index >= 0) && (index <= m_vertex.size())); return m_vertex[index]; } /** @param reverseWinding If true, the winding direction of the polygon is reversed for this test.*/ bool contains(const Vector2& p, bool reverseWinding = false) const; }; } // namespace #endif