/*****
* 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);
}