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
20 #include "xyz.h"
21
22 /*! Table so we can look up by element number.
23 */
24 XYZ::ElementPtr XYZ::element_table[3]={&XYZ::x,&XYZ::y,&XYZ::z};
25
write(std::ostream & out) const26 std::ostream& XYZ::write(std::ostream& out) const
27 {
28 return out << x << " " << y << " " << z;
29 }
30
format_comma() const31 const std::string XYZ::format_comma() const
32 {
33 std::ostringstream s;
34 s << x << "," << y << "," << z;
35 return s.str();
36 }
37
format_blender() const38 const std::string XYZ::format_blender() const
39 {
40 std::ostringstream s;
41 s << x << ", " << y << ", " << z;
42 return s.str();
43 }
44
45 /*! Also transposes y and z co-ordinates because of POV-Rays idea of up.
46 */
format_pov() const47 const std::string XYZ::format_pov() const
48 {
49 std::ostringstream s;
50 s << "<" << x << "," << z << "," << y << ">";
51 return s.str();
52 }
53
RandomXYZInUnitCube(Random01 & rng)54 RandomXYZInUnitCube::RandomXYZInUnitCube(Random01& rng)
55 :XYZ()
56 {
57 x=rng();
58 y=rng();
59 z=rng();
60 }
61
RandomXYZInBox(Random01 & rng,const XYZ & bounds)62 RandomXYZInBox::RandomXYZInBox(Random01& rng,const XYZ& bounds)
63 :XYZ()
64 {
65 x=-bounds.x+2.0*bounds.x*rng();
66 y=-bounds.y+2.0*bounds.y*rng();
67 z=-bounds.z+2.0*bounds.z*rng();
68 }
69
RandomXYZInSphere(Random01 & rng,float radius)70 RandomXYZInSphere::RandomXYZInSphere(Random01& rng,float radius)
71 :XYZ()
72 {
73 do
74 {
75 x=2.0*rng()-1.0;
76 y=2.0*rng()-1.0;
77 z=2.0*rng()-1.0;
78 }
79 while (magnitude2()>1.0);
80 (*this)*=radius;
81 }
82
83 /*! Can handle case of individual axes being zero.
84 */
RandomXYZInEllipsoid(Random01 & rng,const XYZ & axes)85 RandomXYZInEllipsoid::RandomXYZInEllipsoid(Random01& rng,const XYZ& axes)
86 :XYZ()
87 {
88 do
89 {
90 assign(RandomXYZInBox(rng,axes));
91 }
92 while (
93 (axes.x==0.0 ? 0.0 : sqr(x/axes.x))
94 +(axes.y==0.0 ? 0.0 : sqr(y/axes.y))
95 +(axes.z==0.0 ? 0.0 : sqr(z/axes.z))
96 >1.0
97 );
98 }
99
RandomXYZSphereNormal(Random01 & rng)100 RandomXYZSphereNormal::RandomXYZSphereNormal(Random01& rng)
101 :XYZ(0.0,0.0,0.0)
102 {
103 float m2;
104 do
105 {
106 assign(RandomXYZInSphere(rng,1.0));
107 m2=magnitude2();
108 }
109 while (m2==0.0);
110
111 (*this)/=sqrtf(m2);
112 }
113