#ifndef lint
static char *sccsid = "@(#)transforms.c	1.1 (Steve Hill) 3/9/90";
#endif

/* transforms.c
 *
 * This module contains a number of transformation matrices.
 */

#include <stdio.h>
#include <math.h>

#include "basetype.h"
#include "matrix.h"
#include "cartesian.h"
#include "point.h"
#include "vector.h"
#include "quadric.h"
#include "transforms.h"


/* MatrixT
 *
 * Translation matrix - translates by (a, b, c).
 */

matrix_t *
MatrixT(a, b, c)
real_t	a, b, c;
{
	matrix_t	*m;

	m = MatrixId(4);

	MatrixSet(m, 3, 0, a);
	MatrixSet(m, 3, 1, b);
	MatrixSet(m, 3, 2, c);

	return(m);
}

/* MatrixT1
 *
 * Inverse translation matrix.
 */

matrix_t *
MatrixT1(a, b, c)
real_t	a, b, c;
{
	return(MatrixT(-a, -b, -c));
}


/* MatrixS
 *
 * Scaling matrix - scales by factors (a, b, c).
 */

matrix_t *
MatrixS(a, b, c)
real_t	a, b, c;
{
	matrix_t	*m;

	m = Matrix(4, 4, (real_t *) NULL);

	MatrixSet(m, 0, 0, a);
	MatrixSet(m, 1, 1, b);
	MatrixSet(m, 2, 2, c);
	MatrixSet(m, 3, 3, REAL_ONE);

	return(m);
}

/* MatrixS1
 *
 * Inverse scaling matrix.
 */

matrix_t *
MatrixS1(a, b, c)
real_t	a, b, c;
{
	return(MatrixS((real_t) (REAL_ONE / a),
		       (real_t) (REAL_ONE / b),
		       (real_t) (REAL_ONE / c)));
}


/* MatrixRx
 *
 * Rotation about the x-axis by t radians.
 */

matrix_t *
MatrixRx(t)
real_t	t;
{
	matrix_t	*m;
	real_t		s, c;

	m = MatrixId(4);

	s = (real_t) sin((double) t); /* make fast versions later */
	c = (real_t) cos((double) t);

	MatrixSet(m, 1, 1, c);
	MatrixSet(m, 2, 2, c);
	MatrixSet(m, 2, 1, -s);
	MatrixSet(m, 1, 2, s);

	return(m);
}

/* MatrixRx1
 *
 * Inverse rotation around x-axis.
 */

matrix_t *
MatrixRx1(t)
real_t	t;
{
	return(MatrixRx(-t));
}


/* MatrixRy
 *
 * Rotation about the y-axis by t radians.
 */

matrix_t *
MatrixRy(t)
real_t	t;
{
	matrix_t	*m;
	real_t		s, c;

	m = MatrixId(4);

	s = (real_t) sin((double) t); /* make fast versions later */
	c = (real_t) cos((double) t);

	MatrixSet(m, 0, 0, c);
	MatrixSet(m, 2, 2, c);
	MatrixSet(m, 2, 0, -s);
	MatrixSet(m, 0, 2, s);

	return(m);
}

/* MatrixRy1
 *
 * Inverse rotation around y-axis
 */

matrix_t *
MatrixRy1(t)
real_t	t;
{
	return(MatrixRy(-t));
}


/* MatrixRz
 *
 * Rotation around the z-axis by t radians.
 */

matrix_t *
MatrixRz(t)
real_t	t;
{
	matrix_t	*m;
	real_t		s, c;

	m = MatrixId(4);

	s = (real_t) sin((double) t); /* make fast versions later */
	c = (real_t) cos((double) t);

	MatrixSet(m, 0, 0, c);
	MatrixSet(m, 1, 1, c);
	MatrixSet(m, 1, 0, -s);
	MatrixSet(m, 0, 1, s);

	return(m);
}

/* MatrixRz1
 *
 * Inverse rotation about the z-axis.
 */

matrix_t *
MatrixRz1(t)
real_t	t;
{
	return(MatrixRz(-t));
}


/* MatrixSHx
 *
 * Shear in y and z directions.
 */

matrix_t *
MatrixSHx(y, z)
real_t	y, z;
{
	matrix_t	*m;

	m = MatrixId(4);

	MatrixSet(m, 0, 1, y);
	MatrixSet(m, 0, 2, z);

	return(m);
}

/* MatrixSHx1
 *
 * Inverse x-shear matrix.
 */

matrix_t *
MatrixSHx1(y, z)
real_t	y, z;
{
	return(MatrixSHx(-y, -z));
}


/* MatrixSHy
 *
 * Shear in x and z directions.
 */

matrix_t *
MatrixSHy(x, z)
real_t	x, z;
{
	matrix_t	*m;

	m = MatrixId(4);

	MatrixSet(m, 1, 0, x);
	MatrixSet(m, 1, 2, z);

	return(m);
}

/* MatrixSHy1
 *
 * Inverse y-shear matrix.
 */

matrix_t *
MatrixSHy1(x, z)
real_t	x, z;
{
	return(MatrixSHy(-x, -z));
}


/* MatrixSHz
 *
 * Shear in x and y directions.
 */

matrix_t *
MatrixSHz(x, y)
real_t	x, y;
{
	matrix_t	*m;

	m = MatrixId(4);

	MatrixSet(m, 2, 0, x);
	MatrixSet(m, 2, 1, y);

	return(m);
}

/* MatrixSHz1
 *
 * Inverse z-shear matrix.
 */

matrix_t *
MatrixSHz1(x, y)
real_t	x, y;
{
	return(MatrixSHz(-x, -y));
}
