/*
 * Jeffrey Ladino - jnl22@ccs.neu.edu
 *
 * File: transforms.cpp
 *
 * Change Log
 ************
 ** July 28, 1999 - Jeff Ladino
 * Created.
 *
 */

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

/* Identity
 */
matrix3d& Identity(){
  matrix3d *I = new matrix3d();
  for(int i=0;i<3;i++)
    for(int j=0;j<3;j++)
      if (i==j) I->data[i][j]=1;
      else I->data[i][j]=0;
  return *I;
}

/* Rotate
 *
 * counterclockwise rotation by theta radians
 */
matrix3d& Rotate(Real theta){
  matrix3d *R = new matrix3d();
  R->data[0][0] = cos(theta);
  R->data[0][1] = -sin(theta);
  R->data[1][1] = cos(theta);
  R->data[1][0] = sin(theta);
  R->data[2][2] = 1.0;
  R->data[0][2] = R->data[1][2] = R->data[2][0] = R->data[2][1] = 0.0;
  if(VERBOSITY > 1){
    printf("Rotate(%e) - cos(%e) = %e\n", theta, theta, cos(theta) );
    R->print();
  }
  return *R;
}

/* Rotate_about
 *
 * counterclockwise rotation by theta radians around the point
 * xc, yc
 *
 */
matrix3d& Rotate_about(Real theta, Real xp, Real yp){
  return Translate(xp, yp) * Rotate(theta) * Translate(-xp, -yp);
  //printf("Rotate_about(%e,%e,%e)\n",theta, xp, yp);
  //r->print();
}

/* Scale
 *
 * scale in the x and y directions
 */
matrix3d& Scale(matrix3d* S, Real x, Real y){
  //matrix3d *S = new matrix3d();
  for(int i=0;i<3;i++)
    for(int j=0;j<3;j++)
      S->data[i][j]=0;
  S->data[0][0] = x;
  S->data[1][1] = y;
  S->data[2][2] = 1.0;
  return *S;
}

/* Shear
 *
 * shear by Shx and Shy with respect to yref
 */
matrix3d& Shear(Real Shx, Real yref=0.0){
  matrix3d *S = new matrix3d();
  for(int i=0;i<3;i++)
    for(int j=0;j<3;j++)
      S->data[i][j]=0;

  S->data[0][0] = 1.0;
  S->data[0][1] = Shx;
  S->data[0][2] = yref * Shx;
  S->data[1][1] = 1.0;
  S->data[2][2] = 1.0;
  printf("\n Shear %e %e\n", Shx, yref);
  S->print();
  printf("\n");
  return *S;
}

/* Reflect_yeqx
 *
 * reflect through the line y=x
 */
matrix3d& Reflect_yeqx(){
  matrix3d *R = new matrix3d();
  for(int i=0;i<3;i++)
    for(int j=0;j<3;j++)
      R->data[i][j]=0;
  R->data[0][1] = 1.0;
  R->data[1][0] = 1.0;
  R->data[2][2] = 1.0;
  printf("\nReflect y=x\n");
  R->print();
  return *R;
}

/* Reflect_xaxis
 *
 * reflect through the x-axis
 */
matrix3d& Reflect_xaxis(){
  matrix3d *Rf = new matrix3d();
  for(int i=0;i<3;i++)
    for(int j=0;j<3;j++)
      if (i==j) Rf->data[i][j]=1.0;
      else Rf->data[i][j]=0.0;
  Rf->data[1][1] = -1.0;
  return *Rf;
}

/* Translate
 *
 * translate a point by x, y
 */
matrix3d& Translate(Real x, Real y){
  matrix3d *Tr = new matrix3d();
  for(int i=0;i<3;i++)
    for(int j=0;j<3;j++)
      if (i==j) Tr->data[i][j]=1.0;
      else Tr->data[i][j]=0.0;
  Tr->data[0][2] = x;
  Tr->data[1][2] = y;
  if(VERBOSITY > 1){
    printf("Translate(%e, %e)\n", x, y);
    Tr->print();
  }
  return *Tr;
}


