Esempio n. 1
0
	bool DiagonalizeMatrix(const mat3& m, mat3& res)
	{
		vec3 v;
		if (!EigenValues(m, v))
			return false;

		res.Identity();
		res[0] = v[0];
		res[4] = v[1];
		res[8] = v[2];

		return true;
	}
Esempio n. 2
0
	bool SymmetricEigenSystem(const mat3& m, vec3& value, mat3& r)
	{
		const int max_sweep = 32;
		const float epsilon = 1.0e-10f;
		float m11 = m.At(0,0);
		float m12 = m.At(0,1);
		float m13 = m.At(0,2);
		float m22 = m.At(1,1);
		float m23 = m.At(1,2);
		float m33 = m.At(2,2);

		r.Identity();

		for (int a = 0; a < max_sweep; ++a)
		{
			if ((Abs(m12) < epsilon) && (Abs(m13) < epsilon) && (Abs(m23) < epsilon))
				break;

			//	annihilate 1 2
			if (m12 != 0.0f)
			{
				float u = (m22 - m11) * 0.5f / m12;
				float u2 = u*u;
				float u2p1 = u2 + 1.0f;
				float t = (u2p1 != u2) ? ((u < 0.0f) ? -1.0f : 1.0f) * (sqrt(u2p1) - fabs(u)) : 0.5f / u;
				float c = 1.0f / sqrt(t*t + 1.0f);
				float s = c * t;

				m11 -= t * m12;
				m22 += t * m12;
				m12 = 0.0f;

				float temp = c*m13 - s * m23;
				m23 = s * m13 + c * m23;
				m13 = temp;

				for (int i = 0; i < 3; ++i)
				{
					float temp = c * r.At(i, 0) - s * r.At(i,1);
					r.At(i,1) = s * r.At(i,0) + c * r.At(i,1);
					r.At(i,0) = temp;
				}
			}

			//	annihilate 1 3
			if (m13 != 0.0f)
			{
				float u = (m33 - m11) * 0.5f / m13;
				float u2 = u*u;
				float u2p1 = u2 + 1.0f;
				float t = (u2p1 != u2) ? ((u < 0.0f) ? -1.0f : 1.0f) * (sqrt(u2p1) - fabs(u)) : 0.5f / u;
				float c = 1.0f / sqrt(t*t + 1.0f);
				float s = c * t;

				m11 -= t * m13;
				m33 += t * m13;
				m13 = 0.0f;

				float temp = c * m12 - s * m23;
				m23 = s * m12 + c * m23;
				m12 = temp;

				for (int i = 0; i < 3; ++i)
				{
					float temp = c * r.At(i, 0) - s * r.At(i, 2);
					r.At(i, 2) = s * r.At(i, 0) + c * r.At(i, 2);
					r.At(i, 0) = temp;
				}
			}

			//	annihilate 2 3
			if (m23 != 0.0f)
			{
				float u = (m33 - m22) * 0.5f / m23;
				float u2 = u*u;
				float u2p1 = u2 + 1.0f;
				float t = (u2p1 != u2) ? ((u < 0.0f) ? -1.0f : 1.0f) * (sqrt(u2p1) - fabs(u)) : 0.5f / u;
				float c = 1.0f / sqrt(t*t + 1.0f);
				float s = c * t;

				m22 -= t * m23;
				m33 += t * m23;
				m23 = 0.0f;

				float temp = c * m12 - s * m13;
				m13 = s * m12 + c * m13;
				m12 = temp;

				for (int i = 0; i < 3; ++i)
				{
					float temp = c * r.At(i, 1) - s * r.At(i, 2);
					r.At(i, 2) = s * r.At(i, 1) + c * r.At(i, 2);
					r.At(i, 1) = temp;
				}
			}
		}

		value.Set(m11, m22, m33);
		return true;
	}