]>
Dogcows Code - chaz/yoink/blob - src/cml/mathlib/coord_conversion.h
1 /* -*- C++ -*- ------------------------------------------------------------
3 Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/
5 The Configurable Math Library (CML) is distributed under the terms of the
6 Boost Software License, v1.0 (see cml/LICENSE for details).
8 *-----------------------------------------------------------------------*/
13 #ifndef coord_conversion_h
14 #define coord_conversion_h
16 #include <cml/mathlib/checking.h>
17 #include <cml/mathlib/epsilon.h>
18 #include <cml/mathlib/helper.h>
20 /* Functions for converting between Cartesian, polar, cylindrical and
21 * spherical coordinates.
23 * The 3D conversion functions take an integer axis index argument. For
24 * cylindrical coordinates this determines the axis of the cylinder, and for
25 * spherical it determines which cardinal axis is normal to the azimuth plane.
27 * For spherical coordinates the option of whether to treat phi as latitude
28 * or colatitude is also available. The 'type' argument takes either of the
29 * enumerants cml::latitude and cml::colatitude to reflect this.
34 //////////////////////////////////////////////////////////////////////////////
35 // Conversion to Cartesian coordinates
36 //////////////////////////////////////////////////////////////////////////////
38 /* Convert cylindrical coordinates to Cartesian coordinates in R3 */
39 template < typename E
, class A
> void
40 cylindrical_to_cartesian(
41 E radius
, E theta
, E height
, size_t axis
, vector
<E
,A
>& v
)
43 typedef vector
<E
,A
> vector_type
;
44 typedef typename
vector_type::value_type value_type
;
48 detail::CheckIndex3(axis
);
51 cyclic_permutation(axis
, i
, j
, k
);
54 v
[j
] = std::cos(theta
) * radius
;
55 v
[k
] = std::sin(theta
) * radius
;
58 /* Convert spherical coordinates to Cartesian coordinates in R3 */
59 template < typename E
, class A
> void
60 spherical_to_cartesian(E radius
, E theta
, E phi
, size_t axis
,
61 SphericalType type
, vector
<E
,A
>& v
)
63 typedef vector
<E
,A
> vector_type
;
64 typedef typename
vector_type::value_type value_type
;
68 detail::CheckIndex3(axis
);
70 if (type
== latitude
) {
71 phi
= constants
<value_type
>::pi_over_2() - phi
;
74 value_type sin_phi
= std::sin(phi
);
75 value_type cos_phi
= std::cos(phi
);
76 value_type sin_phi_r
= sin_phi
* radius
;
79 cyclic_permutation(axis
, i
, j
, k
);
81 v
[i
] = cos_phi
* radius
;
82 v
[j
] = sin_phi_r
* std::cos(theta
);
83 v
[k
] = sin_phi_r
* std::sin(theta
);
86 /* Convert polar coordinates to Cartesian coordinates in R2 */
87 template < typename E
, class A
> void
88 polar_to_cartesian(E radius
, E theta
, vector
<E
,A
>& v
)
90 /* Checking handled by set() */
91 v
.set(std::cos(theta
) * double(radius
), std::sin(theta
) * double(radius
));
94 //////////////////////////////////////////////////////////////////////////////
95 // Conversion from Cartesian coordinates
96 //////////////////////////////////////////////////////////////////////////////
98 /* Convert Cartesian coordinates to cylindrical coordinates in R3 */
99 template < class VecT
, typename Real
> void
100 cartesian_to_cylindrical(const VecT
& v
, Real
& radius
, Real
& theta
,
101 Real
& height
, size_t axis
, Real tolerance
= epsilon
<Real
>::placeholder())
103 typedef Real value_type
;
106 detail::CheckVec3(v
);
107 detail::CheckIndex3(axis
);
110 cyclic_permutation(axis
, i
, j
, k
);
112 radius
= length(v
[j
],v
[k
]);
113 theta
= radius
< tolerance
? value_type(0) : std::atan2(v
[k
],v
[j
]);
117 /* Convert Cartesian coordinates to spherical coordinates in R3 */
118 template < class VecT
, typename Real
> void
119 cartesian_to_spherical(const VecT
& v
, Real
& radius
, Real
& theta
, Real
& phi
,
120 size_t axis
, SphericalType type
,
121 Real tolerance
= epsilon
<Real
>::placeholder())
123 typedef Real value_type
;
126 detail::CheckVec3(v
);
127 detail::CheckIndex3(axis
);
130 cyclic_permutation(axis
, i
, j
, k
);
132 value_type len
= length(v
[j
],v
[k
]);
133 theta
= len
< tolerance
? value_type(0) : std::atan2(v
[k
],v
[j
]);
134 radius
= length(v
[i
], len
);
135 if (radius
< tolerance
) {
138 phi
= std::atan2(len
,v
[i
]);
139 //phi = type.convert(phi);
140 if (type
== latitude
) {
141 phi
= constants
<value_type
>::pi_over_2() - phi
;
146 /* Convert Cartesian coordinates to polar coordinates in R2 */
147 template < class VecT
, typename Real
> void
148 cartesian_to_polar(const VecT
& v
, Real
& radius
, Real
& theta
,
149 Real tolerance
= epsilon
<Real
>::placeholder())
151 typedef Real value_type
;
154 detail::CheckVec2(v
);
157 theta
= radius
< tolerance
? value_type(0) : std::atan2(v
[1],v
[0]);
This page took 0.047386 seconds and 5 git commands to generate.