1 /* 2 This file is part of MADNESS. 3 4 Copyright (C) 2007,2010 Oak Ridge National Laboratory 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 20 For more information please contact: 21 22 Robert J. Harrison 23 Oak Ridge National Laboratory 24 One Bethel Valley Road 25 P.O. Box 2008, MS-6367 26 27 email: harrisonrj@ornl.gov 28 tel: 865-241-3937 29 fax: 865-572-0680 30 31 $Id$ 32 */ 33 34 /** 35 \file mra/sdf_shape_2D.h 36 \brief Implements the SignedDFInterface for common 2-D geometric objects. 37 \ingroup mrabcint 38 39 This file provides signed distance functions for common 2-D geometric objects: 40 - Circle 41 - Rectangle 42 43 \note The signed distance functions should be the shortest distance between 44 a point and \b any point on the surface. This is hard to calculate in many 45 cases, so we use contours here. The surface layer may not be equally thick 46 around all points on the surface. Some shapes have the exact shortest 47 distances, which will be noted on a class-by-class basis. Serious usage 48 of the contour-based signed distance functions is not recommended. 49 */ 50 51 #ifndef MADNESS_MRA_SDF_SHAPE_2D_H__INCLUDED 52 #define MADNESS_MRA_SDF_SHAPE_2D_H__INCLUDED 53 54 #include <madness/mra/sdf_domainmask.h> 55 56 namespace madness { 57 58 /// \brief A circle (2 dimensions) 59 class SDFCircle : public SignedDFInterface<2> { 60 protected: 61 const double radius; ///< Radius of circle 62 const coord_2d center; ///< Center of circle 63 64 public: 65 /** \brief SDF for a sphere 66 67 \param radius The radius of the sphere 68 \param center The center of the sphere */ SDFCircle(const double radius,const coord_2d & center)69 SDFCircle(const double radius, const coord_2d ¢er) 70 : radius(radius) 71 , center(center) 72 {} 73 74 /** \brief Computes the normal distance 75 76 This SDF is exact, and easy to show. 77 78 \param pt Point at which to compute the distance from the surface 79 \return The signed distance from the surface */ sdf(const coord_2d & pt)80 double sdf(const coord_2d& pt) const { 81 double temp, r; 82 int i; 83 84 r = 0.0; 85 for(i = 0; i < 2; ++i) { 86 temp = pt[i] - center[i]; 87 r += temp * temp; 88 } 89 90 return sqrt(r) - radius; 91 } 92 93 /** \brief Computes the gradient of the SDF. 94 95 \param pt Point at which to compute the gradient 96 \return the gradient */ grad_sdf(const coord_2d & pt)97 coord_2d grad_sdf(const coord_2d& pt) const { 98 double x = pt[0] - center[0]; 99 double y = pt[1] - center[1]; 100 double r = sqrt(x*x + y*y); 101 coord_2d g; 102 if(r < 1.0e-6) { 103 g[0] = g[1] = 0.0; 104 } 105 else { 106 g[0] = x/r; 107 g[1] = y/r; 108 } 109 return g; 110 } 111 }; 112 113 /** \brief A rectangle (2 dimensions) 114 115 This SDF naively uses contours, and should be improved for serious 116 usage. 117 118 \note LIMIT -- the 2 primary axes must be x and y */ 119 class SDFRectangle : public SignedDFInterface<2> { 120 protected: 121 const coord_2d lengths; ///< Half the length of each side 122 const coord_2d center; ///< the center 123 124 public: 125 /** \brief Constructor for rectangle 126 127 \param length The lengths of the rectangle 128 \param center The center of the rectangle */ SDFRectangle(const coord_2d & length,const coord_2d & center)129 SDFRectangle(const coord_2d& length, const coord_2d& center) 130 : lengths(length*0.5), center(center) 131 {} 132 133 /** \brief Computes the normal distance 134 135 \param pt Point at which to compute the distance from the surface 136 \return The signed distance from the surface */ sdf(const coord_2d & pt)137 double sdf(const coord_2d& pt) const { 138 double diff, max; 139 140 max = fabs(pt[0] - center[0]) - lengths[0]; 141 diff = fabs(pt[1] - center[1]) - lengths[1]; 142 if(diff > max) 143 max = diff; 144 145 return max; 146 } 147 148 /** Computes the gradient of the SDF. 149 150 \param pt Point at which to compute the gradient 151 \return the gradient */ grad_sdf(const coord_2d & pt)152 coord_2d grad_sdf(const coord_2d& pt) const { 153 MADNESS_EXCEPTION("gradient method is not yet implemented for this shape",0); 154 } 155 }; 156 157 } // end of madness namespace 158 159 #endif // MADNESS_MRA_SDF_SHAPE_2D_H__INCLUDED 160