1 // rotatepoint.h
2 //
3 // Copyright (C) 2003, 2004 Jason Bevins
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 // The developer's email is jlbezigvins@gmzigail.com (for great email, take
20 // off every 'zig'.)
21 //
22 module noise.mod.rotatepoint;
23 
24 private {
25   import noise.mod.modulebase;
26   import noise.mathconsts;
27 }
28 
29 /// @addtogroup libnoise
30 /// @{
31 
32 /// @addtogroup modules
33 /// @{
34 
35 /// @addtogroup transformermodules
36 /// @{
37 
38 /// Default @a x rotation angle for the module::RotatePoint noise
39 /// module.
40 const double DEFAULT_ROTATE_X = 0.0;
41 
42 /// Default @a y rotation angle for the module::RotatePoint noise
43 /// module.
44 const double DEFAULT_ROTATE_Y = 0.0;
45 
46 /// Default @a z rotation angle for the module::RotatePoint noise
47 /// module.
48 const double DEFAULT_ROTATE_Z = 0.0;
49 
50 /// Noise module that rotates the input value around the origin before
51 /// returning the output value from a source module.
52 ///
53 /// @image html modulerotatepoint.png
54 ///
55 /// The GetValue() method rotates the coordinates of the input value
56 /// around the origin before returning the output value from the source
57 /// module.  To set the rotation angles, call the SetAngles() method.  To
58 /// set the rotation angle around the individual @a x, @a y, or @a z axes,
59 /// call the SetXAngle(), SetYAngle() or SetZAngle() methods,
60 /// respectively.
61 ///
62 /// The coordinate system of the input value is assumed to be
63 /// "left-handed" (@a x increases to the right, @a y increases upward,
64 /// and @a z increases inward.)
65 ///
66 /// This noise module requires one source module.
67 class RotatePoint : Mod
68 {
69 
70   public:
71 
72     /// Constructor.
73     ///
74     /// The default rotation angle around the @a x axis, in degrees, is
75     /// set to module::DEFAULT_ROTATE_X.
76     ///
77     /// The default rotation angle around the @a y axis, in degrees, is
78     /// set to module::DEFAULT_ROTATE_Y.
79     ///
80     /// The default rotation angle around the @a z axis, in degrees, is
81     /// set to module::DEFAULT_ROTATE_Z.
82     this()
83     {
84         super(this.GetSourceModCount());
85         SetAngles (DEFAULT_ROTATE_X, DEFAULT_ROTATE_Y, DEFAULT_ROTATE_Z);
86     }
87 
88     override int GetSourceModCount () const
89     {
90       return 1;
91     }
92 
93     override double GetValue (double x, double y, double z) const
94     {
95       assert (m_pSourceMod[0] !is null);
96 
97       double nx = (m_x1Matrix * x) + (m_y1Matrix * y) + (m_z1Matrix * z);
98       double ny = (m_x2Matrix * x) + (m_y2Matrix * y) + (m_z2Matrix * z);
99       double nz = (m_x3Matrix * x) + (m_y3Matrix * y) + (m_z3Matrix * z);
100       return m_pSourceMod[0].GetValue (nx, ny, nz);
101     }
102 
103     /// Returns the rotation angle around the @a x axis to apply to the
104     /// input value.
105     ///
106     /// @returns The rotation angle around the @a x axis, in degrees.
107     double GetXAngle () const
108     {
109       return m_xAngle;
110     }
111 
112     /// Returns the rotation angle around the @a y axis to apply to the
113     /// input value.
114     ///
115     /// @returns The rotation angle around the @a y axis, in degrees.
116     double GetYAngle () const
117     {
118       return m_yAngle;
119     }
120 
121     /// Returns the rotation angle around the @a z axis to apply to the
122     /// input value.
123     ///
124     /// @returns The rotation angle around the @a z axis, in degrees.
125     double GetZAngle () const
126     {
127       return m_zAngle;
128     }
129 
130     /// Sets the rotation angles around all three axes to apply to the
131     /// input value.
132     ///
133     /// @param xAngle The rotation angle around the @a x axis, in degrees.
134     /// @param yAngle The rotation angle around the @a y axis, in degrees.
135     /// @param zAngle The rotation angle around the @a z axis, in degrees.
136     ///
137     /// The GetValue() method rotates the coordinates of the input value
138     /// around the origin before returning the output value from the
139     /// source module.
140     void SetAngles (double xAngle, double yAngle, double zAngle)
141     {
142       double xCos, yCos, zCos, xSin, ySin, zSin;
143       xCos = cos (xAngle * DEG_TO_RAD);
144       yCos = cos (yAngle * DEG_TO_RAD);
145       zCos = cos (zAngle * DEG_TO_RAD);
146       xSin = sin (xAngle * DEG_TO_RAD);
147       ySin = sin (yAngle * DEG_TO_RAD);
148       zSin = sin (zAngle * DEG_TO_RAD);
149 
150       m_x1Matrix = ySin * xSin * zSin + yCos * zCos;
151       m_y1Matrix = xCos * zSin;
152       m_z1Matrix = ySin * zCos - yCos * xSin * zSin;
153       m_x2Matrix = ySin * xSin * zCos - yCos * zSin;
154       m_y2Matrix = xCos * zCos;
155       m_z2Matrix = -yCos * xSin * zCos - ySin * zSin;
156       m_x3Matrix = -ySin * xCos;
157       m_y3Matrix = xSin;
158       m_z3Matrix = yCos * xCos;
159 
160       m_xAngle = xAngle;
161       m_yAngle = yAngle;
162       m_zAngle = zAngle;
163     }
164 
165     /// Sets the rotation angle around the @a x axis to apply to the input
166     /// value.
167     ///
168     /// @param xAngle The rotation angle around the @a x axis, in degrees.
169     ///
170     /// The GetValue() method rotates the coordinates of the input value
171     /// around the origin before returning the output value from the
172     /// source module.
173     void SetXAngle (double xAngle)
174     {
175       SetAngles (xAngle, m_yAngle, m_zAngle);
176     }
177 
178     /// Sets the rotation angle around the @a y axis to apply to the input
179     /// value.
180     ///
181     /// @param yAngle The rotation angle around the @a y axis, in degrees.
182     ///
183     /// The GetValue() method rotates the coordinates of the input value
184     /// around the origin before returning the output value from the
185     /// source module.
186     void SetYAngle (double yAngle)
187     {
188       SetAngles (m_xAngle, yAngle, m_zAngle);
189     }
190 
191     /// Sets the rotation angle around the @a z axis to apply to the input
192     /// value.
193     ///
194     /// @param zAngle The rotation angle around the @a z axis, in degrees.
195     ///
196     /// The GetValue() method rotates the coordinates of the input value
197     /// around the origin before returning the output value from the
198     /// source module.
199     void SetZAngle (double zAngle)
200     {
201       SetAngles (m_xAngle, m_yAngle, zAngle);
202     }
203 
204   protected:
205 
206     /// An entry within the 3x3 rotation matrix used for rotating the
207     /// input value.
208     double m_x1Matrix;
209 
210     /// An entry within the 3x3 rotation matrix used for rotating the
211     /// input value.
212     double m_x2Matrix;
213 
214     /// An entry within the 3x3 rotation matrix used for rotating the
215     /// input value.
216     double m_x3Matrix;
217 
218     /// @a x rotation angle applied to the input value, in degrees.
219     double m_xAngle;
220 
221     /// An entry within the 3x3 rotation matrix used for rotating the
222     /// input value.
223     double m_y1Matrix;
224 
225     /// An entry within the 3x3 rotation matrix used for rotating the
226     /// input value.
227     double m_y2Matrix;
228 
229     /// An entry within the 3x3 rotation matrix used for rotating the
230     /// input value.
231     double m_y3Matrix;
232 
233     /// @a y rotation angle applied to the input value, in degrees.
234     double m_yAngle;
235 
236     /// An entry within the 3x3 rotation matrix used for rotating the
237     /// input value.
238     double m_z1Matrix;
239 
240     /// An entry within the 3x3 rotation matrix used for rotating the
241     /// input value.
242     double m_z2Matrix;
243 
244     /// An entry within the 3x3 rotation matrix used for rotating the
245     /// input value.
246     double m_z3Matrix;
247 
248     /// @a z rotation angle applied to the input value, in degrees.
249     double m_zAngle;
250 
251 };
252 
253 /// @}
254 
255 /// @}
256 
257 /// @}