/*****
 * runtriple.in
 *
 * Runtime functions for triple operations.
 *
 *****/

triple   => primTriple()

#include "triple.h"
#include "path3.h"
#include "drawelement.h"

using namespace camp;

// Autogenerated routines:


triple :tripleZero()
{
  static triple zero;
  return zero;
}

triple :realRealRealToTriple(real x, real y, real z)
{
  return triple(x,y,z);
}

real xpart:tripleXPart(triple v)
{
  return v.getx();
}

real ypart:tripleYPart(triple v)
{
  return v.gety();
}

real zpart:tripleZPart(triple v)
{
  return v.getz();
}

triple Operator *(real x, triple v)
{
  return x*v;
}

triple Operator *(triple v, real x)
{
  return v*x;
}

triple /(triple v, real x)
{
  return v/x;
}

real length(triple v)
{
  return v.length();
}

real abs(triple v)
{
  return v.length();
}

real abs2(triple v)
{
  return abs2(v);
}

real polar(triple v, bool warn=true)
{
  return v.polar(warn);
}

real azimuth(triple v, bool warn=true)
{
  if(!warn && v.getx() == 0.0 && v.gety() == 0.0) return 0.0;
  return v.azimuth();
}

real colatitude(triple v, bool warn=true)
{
  if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) return 0.0;
  return degrees(v.polar());
}

real latitude(triple v, bool warn=true)
{
  if(!warn && v.getx() == 0.0 && v.gety() == 0.0 && v.getz() == 0.0) return 0.0;
  return 90.0-degrees(v.polar());
}

// Return the longitude of v in [0,360).
real longitude(triple v, bool warn=true)
{
  if(!warn && v.getx() == 0.0 && v.gety() == 0.0) return 0.0;
  return principalBranch(degrees(v.azimuth()));
}

triple unit(triple v)
{
  return unit(v);
}

real dot(triple u, triple v)
{
  return dot(u,v);
}

triple cross(triple u, triple v)
{
  return cross(u,v);
}

triple dir(explicit triple z)
{
  return unit(z);
}

triple expi(real polar, real azimuth)
{
  return expi(polar,azimuth);
}

triple dir(real colatitude, real longitude)
{
  return expi(radians(colatitude),radians(longitude));
}

triple realmult(triple u, triple v)
{
  return triple (u.getx()*v.getx(),u.gety()*v.gety(),u.getz()*v.getz());
}

// Return the component of vector v perpendicular to a unit vector u.
triple perp(triple v, triple u)
{
  return perp(v,u);
}

triple bezier(triple a, triple b, triple c, triple d, real t)
{
  real onemt=1-t;
  real onemt2=onemt*onemt;
  return onemt2*onemt*a+t*(3.0*(onemt2*b+t*onemt*c)+t*t*d);
}

triple bezierP(triple a, triple b, triple c, triple d, real t)
{
  return 3.0*(t*t*(d-a+3.0*(b-c))+t*(2.0*(a+c)-4.0*b)+b-a);
}

triple bezierPP(triple a, triple b, triple c, triple d, real t)
{
  return 6.0*(t*(d-a+3.0*(b-c))+a+c)-12.0*b;
}

triple bezierPPP(triple a, triple b, triple c, triple d)
{
  return 6.0*(d-a)+18.0*(b-c);
}

