1 // line.h
2 //
3 // Copyright (C) 2004 Keith Davies
4 //
5 // This library is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation; either version 2.1 of the License, or (at
8 // your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
13 // License (COPYING.txt) for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this library; if not, write to the Free Software Foundation,
17 // Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 //
19 module noise.model.line;
20 
21 private {
22     import std.math;
23     import noise.mod.modulebase;
24 }
25 
26 /// @addtogroup libnoise
27 /// @{
28 
29 /// @addtogroup models
30 /// @{
31 
32 /// Model that defines the displacement of a line segment.
33 ///
34 /// This model returns an output value from a noise module given the
35 /// one-dimensional coordinate of an input value located on a line
36 /// segment, which can be used as displacements.
37 ///
38 /// This class is useful for creating:
39 ///  - roads and rivers
40 ///  - disaffected college students
41 ///
42 /// To generate an output value, pass an input value between 0.0 and 1.0
43 /// to the GetValue() method.  0.0 represents the start position of the
44 /// line segment and 1.0 represents the end position of the line segment.
45 class Line
46 {
47 
48   public:
49 
50     /// Constructor.
51     this ()
52     {
53         m_attenuate = true;
54         m_pMod = null;
55         m_x0 = 0.0;
56         m_x1 = 1.0;
57         m_y0 = 0.0;
58         m_y1 = 1.0;
59         m_z0 = 0.0;
60         m_z1 = 1.0;
61     }
62 
63     /// Constructor
64     ///
65     /// @param module The noise module that is used to generate the output
66     /// values.
67     this (ref const(Mod) mod)
68     {
69         m_attenuate = true;
70         m_pMod = &mod;
71         m_x0 = 0.0;
72         m_x1 = 1.0;
73         m_y0 = 0.0;
74         m_y1 = 1.0;
75         m_z0 = 0.0;
76         m_z1 = 1.0;
77     }
78 
79     /// Returns a flag indicating whether the output value is to be
80     /// attenuated (moved toward 0.0) as the ends of the line segment are
81     /// approached by the input value.
82     ///
83     /// @returns
84     /// - @a true if the value is to be attenuated
85     /// - @a false if not.
86     bool GetAttenuate () const
87     {
88       return m_attenuate;
89     }
90 
91     /// Returns the noise module that is used to generate the output
92     /// values.
93     ///
94     /// @returns A reference to the noise module.
95     ///
96     /// @pre A noise module was passed to the SetMod() method.
97     ref const(Mod) GetMod () const
98     {
99       assert (m_pMod !is null);
100       return *m_pMod;
101     }
102 
103     /// Returns the output value from the noise module given the
104     /// one-dimensional coordinate of the specified input value located
105     /// on the line segment.
106     ///
107     /// @param p The distance along the line segment (ranges from 0.0
108     /// to 1.0)
109     ///
110     /// @returns The output value from the noise module.
111     ///
112     /// @pre A noise module was passed to the SetMod() method.
113     /// @pre The start and end points of the line segment were specified.
114     ///
115     /// The output value is generated by the noise module passed to the
116     /// SetMod() method.  This value may be attenuated (moved toward
117     /// 0.0) as @a p approaches either end of the line segment; this is
118     /// the default behavior.
119     ///
120     /// If the value is not to be attenuated, @a p can safely range
121     /// outside the 0.0 to 1.0 range; the output value will be
122     /// extrapolated along the line that this segment is part of.
123     double GetValue (double p) const
124     {
125       assert (m_pMod !is null);
126 
127       double x = (m_x1 - m_x0) * p + m_x0;
128       double y = (m_y1 - m_y0) * p + m_y0;
129       double z = (m_z1 - m_z0) * p + m_z0;
130       double value = m_pMod.GetValue (x, y, z);
131 
132       if (m_attenuate) {
133         return p * (1.0 - p) * 4 * value;
134       } else {
135         return value;
136       }
137     }
138 
139     /// Sets a flag indicating that the output value is to be attenuated
140     /// (moved toward 0.0) as the ends of the line segment are approached.
141     ///
142     /// @param att A flag that specifies whether the output value is to be
143     /// attenuated.
144     void SetAttenuate (bool att)
145     {
146       m_attenuate = att;
147     }
148 
149     /// Sets the position ( @a x, @a y, @a z ) of the end of the line
150     /// segment to choose values along.
151     ///
152     /// @param x x coordinate of the end position.
153     /// @param y y coordinate of the end position.
154     /// @param z z coordinate of the end position.
155     void SetEndPoint (double x, double y, double z)
156     {
157       m_x1 = x;
158       m_y1 = y;
159       m_z1 = z;
160     }
161 
162     /// Sets the noise module that is used to generate the output values.
163     ///
164     /// @param module The noise module that is used to generate the output
165     /// values.
166     ///
167     /// This noise module must exist for the lifetime of this object,
168     /// until you pass a new noise module to this method.
169     void SetMod (ref const(Mod) mod)
170     {
171       m_pMod = &mod;
172     }
173 
174     /// Sets the position ( @a x, @a y, @a z ) of the start of the line
175     /// segment to choose values along.
176     ///
177     /// @param x x coordinate of the start position.
178     /// @param y y coordinate of the start position.
179     /// @param z z coordinate of the start position.
180     void SetStartPoint (double x, double y, double z)
181     {
182       m_x0 = x;
183       m_y0 = y;
184       m_z0 = z;
185     }
186 
187   private:
188 
189     /// A flag that specifies whether the value is to be attenuated
190     /// (moved toward 0.0) as the ends of the line segment are approached.
191     bool m_attenuate;
192 
193     /// A pointer to the noise module used to generate the output values.
194     const(Mod)* m_pMod;
195 
196     /// @a x coordinate of the start of the line segment.
197     double m_x0;
198 
199     /// @a x coordinate of the end of the line segment.
200     double m_x1;
201 
202     /// @a y coordinate of the start of the line segment.
203     double m_y0;
204 
205     /// @a y coordinate of the end of the line segment.
206     double m_y1;
207 
208     /// @a z coordinate of the start of the line segment.
209     double m_z0;
210 
211     /// @a z coordinate of the end of the line segment.
212     double m_z1;
213 
214 };
215 
216 /// @}
217 
218 /// @}