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

/* quadtrans.c
 *
 * Perform various transformations on quadrics.
 */

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

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


/* QuadricTransform
 *
 * Apply transformation matrix to quadric.
 */

quadric_t *
QuadricTransform(quadric, matrix)
quadric_t	*quadric;
matrix_t	*matrix;
{
	matrix_t	*transposed, *quad_matrix;

	quad_matrix = QuadricMatrix(quadric);
	transposed  = MatrixTranspose(MatrixNull, matrix);

	MatrixMul(quad_matrix, matrix, quad_matrix);
	MatrixMul(quad_matrix, quad_matrix, transposed);
	MatrixFree(transposed);
	QuadricNorm(quadric);

	return(quadric);
}


/* QuadricT
 *
 * Translate quadric by (a, b, c).
 */

quadric_t *
QuadricT(q, a, b, c)
quadric_t	*q;
real_t		a, b, c;
{
	matrix_t	*m;

	m = MatrixT1(a, b, c);
	q = QuadricTransform(q, m);
	MatrixFree(m);

	return(q);
}


/* QuadricS
 *
 * Scale quadric by (a, b, c).
 */

quadric_t *
QuadricS(q, a, b, c)
quadric_t	*q;
real_t		a, b, c;
{
	matrix_t	*m;

	m = MatrixS1(a, b, c);
	q = QuadricTransform(q, m);
	MatrixFree(m);

	return(q);
}


/* QuadricRx
 *
 * Rotate about the x-axis by t radians.
 */

quadric_t *
QuadricRx(q, t)
quadric_t	*q;
real_t		t;
{
	matrix_t	*m;

	m = MatrixRx1(t);
	q = QuadricTransform(q, m);
	MatrixFree(m);

	return(q);
}


/* QuadricRy
 *
 * Rotate about the y-axis by t radians.
 */

quadric_t *
QuadricRy(q, t)
quadric_t	*q;
real_t		t;
{
	matrix_t	*m;

	m = MatrixRy1(t);
	q = QuadricTransform(q, m);
	MatrixFree(m);

	return(q);
}


/* QuadricRz
 *
 * Rotate about the z-axis by t radians.
 */

quadric_t *
QuadricRz(q, t)
quadric_t	*q;
real_t		t;
{
	matrix_t	*m;

	m = MatrixRz1(t);
	q = QuadricTransform(q, m);
	MatrixFree(m);

	return(q);
}


/* QuadricSHx
 *
 * Shear quadric in y and z directions.
 */

quadric_t *
QuadricSHx(q, y, z)
quadric_t	*q;
real_t		y, z;
{
	matrix_t	*m;

	m = MatrixSHx1(y, z);
	q = QuadricTransform(q, m);
	MatrixFree(m);

	return(q);
}


/* QuadricSHy
 *
 * Shear quadric in x and z directions.
 */

quadric_t *
QuadricSHy(q, x, z)
quadric_t	*q;
real_t		x, z;
{
	matrix_t	*m;

	m = MatrixSHy1(x, z);
	q = QuadricTransform(q, m);
	MatrixFree(m);

	return(q);
}


/* QuadricSHz
 *
 * Shear quadric in x and y directions.
 */

quadric_t *
QuadricSHz(q, x, y)
quadric_t	*q;
real_t		x, y;
{
	matrix_t	*m;

	m = MatrixSHz1(x, y);
	q = QuadricTransform(q, m);
	MatrixFree(m);

	return(q);
}
