File: matrix33.h

package info (click to toggle)
meshlab 1.3.2%2Bdfsg1-4
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 21,096 kB
  • ctags: 33,630
  • sloc: cpp: 224,813; ansic: 8,170; xml: 119; makefile: 80
file content (323 lines) | stat: -rw-r--r-- 9,530 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/****************************************************************************
* VCGLib                                                            o o     *
* Visual and Computer Graphics Library                            o     o   *
*                                                                _   O  _   *
* Copyright(C) 2004                                                \/)\/    *
* Visual Computing Lab                                            /\/|      *
* ISTI - Italian National Research Council                           |      *
*                                                                    \      *
* All rights reserved.                                                      *
*                                                                           *
* This program is free software; you can redistribute it and/or modify      *
* it under the terms of the GNU General Public License as published by      *
* the Free Software Foundation; either version 2 of the License, or         *
* (at your option) any later version.                                       *
*                                                                           *
* This program is distributed in the hope that it will be useful,           *
* but WITHOUT ANY WARRANTY; without even the implied warranty of            *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
* for more details.                                                         *
*                                                                           *
****************************************************************************/

#ifndef VCG_USE_EIGEN
#include "deprecated_matrix33.h"
#else

#ifndef __VCGLIB_MATRIX33_H
#define __VCGLIB_MATRIX33_H

#include "eigen.h"
#include "matrix44.h"

namespace vcg{
template<class Scalar> class Matrix33;
}

namespace Eigen{
template<typename Scalar>
struct ei_traits<vcg::Matrix33<Scalar> > : ei_traits<Eigen::Matrix<Scalar,3,3,RowMajor> > {};
template<typename XprType> struct ei_to_vcgtype<XprType,3,3,RowMajor,3,3>
{ typedef vcg::Matrix33<typename XprType::Scalar> type; };
}

namespace vcg {

/** \deprecated use Matrix<Scalar,3,3>
	@name Matrix33
	Class Matrix33.
    This is the class for definition of a matrix 3x3.
	@param S (Templete Parameter) Specifies the ScalarType field.
*/
template<class _Scalar>
class Matrix33 : public Eigen::Matrix<_Scalar,3,3,Eigen::RowMajor> // FIXME col or row major ?
{

	typedef Eigen::Matrix<_Scalar,3,3,Eigen::RowMajor> _Base;
public:

	using _Base::coeff;
	using _Base::coeffRef;
	using _Base::setZero;

	_EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix33,_Base);
	typedef _Scalar ScalarType;

	VCG_EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Matrix33)

	/// Default constructor
	inline Matrix33() : Base() {}

	/// Copy constructor
	Matrix33(const Matrix33& m ) : Base(m) {}

	/// create from a \b row-major array
	Matrix33(const Scalar * v ) : Base(Eigen::Map<Eigen::Matrix<Scalar,3,3,Eigen::RowMajor> >(v)) {}

	/// create from Matrix44 excluding row and column k
	Matrix33(const Matrix44<Scalar> & m, const int & k) : Base(m.minor(k,k)) {}

	template<typename OtherDerived>
	Matrix33(const Eigen::MatrixBase<OtherDerived>& other) : Base(other) {}

	/*! \deprecated use *this.row(i) */
	inline typename Base::RowXpr operator[](const unsigned int i)
	{ return Base::row(i); }

	/*! \deprecated use *this.row(i) */
	inline const typename Base::RowXpr operator[](const unsigned int i) const
	{ return Base::row(i); }

	/** \deprecated */
	Matrix33 & SetRotateRad(Scalar angle, const Point3<Scalar> & axis )
	{
		*this = Eigen::AngleAxis<Scalar>(angle,axis).toRotationMatrix();
		return (*this);
	}
	/** \deprecated */
	Matrix33 & SetRotateDeg(Scalar angle, const Point3<Scalar> & axis ){
		return SetRotateRad(math::ToRad(angle),axis);
	}

  // Warning, this Inversion code can be HIGHLY NUMERICALLY UNSTABLE!
  // In most case you are advised to use the Invert() method based on SVD decomposition.
  /** \deprecated */
	Matrix33 & FastInvert() { return  *this = Base::inverse(); }

	void show(FILE * fp)
	{
		for(int i=0;i<3;++i)
		    printf("| %g \t%g \t%g |\n",coeff(i,0),coeff(i,1),coeff(i,2));
	}

	/** \deprecated use a * b.transpose()
	compute the matrix generated by the product of a * b^T
	*/
	// hm.... this is the outer product
	void ExternalProduct(const Point3<Scalar> &a, const Point3<Scalar> &b) { *this = a * b.transpose(); }

	/** Compute the Frobenius Norm of the Matrix */
	Scalar Norm() { return Base::cwise().abs2().sum(); }
