#ifndef jbt_distance_h #define jbt_distance_h #include <jgl/jgl.h> class jbt_primitive; class jbt_distance { public: jbt_distance() : refcnt(0), kx(1), ky(1), kz(1) {} virtual ~jbt_distance() {}; void setScale( jFlt _kx, jFlt _ky, jFlt _kz ) { kx = _kx, ky = _ky, kz = _kz; } jFlt scaleX() const { return kx; } jFlt scaleY() const { return ky; } jFlt scaleZ() const { return kz; } virtual jFlt f( const jVec3& ); virtual jVec3 df(const jVec3&, jFlt ); virtual jgl_algebraic* expression( jgl_algebraic*, jgl_algebraic*, jgl_algebraic* ) const; static jbt_distance D; protected: jFlt kx,ky,kz; private: friend class jbt_primitive; friend class jbt_build; int refcnt; }; class jbt_lmetric_distance : public jbt_distance { public: jbt_lmetric_distance( jFlt _n ) : n(_n) { n_1 = 1.0/n; } jFlt f( const jVec3& ); jVec3 df( const jVec3&, jFlt ); jgl_algebraic* expression( jgl_algebraic*, jgl_algebraic*, jgl_algebraic* ) const; void setN( jFlt _n ) { n = _n, n_1 = 1.0/_n; } protected: jFlt n, n_1; }; class jbt_superquadric_distance : public jbt_distance { public: jbt_superquadric_distance( jFlt _ew = 2, jFlt _ns = 2, int _axis = 2 ) : ew(_ew), ns(_ns), axis(_axis) { ew_2 = 2.0/ew, ns_2 = 2.0/ns, ns_ew = ew/ns; } jFlt f( const jVec3& ); jVec3 df( const jVec3&, jFlt); // jgl_algebraic* equation() const; protected: jFlt ew,ns, ew_2, ns_2, ns_ew; int axis; }; class jbt_anisotropic_lmetric_distance : public jbt_lmetric_distance { public: jbt_anisotropic_lmetric_distance( const jNorm3& N, jFlt p0, jFlt p1, jFlt a = 0, jFlt b = 1); jFlt f( const jVec3& ); jVec3 df( const jVec3&, jFlt ); private: jNorm3 N; jFlt p0,p1,a,b; }; class jbt_anisotropic_superquadric_distance : public jbt_superquadric_distance { public: jbt_anisotropic_superquadric_distance( const jNorm3& N, jFlt ew0, jFlt ns0, jFlt ew1, jFlt ns1, int axis = 2, jFlt a = 0, jFlt b = 1); jFlt f( const jVec3& ); jVec3 df( const jVec3&, jFlt ); private: jNorm3 N; jFlt ew0,ns0,ew1,ns1; jFlt a,b; }; #endif