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 &center)
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