// 	{
// 		// FIXME looks like there was a bug: j is not used !!!
// 		Scalar SQsum=0;
// 		for(int i=0;i<3;++i)
// 			for(int j=0;j<3;++j)
// 				SQsum += a[i]*a[i];
// 		return (math::Sqrt(SQsum));
// 	}


	/** Computes the  covariance matrix of a set of 3d points. Returns the barycenter.
	*/
	// FIXME should be outside Matrix
	template <class STLPOINTCONTAINER >
	void Covariance(const STLPOINTCONTAINER &points, Point3<Scalar> &bp) {
		assert(!points.empty());
		typedef typename  STLPOINTCONTAINER::const_iterator PointIte;
		// first cycle: compute the barycenter
		bp.setZero();
		for( PointIte pi = points.begin(); pi != points.end(); ++pi) bp+= (*pi);
		bp/=points.size();
		// second cycle: compute the covariance matrix
		this->setZero();
		vcg::Matrix33<ScalarType> A;
		for( PointIte pi = points.begin(); pi != points.end(); ++pi) {
				Point3<Scalar> p = (*pi)-bp;
				A.OuterProduct(p,p);
				(*this)+= A;
		}
	}

	/**
	It computes the cross covariance matrix of two set of 3d points P and X;
	it returns also the barycenters of P and X.
	fonte:

	Besl, McKay
	A method for registration o f 3d Shapes
	IEEE TPAMI Vol 14, No 2 1992

	*/
	// FIXME should be outside Matrix
	template <class STLPOINTCONTAINER >
	void CrossCovariance(const STLPOINTCONTAINER &P, const STLPOINTCONTAINER &X,
											Point3<Scalar> &bp, Point3<Scalar> &bx)
	{
		setZero();
		assert(P.size()==X.size());
		bx.setZero();
		bp.setZero();
		Matrix33<Scalar> tmp;
		typename std::vector <Point3<Scalar> >::const_iterator pi,xi;
		for(pi=P.begin(),xi=X.begin();pi!=P.end();++pi,++xi){
			bp+=*pi;
			bx+=*xi;
			tmp.ExternalProduct(*pi,*xi);
			(*this)+=tmp;
		}
		bp/=P.size();
		bx/=X.size();
		(*this)/=P.size();
		tmp.ExternalProduct(bp,bx);
		(*this)-=tmp;
	}

	template <class STLPOINTCONTAINER, class STLREALCONTAINER>
	void WeightedCrossCovariance(const STLREALCONTAINER &  weights,
								const STLPOINTCONTAINER &P,
								const STLPOINTCONTAINER &X,
								Point3<Scalar> &bp,
								Point3<Scalar> &bx)
	{
		setZero();
		assert(P.size()==X.size());
		bx.SetZero();
		bp.SetZero();
		Matrix33<Scalar> tmp;
		typename std::vector <Point3<Scalar> >::const_iterator pi,xi;
		typename STLREALCONTAINER::const_iterator pw;

		for(pi=P.begin(),xi=X.begin();pi!=P.end();++pi,++xi){
			bp+=(*pi);
			bx+=(*xi);
		}
		bp/=P.size();
		bx/=X.size();

		for(pi=P.begin(),xi=X.begin(),pw = weights.begin();pi!=P.end();++pi,++xi,++pw){

			tmp.ExternalProduct(((*pi)-(bp)),((*xi)-(bp)));

			(*this)+=tmp*(*pw);
		}
	}
};

