/* Vector routines for 3d-vectors */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "vector.h"

vector vassign(scalar x, scalar y, scalar z)
{
  vector v;
  v.x=x;
  v.y=y;
  v.z=z;
  return v;
}

vector vadd(vector u, vector v)
{
  v.x+=u.x;
  v.y+=u.y;
  v.z+=u.z;
  return v;
}

vector vsub(vector u, vector v)
{
  u.x-=v.x;
  u.y-=v.y;
  u.z-=v.z;
  return u;
}

vector smul(scalar k, vector v)
{
  return vassign(k*v.x,k*v.y,k*v.z);
}

scalar dot(vector u, vector v)
{
  return u.x*v.x + u.y*v.y + u.z*v.z;
}

scalar vdotv(vector v)
{
  return v.x*v.x + v.y*v.y + v.z*v.z;
}

vector cross(vector u, vector v)
{
  vector w;
  w.x=u.y*v.z-u.z*v.y;
  w.y=u.z*v.x-u.x*v.z;
  w.z=u.x*v.y-u.y*v.x;
  return w;
}

scalar norm(vector v)
{
  return sqrt(v.x*v.x+v.y*v.y+v.z*v.z);
}

vector unit(vector v)
{
  return smul(1.0/norm(v),v);
}

vector vneg(vector v)
{
  return vassign(-v.x,-v.y,-v.z);
}

vector zero(void)
{
  return vassign(0.0,0.0,0.0);
}

vector vrotate(vector v, vector y, vector z)
{
  vector x, rx, ry, rz;
  
  x=unit(cross(y, z));
  y=unit(y);
  z=cross(x, y);
  
  rx=smul(v.x, x);
  ry=smul(v.y, y);
  rz=smul(v.z, z);

  return vassign(rx.x+ry.x+rz.x, rx.y+ry.y+rz.y, rx.z+ry.z+rz.z);
}

#define EPSILON 0.001

int iszero(vector v)
{
  return abs(v.x)<EPSILON && abs(v.y)<EPSILON && abs(v.z)<EPSILON;
}

void vwrite(char *string1, vector v, char *string2)
{
  printf("%s(%.3lg,%.3lg,%.3lg)%s",string1,v.x,v.y,v.z,string2);
}

vector vread(char *string)
{
  vector v;
  printf("%s",string);
  scanf("%lf%lf%lf",&v.x,&v.y,&v.z);
  return v;
}

void swrite(char *string1, scalar s, char *string2)
{
  printf("%s%lf%s",string1,s,string2);
}

scalar sread(char *string)
{
  scalar s;
  printf("%s",string);
  scanf("%lf",&s);
  return s;
}
/* end */

