00001
00002
00003
00004
00005
00006
00007
00008
00015 #ifndef vector_ortho_h
00016 #define vector_ortho_h
00017
00018 #include <cml/mathlib/vector_misc.h>
00019 #include <cml/mathlib/misc.h>
00020
00021 namespace cml {
00022
00024
00026
00027
00042 template < typename E, class A > void
00043 orthonormalize(vector<E,A>& v0, vector<E,A>& v1, vector<E,A>& v2,
00044 size_t stable_axis = 2, size_t num_iter = 0, E s = E(1))
00045 {
00046
00047 detail::CheckVec3(v0);
00048 detail::CheckVec3(v1);
00049 detail::CheckVec3(v2);
00050 detail::CheckIndex3(stable_axis);
00051
00052 typedef vector< E, fixed<3> > vector_type;
00053 typedef typename vector_type::value_type value_type;
00054
00055
00056
00057 for (size_t i = 0; i < num_iter; ++i) {
00058 value_type dot01 = dot(v0,v1);
00059 value_type dot12 = dot(v1,v2);
00060 value_type dot20 = dot(v2,v0);
00061 value_type inv_dot00 = value_type(1) / dot(v0,v0);
00062 value_type inv_dot11 = value_type(1) / dot(v1,v1);
00063 value_type inv_dot22 = value_type(1) / dot(v2,v2);
00064
00065 vector_type temp0 = v0 - s*dot01*inv_dot11*v1 - s*dot20*inv_dot22*v2;
00066 vector_type temp1 = v1 - s*dot12*inv_dot22*v2 - s*dot01*inv_dot00*v0;
00067 vector_type temp2 = v2 - s*dot20*inv_dot00*v0 - s*dot12*inv_dot11*v1;
00068
00069 v0 = temp0;
00070 v1 = temp1;
00071 v2 = temp2;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080 size_t i, j, k;
00081 cyclic_permutation(stable_axis, i, j, k);
00082 vector_type v[] = { v0, v1, v2 };
00083
00084 v[i].normalize();
00085 v[j] = normalize(project_to_hplane(v[j],v[i]));
00086 v[k] = normalize(project_to_hplane(project_to_hplane(v[k],v[i]),v[j]));
00087
00088 v0 = v[0];
00089 v1 = v[1];
00090 v2 = v[2];
00091 }
00092
00094 template < typename E, class A > void
00095 orthonormalize(vector<E,A>& v0, vector<E,A>& v1,
00096 size_t stable_axis = 0, size_t num_iter = 0, E s = E(1))
00097 {
00098 typedef vector< E, fixed<2> > vector_type;
00099 typedef typename vector_type::value_type value_type;
00100
00101
00102 detail::CheckVec2(v0);
00103 detail::CheckVec2(v1);
00104 detail::CheckIndex2(stable_axis);
00105
00106
00107
00108 for (size_t i = 0; i < num_iter; ++i) {
00109 value_type dot01 = dot(v0,v1);
00110
00111 vector_type temp0 = v0 - (s * dot01 * v1) / dot(v1,v1);
00112 vector_type temp1 = v1 - (s * dot01 * v0) / dot(v0,v0);
00113
00114 v0 = temp0;
00115 v1 = temp1;
00116 }
00117
00118
00119
00120
00121
00122
00123
00124 size_t i, j;
00125 cyclic_permutation(stable_axis, i, j);
00126 vector_type v[] = { v0, v1 };
00127
00128 v[i].normalize();
00129 v[j] = normalize(project_to_hplane(v[j],v[i]));
00130
00131 v0 = v[0];
00132 v1 = v[1];
00133 }
00134
00136
00138
00158 template < class VecT_1, class VecT_2, typename E, class A > void
00159 orthonormal_basis(
00160 const VecT_1& align,
00161 const VecT_2& reference,
00162 vector<E,A>& x,
00163 vector<E,A>& y,
00164 vector<E,A>& z,
00165 bool normalize_align = true,
00166 AxisOrder order = axis_order_zyx)
00167 {
00168 typedef vector< E,fixed<3> > vector_type;
00169 typedef typename vector_type::value_type value_type;
00170
00171
00172
00173 size_t i, j, k;
00174 bool odd;
00175 detail::unpack_axis_order(order, i, j, k, odd);
00176
00177 vector_type axis[3];
00178
00179 axis[i] = normalize_align ? normalize(align) : align;
00180 axis[k] = unit_cross(axis[i],reference);
00181 axis[j] = cross(axis[k],axis[i]);
00182
00183 if (odd) {
00184 axis[k] = -axis[k];
00185 }
00186
00187 x = axis[0];
00188 y = axis[1];
00189 z = axis[2];
00190 }
00191
00200 template < class VecT, typename E, class A >
00201 void orthonormal_basis(
00202 const VecT& align,
00203 vector<E,A>& x,
00204 vector<E,A>& y,
00205 vector<E,A>& z,
00206 bool normalize_align = true,
00207 AxisOrder order = axis_order_zyx)
00208 {
00209
00210 detail::CheckVec3(align);
00211
00212
00213
00214 orthonormal_basis(
00215 align,
00216 axis_3D(cml::index_of_min_abs(align[0],align[1],align[2])),
00217 x, y, z, normalize_align, order
00218 );
00219 }
00220
00234 template < class VecT_1, class VecT_2, typename E, class A >
00235 void orthonormal_basis_axial(
00236 const VecT_1& align,
00237 const VecT_2& axis,
00238 vector<E,A>& x,
00239 vector<E,A>& y,
00240 vector<E,A>& z,
00241 bool normalize_align = true,
00242 AxisOrder order = axis_order_zyx)
00243 {
00244 orthonormal_basis(
00245 axis,
00246 align,
00247 x,
00248 y,
00249 z,
00250 normalize_align,
00251 detail::swap_axis_order(order));
00252 }
00253
00260 template < class MatT, typename E, class A >
00261 void orthonormal_basis_viewplane(
00262 const MatT& view_matrix,
00263 vector<E,A>& x,
00264 vector<E,A>& y,
00265 vector<E,A>& z,
00266 Handedness handedness,
00267 AxisOrder order = axis_order_zyx)
00268 {
00269 typedef MatT matrix_type;
00270 typedef typename matrix_type::value_type value_type;
00271
00272 orthonormal_basis(
00273 -(handedness == left_handed ? value_type(1) : value_type(-1)) *
00274 matrix_get_transposed_z_basis_vector(view_matrix),
00275 matrix_get_transposed_y_basis_vector(view_matrix),
00276 x, y, z, false, order
00277 );
00278 }
00279
00281 template < class MatT, typename E, class A >
00282 void orthonormal_basis_viewplane_LH(
00283 const MatT& view_matrix,
00284 vector<E,A>& x,
00285 vector<E,A>& y,
00286 vector<E,A>& z,
00287 AxisOrder order = axis_order_zyx)
00288 {
00289 orthonormal_basis_viewplane(
00290 view_matrix,x,y,z,left_handed,order);
00291 }
00292
00294 template < class MatT, typename E, class A >
00295 void orthonormal_basis_viewplane_RH(
00296 const MatT& view_matrix,
00297 vector<E,A>& x,
00298 vector<E,A>& y,
00299 vector<E,A>& z,
00300 AxisOrder order = axis_order_zyx)
00301 {
00302 orthonormal_basis_viewplane(
00303 view_matrix,x,y,z,right_handed,order);
00304 }
00305
00307 template < class VecT, typename E, class A >
00308 void orthonormal_basis_2D(
00309 const VecT& align,
00310 vector<E,A>& x,
00311 vector<E,A>& y,
00312 bool normalize_align = true,
00313 AxisOrder2D order = axis_order_xy)
00314 {
00315 typedef vector< E,fixed<2> > vector_type;
00316
00317
00318
00319 size_t i, j;
00320 bool odd;
00321 detail::unpack_axis_order_2D(order, i, j, odd);
00322
00323 vector_type axis[2];
00324
00325 axis[i] = normalize_align ? normalize(align) : align;
00326 axis[j] = perp(axis[i]);
00327
00328 if (odd) {
00329 axis[j] = -axis[j];
00330 }
00331
00332 x = axis[0];
00333 y = axis[1];
00334 }
00335
00336 }
00337
00338 #endif