template <class S>
void Invert(Matrix33<S> &m) { m = m.lu().inverse(); }

template <class S>
Matrix33<S> Inverse(const Matrix33<S>&m) { return m.lu().inverse(); }

///given 2 vector centered into origin calculate the rotation matrix from first to the second
template <class S>
Matrix33<S> RotationMatrix(vcg::Point3<S> v0,vcg::Point3<S> v1,bool normalized=true)
	{
		typedef typename vcg::Point3<S> CoordType;
		Matrix33<S> rotM;
		const S epsilon=0.00001;
		if (!normalized)
		{
			v0.Normalize();
			v1.Normalize();
		}
		S dot=v0.dot(v1);
		///control if there is no rotation
		if (dot>((S)1-epsilon))
		{
			rotM.SetIdentity();
			return rotM;
		}

		///find the axis of rotation
		CoordType axis;
		axis=v0^v1;
		axis.Normalize();

		///construct rotation matrix
		S u=axis.X();
		S v=axis.Y();
		S w=axis.Z();
		S phi=acos(dot);
		S rcos = cos(phi);
		S rsin = sin(phi);

		rotM[0][0] =      rcos + u*u*(1-rcos);
		rotM[1][0] =  w * rsin + v*u*(1-rcos);
		rotM[2][0] = -v * rsin + w*u*(1-rcos);
		rotM[0][1] = -w * rsin + u*v*(1-rcos);
		rotM[1][1] =      rcos + v*v*(1-rcos);
		rotM[2][1] =  u * rsin + w*v*(1-rcos);
		rotM[0][2] =  v * rsin + u*w*(1-rcos);
		rotM[1][2] = -u * rsin + v*w*(1-rcos);
		rotM[2][2] =      rcos + w*w*(1-rcos);

		return rotM;
	}

///return the rotation matrix along axis
template <class S>
Matrix33<S> RotationMatrix(const vcg::Point3<S> &axis,
						   const float &angleRad)
	{
		vcg::Matrix44<S> matr44;
		vcg::Matrix33<S> matr33;
		matr44.SetRotate(angleRad,axis);
		for (int i=0;i<3;i++)
			for (int j=0;j<3;j++)
				matr33[i][j]=matr44[i][j];
		return matr33;
	}

/// return a random rotation matrix, from the paper:
/// Fast Random Rotation Matrices, James Arvo
/// Graphics Gems III pp. 117-120
template <class S>
 Matrix33<S> RandomRotation(){
	S x1,x2,x3;
	Matrix33<S> R,H,M,vv;
	Point3<S> v;
	R.SetIdentity();
	H.SetIdentity();
	x1 = rand()/S(RAND_MAX);
	x2 = rand()/S(RAND_MAX);
	x3 = rand()/S(RAND_MAX);

	R[0][0] =		cos(S(2)*M_PI*x1);
	R[0][1] =		sin(S(2)*M_PI*x1);
	R[1][0] = -	R[0][1];
	R[1][1] =		R[0][0];

	v[0] = cos(2.0 * M_PI * x2)*sqrt(x3);
	v[1] = sin(2.0 * M_PI * x2)*sqrt(x3);
	v[2] = sqrt(1-x3);

	vv.OuterProduct(v,v);
	H -= vv*S(2);
	M = H*R*S(-1);
	return M;
}

///
typedef Matrix33<short>  Matrix33s;
typedef Matrix33<int>    Matrix33i;
typedef Matrix33<float>  Matrix33f;
typedef Matrix33<double> Matrix33d;

} // end of namespace

#endif

#endif