39#include <visp3/core/vpMath.h>
41#ifndef DOXYGEN_SHOULD_SKIP_THIS
49 void fprintf_matrix(FILE *fp, Matrix m)
53 fprintf(fp,
"(matrix\n");
54 for (i = 0;
i < 4;
i++)
55 fprintf(fp,
"\t%.4f\t%.4f\t%.4f\t%.4f\n", m[i][0], m[i][1], m[i][2], m[i][3]);
64void ident_matrix(Matrix m)
66 static Matrix identity = IDENTITY_MATRIX;
69 memmove((
char *)m, (
char *)identity,
sizeof(Matrix));
87void premult_matrix(Matrix a, Matrix b)
92 for (i = 0;
i < 4;
i++)
93 for (j = 0;
j < 4;
j++)
94 m[i][j] = b[i][0] * a[0][j] + b[i][1] * a[1][j] + b[i][2] * a[2][j] + b[i][3] * a[3][j];
96 memmove((
char *)a, (
char *)m,
sizeof(Matrix));
106void premult3_matrix(Matrix a, Matrix b)
112 memmove((
char *)m, (
char *)a,
sizeof(Matrix));
113 for (i = 0;
i < 3;
i++)
114 for (j = 0;
j < 4;
j++)
115 a[i][j] = b[i][0] * m[0][j] + b[i][1] * m[1][j] + b[i][2] * m[2][j];
124void prescale_matrix(Matrix m, Vector *vp)
128 for (i = 0;
i < 4;
i++) {
141void pretrans_matrix(Matrix m, Vector *vp)
145 for (i = 0;
i < 4;
i++)
146 m[3][i] += vp->x * m[0][i] + vp->y * m[1][i] + vp->z * m[2][i];
156void postleft_matrix(Matrix m,
char axis)
163 for (i = 0;
i < 4;
i++)
167 for (i = 0;
i < 4;
i++)
171 for (i = 0;
i < 4;
i++)
175 static char proc_name[] =
"postleft_matrix";
176 fprintf(stderr,
"%s: axis unknown\n", proc_name);
188void postmult_matrix(Matrix a, Matrix b)
193 for (i = 0;
i < 4;
i++)
194 for (j = 0;
j < 4;
j++)
195 m[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j] + a[i][3] * b[3][j];
197 memmove((
char *)a, (
char *)m,
sizeof(Matrix));
207void postmult3_matrix(Matrix a, Matrix b)
213 memmove((
char *)m, (
char *)a,
sizeof(Matrix));
214 for (i = 0;
i < 4;
i++)
215 for (j = 0;
j < 3;
j++)
216 a[i][j] = m[i][0] * b[0][j] + m[i][1] * b[1][j] + m[i][2] * b[2][j];
225void postscale_matrix(Matrix m, Vector *vp)
229 for (i = 0;
i < 4;
i++) {
241void posttrans_matrix(Matrix m, Vector *vp)
245 for (i = 0;
i < 4;
i++) {
246 m[
i][0] += m[
i][3] * vp->x;
247 m[
i][1] += m[
i][3] * vp->y;
248 m[
i][2] += m[
i][3] * vp->z;
257void transpose_matrix(Matrix m)
262 for (i = 0;
i < 4;
i++)
263 for (j = 0;
j <
i;
j++)
264 SWAP(m[i][j], m[j][i], t);
275float cosin_to_angle(
float ca,
float sa)
279 if (FABS(ca) < M_EPSILON) {
280 a = (sa > 0.0f) ?
static_cast<float>(M_PI_2) :
static_cast<float>(-M_PI_2);
283 a =
static_cast<float>(atan(
static_cast<double>(sa / ca)));
285 a += (sa >0.0f) ?
static_cast<float>(M_PI) :
static_cast<float>(-M_PI);
298void cosin_to_lut(Index level,
float *coslut,
float *sinlut)
301 int i_pi_2 = TWO_POWER(level);
304 double step = M_PI_2 /
static_cast<double>(i_pi_2);
319 for (i = 1, a = step;
i < i_pi_2;
i++, a +=
step) {
320 float ca =
static_cast<float>(cos(a));
322 coslut[quad +
i] = ca;
324 sinlut[quad -
i] = ca;
325 sinlut[quad +
i] = ca;
327 coslut[quad -
i] = -ca;
328 coslut[quad +
i] = -ca;
330 sinlut[quad -
i] = -ca;
331 sinlut[quad +
i] = -ca;
333 coslut[quad -
i] = ca;
345float norm_vector(Vector *vp)
349 if ((norm =
static_cast<float>(sqrt(
static_cast<double>(DOT_PRODUCT(*vp, *vp))))) > M_EPSILON) {
355 static char proc_name[] =
"norm_vector";
356 fprintf(stderr,
"%s: nul vector\n", proc_name);
368void plane_norme(Vector *np, Point3f *ap, Point3f *bp, Point3f *cp)
372 DIF_COORD3(u, *bp, *ap)
373 DIF_COORD3(v, *cp, *ap)
376 CROSS_PRODUCT(*np, u, v);
387void point_matrix(Point4f *p4, Point3f *p3, Matrix m)
389 float x = p3->x,
y = p3->y,
z = p3->z;
391 p4->x = COORD3_COL(x, y, z, m, 0);
392 p4->y = COORD3_COL(x, y, z, m, 1);
393 p4->z = COORD3_COL(x, y, z, m, 2);
394 p4->w = COORD3_COL(x, y, z, m, 3);
405void point_3D_3D(Point3f *ip,
int size, Matrix m, Point3f *op)
407 Point3f *pend = ip + size;
409 for (; ip < pend; ip++, op++) {
414 op->x = COORD3_COL(x, y, z, m, 0);
415 op->y = COORD3_COL(x, y, z, m, 1);
416 op->z = COORD3_COL(x, y, z, m, 2);
427void point_3D_4D(Point3f *p3,
int size, Matrix m, Point4f *p4)
429 Point3f *pend = p3 + size;
431 for (; p3 < pend; p3++, p4++) {
436 p4->x = COORD3_COL(x, y, z, m, 0);
437 p4->y = COORD3_COL(x, y, z, m, 1);
438 p4->z = COORD3_COL(x, y, z, m, 2);
439 p4->w = COORD3_COL(x, y, z, m, 3);
451void rotate_vector(Vector *vp,
float a, Vector *axis)
453 Vector n,
u,
v, cross;
456 a *=
static_cast<float>(M_PI) / 180.0f;
471 f = DOT_PRODUCT(*vp, n);
473 MUL_COORD3(u, f, f, f)
475 DIF_COORD3(v, *vp, u)
477 f =
static_cast<float>(cos(
static_cast<double>(a)));
478 MUL_COORD3(v, f, f, f)
480 CROSS_PRODUCT(cross, n, *vp);
481 f =
static_cast<float>(sin(
static_cast<double>(a)));
482 MUL_COORD3(cross, f, f, f)
484 SET_COORD3(*vp,
u.x +
v.x + cross.x,
u.y +
v.y + cross.y,
u.z +
v.z + cross.z)
495void upright_vector(Vector *vp, Vector *up)
497 if (FABS(vp->z) > M_EPSILON) {
498 up->z = -(vp->x + vp->y) / vp->z;
501 else if (FABS(vp->y) > M_EPSILON) {
502 up->y = -(vp->x + vp->z) / vp->y;
505 else if (FABS(vp->x) > M_EPSILON) {
506 up->x = -(vp->y + vp->z) / vp->x;
510 static char proc_name[] =
"upright_vector";
511 up->x = up->y = up->z = 0.0;
512 fprintf(stderr,
"%s: nul vector\n", proc_name);
525void Matrix_to_Position(Matrix m, AritPosition *pp)
527 Matrix_to_Rotate(m, &pp->rotate);
528 SET_COORD3(pp->scale, 1.0, 1.0, 1.0)
529 SET_COORD3(pp->translate, m[3][0], m[3][1], m[3][2])
558void Matrix_to_Rotate(Matrix m, Vector *vp)
561 float cy =
static_cast<float>(sqrt(1.0 -
static_cast<double>(sy * sy)));
564 if (FABS(cy) > M_EPSILON) {
565 float sz = m[0][1] / cy;
566 float cz = m[0][0] / cy;
571 SET_COORD3(*vp, cosin_to_angle(cx, sx), cosin_to_angle(cy, sy), cosin_to_angle(cz, sz))
577 SET_COORD3(*vp, cosin_to_angle(cx, sx), (sy > 0.0f) ?
static_cast<float>(M_PI_2) :
static_cast<float>(-M_PI_2), 0.0f)
579 vp->x *= 180.0f /
static_cast<float>(M_PI);
580 vp->y *= 180.0f /
static_cast<float>(M_PI);
581 vp->z *= 180.0f /
static_cast<float>(M_PI);
591void Position_to_Matrix(AritPosition *pp, Matrix m)
593 Rotate_to_Matrix(&pp->rotate, m);
594 prescale_matrix(m, &pp->scale);
595 m[3][0] = pp->translate.x;
596 m[3][1] = pp->translate.y;
597 m[3][2] = pp->translate.z;
620void Rotate_to_Matrix(Vector *vp, Matrix m)
622 float rx = vp->x *
static_cast<float>(M_PI) / 180.0f;
623 float ry = vp->y *
static_cast<float>(M_PI) / 180.0f;
624 float rz = vp->z *
static_cast<float>(M_PI) / 180.0f;
625 float cx =
static_cast<float>(cos(
static_cast<double>(rx)));
626 float sx =
static_cast<float>(sin(
static_cast<double>(rx)));
627 float cy =
static_cast<float>(cos(
static_cast<double>(ry)));
628 float sy =
static_cast<float>(sin(
static_cast<double>(ry)));
629 float cz =
static_cast<float>(cos(
static_cast<double>(rz)));
630 float sz =
static_cast<float>(sin(
static_cast<double>(rz)));
633 m[1][0] = (sx * sy * cz) - (cx * sz);
634 m[2][0] = (cx * sy * cz) + (sx * sz);
637 m[1][1] = (sx * sy * sz) + (cx * cz);
638 m[2][1] = (cx * sy * sz) - (sx * cz);
644 m[0][3] = m[1][3] = m[2][3] = 0.0;
645 m[3][0] = m[3][1] = m[3][2] = 0.0;
672void Rotaxis_to_Matrix(
float a, Vector *axis, Matrix m)
681 a *=
static_cast<float>(M_PI) / 180.0f;
683 cosa =
static_cast<float>(cos(
static_cast<double>(a)));
684 sina =
static_cast<float>(sin(
static_cast<double>(a)));
690 MUL_COORD3(conv, vera, vera, vera)
691 MUL_COORD3(tilde, sina, sina, sina)
693 m[0][0] = conv.x * n.x + cosa;
694 m[0][1] = conv.x * n.y + tilde.z;
695 m[0][2] = conv.x * n.z - tilde.y;
697 m[1][0] = conv.y * n.x - tilde.z;
698 m[1][1] = conv.y * n.y + cosa;
699 m[1][2] = conv.y * n.z + tilde.x;
701 m[2][0] = conv.z * n.x + tilde.y;
702 m[2][1] = conv.z * n.y - tilde.x;
703 m[2][2] = conv.z * n.z + cosa;
705 m[0][3] = m[2][3] = m[1][3] = 0.0;
706 m[3][0] = m[3][1] = m[3][2] = 0.0;
718void Rotrans_to_Matrix(Vector *rp, Vector *tp, Matrix m)
720 Rotate_to_Matrix(rp, m);
732void Scale_to_Matrix(Vector *vp, Matrix m)
745void Translate_to_Matrix(Vector *vp, Matrix m)