// This is a part of the Object Oriented Mathematical Library
// Copyright (C) 1999-2008 Renishaw plc
//
// This source file is the confidential property of Renishaw plc.
// Reproduction or transmission in whole or in part, in any form or
// by any means, electronic, mechanical or otherwise, is prohibited
// without the prior written consent of the copyright owner.
//
// objtrigo.h -- trigonometric objects


// ========================================================================================================================
#ifndef __OBJTRIGO_H__
#define __OBJTRIGO_H__

#include "OOMathsExport.h"

#include "objgeome.h"

// ========================================================================================================================
////////////////////////////////////////////////////////////////////////////////
// CMaTrigonometry - math library trigonometry (abstract base class)

class OOMATHS_API CMaTrigonometry : public CMaObject
{
public:
// destructor
   virtual ~CMaTrigonometry();

protected:
// constructor
   CMaTrigonometry();
};

// ========================================================================================================================
////////////////////////////////////////////////////////////////////////////////
// CMaCosineCurve - math library cosine curve (concrete class)

// formula: y = a * cos (b * x + c)
//
// note: when it represents a periodic motion, a, b and c are termed as amplitude,
//    angular frequency and phase angle of the motion.

class OOMATHS_API CMaCosineCurve : public CMaTrigonometry
{
public:
// constructor
   CMaCosineCurve(double amplitude = 1.0, double frequency = 1.0, double phase = 0.0);

// attributes
   double GetAmplitude() const;
   double GetFrequency() const;
   double GetPhase() const;
   void GetData(double* amplitude, double* frequency, double* phase) const;

// operations
   // curve location
   void GetPosition(CMaPoint* origin, CMaVector* xaxis, CMaVector* zaxis) const;
   void SetPosition(const CMaPoint& origin, const CMaVector& xaxis, const CMaVector& zaxis);

   // least-squares fitting: closest fit
   void Fit(const CMaPointArray& points);
   void Fit(const CMaPointArray& points, double* sqrErrors);
   void Fit(const CMaPointArray& points, double* sqrErrors, CMaDoubleArray* residuals);

   // conversions
   CMaPolyline   ToPolyline  (int size, double x1, double x2) const;   // size > 1, x1 < x2
   CMaPointArray ToPointArray(int size, double x1, double x2) const;

private:
// implementation
   double m_A, m_B, m_C;   // curve parameters
   CMaPoint  m_cOrigin;    // data coordinate system
   CMaVector m_cXaxis;
   CMaVector m_cZaxis;
};

// ========================================================================================================================
////////////////////////////////////////////////////////////////////////////////
// CMaSineCurve - math library sine curve (concrete class)

// formula: y = a * sin (b * x + c)
//
// note: when it represents a periodic motion, a, b and c are termed as amplitude,
//    angular frequency and phase angle of the motion.

class OOMATHS_API CMaSineCurve : public CMaTrigonometry
{
public:
// constructor
   CMaSineCurve(double amplitude = 1.0, double frequency = 1.0, double phase = 0.0);

// attributes
   double GetAmplitude() const;
   double GetFrequency() const;
   double GetPhase() const;
   void GetData(double* amplitude, double* frequency, double* phase) const;

// operations
   // curve location
   void GetPosition(CMaPoint* origin, CMaVector* xaxis, CMaVector* zaxis) const;
   void SetPosition(const CMaPoint& origin, const CMaVector& xaxis, const CMaVector& zaxis);

   // least-squares fitting: closest fit
   void Fit(const CMaPointArray& points);
   void Fit(const CMaPointArray& points, double* sqrErrors);
   void Fit(const CMaPointArray& points, double* sqrErrors, CMaDoubleArray* residuals);

   // conversions
   CMaPolyline   ToPolyline  (int size, double x1, double x2) const;   // size > 1, x1 < x2
   CMaPointArray ToPointArray(int size, double x1, double x2) const;

private:
// implementation
   double m_A, m_B, m_C;   // curve parameters
   CMaPoint  m_cOrigin;    // data coordinate system
   CMaVector m_cXaxis;
   CMaVector m_cZaxis;
};

// ========================================================================================================================
////////////////////////////////////////////////////////////////////////////////
// CMaTriag - math library triangular trigonometric function (concrete class)

class OOMATHS_API CMaTriag : public CMaTrigonometry
{
public:
// constructor
   CMaTriag(int degree = 0);                   // degree >= 0

// destructor
   ~CMaTriag();

// attribute
   int GetDegree() const;

// operations
   // assignment (auto) and data element
   double& Element(int i, int j);              // element [i][j], i+j <= degree
   double  Element(int i, int j) const;
   double  GetElement(int i, int j) const;
   void    SetElement(int i, int j, double value);

   // comparison
   EMaBoolean IsZero(double tolerance = MaGetZero()) const;
   EMaBoolean IsValueZero(double tolerance = MaGetZero()) const;

   // arithmetic
   CMaTriag operator+ (const CMaTriag& other) const;
   CMaTriag operator- (const CMaTriag& other) const;
   CMaTriag operator* (const CMaTriag& other) const;
   CMaTriag operator* (double number) const;
   CMaTriag operator/ (double number) const;

   CMaTriag operator- () const;

   // other related calculation
   double MaxElement() const;                  // largest absolute value
   double ValueAt(double t) const;             // t in radians
   void Simplify(double tolerance = MaGetZero());   // make sure coefficient A[N, N-i] != 0

private:
// implementation
   int       m_nN;   // degree of triag
   CMaMatrix m_cA;   // coefficients A[N+1, N+1]
};

// ========================================================================================================================
////////////////////////////////////////////////////////////////////////////////
// CMaTriagEqu - math library triag equation (concrete class)

class OOMATHS_API CMaTriagEqu : public CMaTrigonometry
{
public:
// constructor
   CMaTriagEqu();

// destructor
   ~CMaTriagEqu();

// attributes
   int GetNumberRoots() const;
   CMaDoubleArray GetRoots() const;            // roots in radians

// operation
   void Solve(const CMaTriag& p);              // solve p = 0, p's degree > 0

private:
// implementation
   // default copy constructor and assignment disabled
   CMaTriagEqu(const CMaTriagEqu&);
   void operator=(const CMaTriagEqu&);

   int     m_nN;       // number of roots
   double* m_pRoots;   // roots[N]
};

// ========================================================================================================================
////////////////////////////////////////////////////////////////////////////////
// CMaTriagpolynomial - math library triag polynomial (concrete class)

class OOMATHS_API CMaTriagPolynomial : public CMaTrigonometry
{
public:
// constructors
   CMaTriagPolynomial(int degree = 0);                    // degree >= 0
   CMaTriagPolynomial(const CMaTriagPolynomial& other);   // copy

// destructor
   ~CMaTriagPolynomial();

// attribute
   int GetDegree() const;

// operations
   // assignment and data element
   CMaTriagPolynomial& operator= (const CMaTriagPolynomial& other);
   CMaTriag& operator[] (int Index);                      // triag coefficient a[i]
   CMaTriag  operator[] (int Index) const;

   // comparison
   EMaBoolean IsZero(double tolerance = MaGetZero()) const;

   // other related calculation
   CMaPolynomial GetRealPolynomial(double t) const;       // t in radians
   void Simplify(double tolerance = MaGetZero());              // make sure A[N] != 0

private:
// implementation
   void Copy(const CMaTriagPolynomial& other);

   int       m_nN;   // degree of polynomial
   CMaTriag* m_pA;   // triag coefficients A[N+1]
};

// ========================================================================================================================

#endif // __OBJTRIGO_H__

// ========================================================================================================================
