My Project
 All Classes Files Functions Variables Enumerations Pages
geometry.h
Go to the documentation of this file.
1 /**************************************************************************/
2 /* Copyright 2009 Tim Day */
3 /* */
4 /* This file is part of Fracplanet */
5 /* */
6 /* Fracplanet 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 3 of the License, or */
9 /* (at your option) any later version. */
10 /* */
11 /* Fracplanet 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 Fracplanet. If not, see <http://www.gnu.org/licenses/>. */
18 /**************************************************************************/
19 
24 #ifndef _geometry_h_
25 #define _geometry_h_
26 
27 #include "scan.h"
28 #include "vertex.h"
29 #include "xyz.h"
30 
32 
36 class Geometry : public ScanConverter
37 {
38 public:
39 
41  Geometry(uint seed)
42  :_r01(seed)
43  {}
44 
46  virtual ~Geometry()
47  {}
48 
50  virtual float height(const XYZ& p) const
51  =0;
52 
54  virtual void set_height(XYZ& p,float v) const
55  =0;
56 
58  virtual const XYZ midpoint(const XYZ& v0,const XYZ& v1) const
59  =0;
60 
62  virtual float normalised_latitude(const XYZ&p) const
63  =0;
64 
66  virtual const XYZ up(const XYZ& p) const
67  =0;
69  virtual const XYZ north(const XYZ& p) const
70  =0;
72  virtual const XYZ east(const XYZ& p) const
73  =0;
74 
76  virtual const XYZ perturb(const XYZ& v,const XYZ& variation) const
77  =0;
78 
80 
83  virtual float epsilon() const
84  =0;
85 
87  virtual uint scan_convert_image_aspect_ratio() const
88  {
89  return 1;
90  }
91 
92  protected:
93 
95  static void scan_convert_common
96  (
97  const boost::array<XYZ,3>& v,
98  const ScanConvertBackend& backend
99  );
100 
102 
105  mutable Random01 _r01;
106 };
107 
109 class GeometryFlat : public Geometry
110 {
111  public:
112 
113  GeometryFlat(uint seed)
114  :Geometry(seed)
115  {}
116 
117  ~GeometryFlat()
118  {}
119 
121  float height(const XYZ& p) const
122  {
123  return p.z;
124  }
125 
127  void set_height(XYZ& p,float v) const
128  {
129  p.z=v;
130  }
131 
133  const XYZ midpoint(const XYZ& v0,const XYZ& v1) const
134  {
135  return 0.5f*(v0+v1);
136  }
137 
139  float normalised_latitude(const XYZ&) const
140  {
141  return 0.0f;
142  }
143 
145  const XYZ up(const XYZ&) const
146  {
147  return XYZ(0.0f,0.0f,1.0f);
148  }
149 
151  const XYZ north(const XYZ&) const
152  {
153  return XYZ(0.0f,1.0f,0.0f);
154  }
155 
157  const XYZ east(const XYZ&) const
158  {
159  return XYZ(1.0f,0.0f,0.0f);
160  }
161 
163  const XYZ perturb(const XYZ& p,const XYZ& variation) const
164  {
165  // The correct thing to do would be to return p+RandomXYZInEllipsoid(_r01,variation);
166  // however, this uses a variable number of random number calls which means small parameter changes can have big effects on generated terrain.
167 
168  // This, on the other hand, always uses the same number of random numbers, but isn't statistically equivalent:
169  return p+RandomXYZInBox(_r01,variation);
170  }
171 
173  float epsilon() const
174  {
175  return 0.0f; // No need 'cos heights are stored exactly
176  }
177 
178  virtual void scan_convert
179  (
180  const boost::array<XYZ,3>& v,
181  const ScanConvertBackend&
182  ) const;
183 };
184 
187 {
188  public:
190  GeometrySpherical(uint seed)
191  :Geometry(seed)
192  {}
193 
196  {}
197 
199  float height(const XYZ& p) const
200  {
201  return p.magnitude()-1.0f;
202  }
203 
205  void set_height(XYZ& p,float h) const
206  {
207  const float m=p.magnitude();
208  p*=((1.0f+h)/m);
209  }
210 
212  const XYZ midpoint(const XYZ& v0,const XYZ& v1) const
213  {
214  const float h0=v0.magnitude();
215  const float h1=v1.magnitude();
216  const float h_av=0.5f*(h0+h1);
217 
218  const XYZ m(0.5f*(v0+v1));
219  return (h_av/m.magnitude())*m;
220  }
221 
223  float normalised_latitude(const XYZ& p) const
224  {
225  return p.z;
226  }
227 
229  const XYZ up(const XYZ& p) const
230  {
231  return p.normalised();
232  }
233 
235 
237  const XYZ north(const XYZ& p) const
238  {
239  if (p.x==0.0f && p.y==0.0f)
240  return XYZ(0.0f,0.0f,0.0f);
241  else
242  return (up(p)*east(p)).normalised();
243  }
244 
246 
248  const XYZ east(const XYZ& p) const
249  {
250  if (p.x==0.0f && p.y==0.0f)
251  return XYZ(0.0f,0.0f,0.0f);
252  else
253  return (XYZ(0.0f,0.0f,1.0f)*up(p)).normalised();
254  }
255 
257 
259  const XYZ perturb(const XYZ& p,const XYZ& variation) const
260  {
261  // The correct thing to do would be to use const RandomXYZInEllipsoid v(_r01,variation);
262  // however, this uses a variable number of random number calls which means small parameter changes can have big effects on generated terrain.
263 
264  // This, on the other hand, always uses the same number of random numbers, but isn't statistically equivalent:
265  const RandomXYZInBox v(_r01,variation);
266  return p+v.x*east(p)+v.y*north(p)+v.z*up(p);
267  }
268 
270  float epsilon() const
271  {
272  return 0.000001f;
273  }
274 
275  void scan_convert
276  (
277  const boost::array<XYZ,3>& v,
278  const ScanConvertBackend&
279  ) const;
280 
283  {
284  return 2;
285  }
286 };
287 
288 #endif
void scan_convert(const boost::array< XYZ, 3 > &v, const ScanConvertBackend &) const
Definition: geometry.cpp:114
virtual const XYZ midpoint(const XYZ &v0, const XYZ &v1) const =0
Return a point halfway between the two given points.
float epsilon() const
This needs to return something small for the lake flooding algorithm to work.
Definition: geometry.h:270
virtual float normalised_latitude(const XYZ &p) const =0
Really only meaningful for spherical geometries.
Geometry(uint seed)
Constructor.
Definition: geometry.h:41
virtual const XYZ east(const XYZ &p) const =0
Return the direction of "east" at the specified point.
~GeometrySpherical()
Destructor.
Definition: geometry.h:195
GeometrySpherical(uint seed)
Constructor.
Definition: geometry.h:190
Interface for class XYZ.
uint scan_convert_image_aspect_ratio() const
Return 2.0 for spheres because vertical range is +/- pi/2, horizontal is +/- pi.
Definition: geometry.h:282
float height(const XYZ &p) const
Height is just the z co-ordinate of a point.
Definition: geometry.h:121
const XYZ midpoint(const XYZ &v0, const XYZ &v1) const
The mid-point between two points is simply their average.
Definition: geometry.h:133
Random01 _r01
Random number generator used for perturbations and the like.
Definition: geometry.h:105
virtual void scan_convert(const boost::array< XYZ, 3 > &v, const ScanConvertBackend &) const
Definition: geometry.cpp:95
Generates random points in a recnangular box centred on the origin.
Definition: xyz.h:245
const XYZ perturb(const XYZ &p, const XYZ &variation) const
Add a random variation to a point.
Definition: geometry.h:163
float normalised_latitude(const XYZ &) const
This doesn't really mean anything here, so return zero, which would correspond to the equator of a sp...
Definition: geometry.h:139
Class to provide abstract interface to different world geometries.
Definition: geometry.h:36
virtual uint scan_convert_image_aspect_ratio() const
Multiplier for width of a scan-converted image.
Definition: geometry.h:87
Class to hold vectors in 3D cartesian co-ordinates.
Definition: xyz.h:34
virtual void set_height(XYZ &p, float v) const =0
Move the specified point vertically until.
float magnitude() const
Return the magnitude.
Definition: xyz.h:131
float height(const XYZ &p) const
Height is relative to the surface of the unit radius sphere.
Definition: geometry.h:199
float epsilon() const
Returns zero. Heights are stored exactly once assigned so no need for non-zero epsilon.
Definition: geometry.h:173
virtual const XYZ up(const XYZ &p) const =0
Return the direction of "up" at the specified point.
virtual ~Geometry()
Destructor.
Definition: geometry.h:46
const XYZ east(const XYZ &) const
Returns unit x vector. (East is the same everywhere in this geometry).
Definition: geometry.h:157
Interface for class Vertex.
const XYZ up(const XYZ &p) const
Up is normal to the sphere.
Definition: geometry.h:229
void set_height(XYZ &p, float v) const
Setting a height is simply assigning to the z-coordinate.
Definition: geometry.h:127
Generates random numbers in the range [0,1).
Definition: random.h:28
static void scan_convert_common(const boost::array< XYZ, 3 > &v, const ScanConvertBackend &backend)
Common scan-converter code.
Definition: geometry.cpp:27
virtual float height(const XYZ &p) const =0
Return the height of the given point.
Concrete class providing a flat geometry (in the XY-plane, with Z up).
Definition: geometry.h:109
Definition: scan.h:76
virtual float epsilon() const =0
Nasty hack to work around height setting possibly not being exact.
Interface for classes for scan conversion.
const XYZ up(const XYZ &) const
Returns unit z vector. (Up is the same everywhere in this geometry).
Definition: geometry.h:145
const XYZ north(const XYZ &) const
Returns unit y vector. (North is the same everywhere in this geometry).
Definition: geometry.h:151
void set_height(XYZ &p, float h) const
The height set is relative to the surface of the unit radius sphere.
Definition: geometry.h:205
const XYZ east(const XYZ &p) const
East is perpendicular to "up" and the polar vector.
Definition: geometry.h:248
const XYZ midpoint(const XYZ &v0, const XYZ &v1) const
Don't just take the mid-point of the straight-line path through the sphere's surface: must work relat...
Definition: geometry.h:212
Definition: scan.h:55
virtual const XYZ north(const XYZ &p) const =0
Return the direction of "north" at the specified point.
float normalised_latitude(const XYZ &p) const
Normalised latitude is 1.0 at the north pole, -1.0 at the south pole.
Definition: geometry.h:223
Concrete class providing a flat geometry (a sphere with nominal radius 1, equator in the XY-plane...
Definition: geometry.h:186
const XYZ normalised() const
Return the vector normalised.
Definition: xyz.h:217
virtual const XYZ perturb(const XYZ &v, const XYZ &variation) const =0
Add a random variation to a point.
const XYZ perturb(const XYZ &p, const XYZ &variation) const
Add a random variation to a point.
Definition: geometry.h:259
const XYZ north(const XYZ &p) const
North is perpendicular to "up" and "east".
Definition: geometry.h:237