fix in eigen vector

This commit is contained in:
Luc 2018-08-19 04:56:27 +02:00
parent c06fe4c3eb
commit 3ecdb295b5

View File

@ -1254,66 +1254,74 @@ sweet_matrix_solve3 (mat3 * m, vec3 * v)
return 0; return 0;
} }
static int is_identity (mat3 * m) static int is_diagonal (mat3 * m)
{ {
if (!sweet_math_approx_equals (m->v[0], 1.0, EPSILON)) { return 0; }
if (!sweet_math_approx_equals (m->v[1], 0.0, EPSILON)) { return 0; } if (!sweet_math_approx_equals (m->v[1], 0.0, EPSILON)) { return 0; }
if (!sweet_math_approx_equals (m->v[2], 0.0, EPSILON)) { return 0; } if (!sweet_math_approx_equals (m->v[2], 0.0, EPSILON)) { return 0; }
if (!sweet_math_approx_equals (m->v[3], 0.0, EPSILON)) { return 0; } if (!sweet_math_approx_equals (m->v[3], 0.0, EPSILON)) { return 0; }
if (!sweet_math_approx_equals (m->v[4], 1.0, EPSILON)) { return 0; }
if (!sweet_math_approx_equals (m->v[5], 0.0, EPSILON)) { return 0; } if (!sweet_math_approx_equals (m->v[5], 0.0, EPSILON)) { return 0; }
if (!sweet_math_approx_equals (m->v[6], 0.0, EPSILON)) { return 0; } if (!sweet_math_approx_equals (m->v[6], 0.0, EPSILON)) { return 0; }
if (!sweet_math_approx_equals (m->v[7], 0.0, EPSILON)) { return 0; } if (!sweet_math_approx_equals (m->v[7], 0.0, EPSILON)) { return 0; }
if (!sweet_math_approx_equals (m->v[8], 1.0, EPSILON)) { return 0; }
return 1; return 1;
} }
static void get_eigen_vector (vec3 * v, mat3 * a, float h) static int col_n_zero (mat3 * m, int i)
{ {
char free_value; i = i * 3;
a->v[0] = a->v[0] - h; return (sweet_math_approx_equals (m->v[i], 0, EPSILON) &&
a->v[4] = a->v[4] - h; sweet_math_approx_equals (m->v[i+1], 0, EPSILON) &&
a->v[8] = a->v[8] - h; sweet_math_approx_equals (m->v[i+2], 0, EPSILON));
}
static int row_n_zero (mat3 * m, int i)
{
return (sweet_math_approx_equals (m->v[i], 0, EPSILON) &&
sweet_math_approx_equals (m->v[i+3], 0, EPSILON) &&
sweet_math_approx_equals (m->v[i+6], 0, EPSILON));
}
static void get_eigen_vector (vec3 * v, mat3 a, float h)
{
a.v[0] = a.v[0] - h;
a.v[4] = a.v[4] - h;
a.v[8] = a.v[8] - h;
v->x = 0; v->x = 0;
v->y = 0; v->y = 0;
v->z = 0; v->z = 0;
free_value = 0;
sweet_matrix_gaussian_elimination3 (a, v); sweet_matrix_gaussian_elimination3 (&a, v);
if (sweet_math_approx_equals (a->v[0], 0, EPSILON) && if (col_n_zero (&a, 0))
sweet_math_approx_equals (a->v[1], 0, EPSILON) &&
sweet_math_approx_equals (a->v[2], 0, EPSILON))
{
free_value = 1;
v->x = 1; v->x = 1;
} else if (col_n_zero(&a, 1))
if (sweet_math_approx_equals (a->v[3], 0, EPSILON) &&
sweet_math_approx_equals (a->v[4], 0, EPSILON) &&
sweet_math_approx_equals (a->v[5], 0, EPSILON))
{
free_value = 1;
v->y = 1; v->y = 1;
} else if (col_n_zero(&a, 2))
if (sweet_math_approx_equals (a->v[6], 0, EPSILON) &&
sweet_math_approx_equals (a->v[7], 0, EPSILON) &&
sweet_math_approx_equals (a->v[8], 0, EPSILON))
{
free_value = 1;
v->z = 1; v->z = 1;
} else
{
if (!free_value && if (sweet_math_approx_equals (a.v[2], 0, EPSILON) &&
sweet_math_approx_equals (a->v[2], 0, EPSILON) && sweet_math_approx_equals (a.v[5], 0, EPSILON))
sweet_math_approx_equals (a->v[5], 0, EPSILON) && {
sweet_math_approx_equals (a->v[8], 0, EPSILON)) if (sweet_math_approx_equals (a.v[8], 0, EPSILON))
{ {
v->z = 1; v->z = 1;
v->y = - a->v[7]; v->y = - a.v[7];
v->x = - a->v[3] * v->y - a->v[6]; v->x = (-v->y * a.v[3] - a.v[6]);
}
else
{
v->z = 0;
v->y = 1;
v->x = (-a.v[3]);
}
}
else if (row_n_zero (&a, 1))
{
v->y = 1;
v->z = 0;
v->x = (-v->y * a.v[3]);
}
} }
*v = sweet_vector_normalize3 (*v); *v = sweet_vector_normalize3 (*v);
} }
@ -1326,7 +1334,7 @@ sweet_matrix_eigen_vector3 (vec3 * vectors, mat3 * m)
int n; int n;
float h1, h2, h3; float h1, h2, h3;
if (is_identity (m)) if (is_diagonal (m))
{ {
vectors[0] = sweet_vector_new3 (1,0,0); vectors[0] = sweet_vector_new3 (1,0,0);
vectors[1] = sweet_vector_new3 (0,1,0); vectors[1] = sweet_vector_new3 (0,1,0);
@ -1337,16 +1345,16 @@ sweet_matrix_eigen_vector3 (vec3 * vectors, mat3 * m)
n = sweet_matrix_eigen_value3 (&h1, &h2, &h3, m); n = sweet_matrix_eigen_value3 (&h1, &h2, &h3, m);
/* vector associated with h1 */ /* vector associated with h1 */
a = *m; get_eigen_vector (&vectors[0], *m, h1);
get_eigen_vector (&vectors[0], &a, h1);
/* vector associated with h2 */ /* vector associated with h2 */
a = *m; get_eigen_vector (&vectors[1], *m, h2);
get_eigen_vector (&vectors[1], &a, h2);
/* vector associated with h3 */ /* vector associated with h3 */
a = *m; if (n > 2)
get_eigen_vector (&vectors[2], &a, h3); get_eigen_vector (&vectors[2], *m, h3);
else
vectors[2] = sweet_vector_cross (vectors[0], vectors[1]);
return n; return n;
} }