prism.h

Go to the documentation of this file.
00001 /*
00002  * prism.h
00003  *
00004  * Copyright (C) 2010  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  *
00031  * 3D Prisms
00032  */
00033 
00034 #ifndef WAVEPACKET_PRISM_H__
00035 #define WAVEPACKET_PRISM_H__
00036 
00037 // includes --------------------------------------------------------------------
00038 #include "geometry_3d.h"
00039 #include "matrix_4.h"
00040 
00041 
00042 /// \ingroup geometry
00043 /*@{*/
00044 
00045 
00046 /// a prism is a 3D object, basically a polygon in some plane with some
00047 ///     extent in the plane normal direction.  See wikipedia for the general
00048 ///     definition: http://en.wikipedia.org/wiki/Prism_(geometry)
00049 ///     In particular, this is a \b right prism.
00050 /// This class (prism_base_t) is templated, so that the client can decide the
00051 ///     max size of the vertex array.  Given a polygonal base of N points, you
00052 ///     will need 2N vertices.
00053 /// The array of points has a specific convention:
00054 ///     point[2 * i] is the vertex on the "floor" (y = 0)
00055 ///     point[(2 * i) + 1] is the vertex on the ceiling (y = height above the
00056 ///             point[2 * i] vertex)
00057 /// So for instance, any consecutive sequence of 4 points starting with even
00058 ///     index is guaranteed to be a planar rectangle.  This is a very helpful
00059 ///     property of prisms.
00060 /// \b WARNING: the xz-plane, y-extent convention is recommended for basic
00061 ///     prisms.  However, prisms can be transformed by arbitrary 3D
00062 ///     transformations (see matrix4_t).  So you can't assume that an
00063 ///     odd-indexed point is only translated in the y-direction from its
00064 ///     even-indexed base, for instance.  However, consecutive sequences of 4
00065 ///     points starting with even index will always be a planar rectangle, even
00066 ///     when transformed.
00067 template <class Size>
00068 struct prism_base_t {
00069         // constructor, manipulators
00070         prism_base_t(void) throw() { this->clear(); }
00071         void clear(void) throw() {
00072                         nVertices = 0;
00073                 }
00074         bool isValid(void) const throw() {
00075                         return (nVertices > 2) &&
00076                                (2 * nVertices < Size::eMaxCount);
00077                 }
00078         void setVertexCount(IN int N) {
00079                         ASSERT_THROW(N > 5 &&           // at least 3-sided
00080                                      (0 == (N % 2)) &&  // must be even
00081                                      N <= Size::eMaxCount,
00082                             "Invalid prism vertex count: " << N);
00083                         nVertices = N;
00084                 }
00085 
00086         // data fields
00087         point3d_t               points[Size::eMaxCount];
00088         int                     nVertices;
00089 };
00090 
00091 
00092 
00093 class DefaultSize {
00094 public:
00095         enum eConstants {
00096                 eMaxCount               = 16
00097         };
00098 };
00099 
00100 
00101 
00102 /// a default prism class, supporting up to 16 points (supports prisms based
00103 ///     on polygons up to 8 sides).
00104 typedef prism_base_t<DefaultSize> prism_t;
00105 
00106 
00107 
00108 /// creates a 3D prism whose base is a regular N-polygon, with specified radius
00109 ///     and height.  Caller must provide an array big enough to hold 2*nSides
00110 ///     points.  That array is populated on output.  The polygons are in the
00111 ///     xz plane, separated by distance height in the y direction.
00112 void createRegularPrism(IN int nSides,
00113                         IN float radius,
00114                         IN float height,
00115                         IO point3d_t * points);
00116 
00117 
00118 
00119 /// helper method to create a regular prism
00120 template <class Size>
00121 void createRegularPrism
00122 (
00123 IN int nSides,
00124 IN float radius,
00125 IN float height,
00126 OUT prism_base_t<Size>& prism
00127 )
00128 {
00129         prism.setVertexCount(2 * nSides);
00130         createRegularPrism(nSides, radius, height, prism.points);
00131 }
00132 
00133 
00134 
00135 /// transforms a prism by a matrix4_t transformation
00136 template <class Size>
00137 prism_base_t<Size>
00138 operator *
00139 (
00140 IN const matrix4_t& T,
00141 IN const prism_base_t<Size>& prism
00142 )
00143 {
00144         ASSERT_THROW(prism.isValid(), "Invalid prism being transformed");
00145         prism_base_t<Size> outPrism;
00146         outPrism.setVertexCount(prism.nVertices);
00147         transformPoints(T, prism.nVertices, prism.points, outPrism.points);
00148         return outPrism;
00149 }
00150 
00151 
00152 
00153 #endif  // WAVEPACKET_PRISM_H__
00154