/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #ifndef _MGTolerance_HH_ #define _MGTolerance_HH_ /** @file */ /** @addtogroup BASE * @{ */ #include "mg/MGCL.h" /// Forward Declarations class MGIfstream; class MGOfstream; class MGEReal; // MGTolerance.h #define MG_MAX_TOL_STACK_SIZE 10 // Defines tolerance. // ///MGTolerance is a class to hold various tolerance data used in MGCL. ///Tolerances used are follows: ///(Out of these, wc_zero, line_zero are important. If not familiar, forget ///rc_zero, mach_zero, m_max_knot_ratio, and angle_zero. Defalut values will be OK.) ///(1) wc_zero(world coordinate zero value): ///Two points distance that should be regarded as coincidence in user's world coordinate. ///Typically, intersection of 2 curves are so computed that the i-points be within ///this tolerance. ///(2) line_zero(Line zero in world coordinates): ///Two curves distance that should be regarded as coincidence. ///line_zero>=wc_zero is recommended. ///(3) rc_zero(normalized relative coordinate zero): ///Two points distance that should be regarded as coincidence in normalized (0.,1.) space. ///This is used when the computation is ecexuted other than world coordinates, like ///in parameter space. ///Generally speaking, when the span of the world interedted is L, L*rc_zero=wc_zero. ///(4) angle_zero: Angle that should be regarded as zero angle in radian. ///Generally speaking, mgDBLPAI*rc_zero=angle_zero. ///(5) m_max_knot_ratio:Maximum ratio of neighboring two spans of a knot vector. ///This is used to stabilize the computation to solve linear equations for B-Spline coefficients. ///(6) mach_zero(machine zero): the smallest floating value to avoid exception of division zero. class MG_DLL_DECLR MGTolerance { private: MGTolerance(); MGTolerance(const MGTolerance&); MGTolerance& operator=(const MGTolerance&); public: ///String stream function. デバッグ関数. MG_DLL_DECLR friend std::ostream& operator << (std::ostream&, const MGTolerance& ); ///トレランスを考慮して与えられた double が 0 かどうか調べる. ///Test if data is machine zero. /// Machine Zero version MG_DLL_DECLR friend bool MGMZero (double data); ///トレランスを考慮して与えられた2つの double が一致するか調べる. ///等しい時 true(non zero) を返却する-----Absolute Version. ///Test if two double is equal in world coordinate. MG_DLL_DECLR friend bool MGAEqual (double data1, double data2); ///トレランスを考慮して与えられた値が0か調べる-----Absolute Version. ///Test if data is world coordinate zero. MG_DLL_DECLR friend bool MGAZero(double data); ///Test if difference of two data is less than MGTolerance::rc_zero(). MG_DLL_DECLR friend bool MGREqual (double data1, double data2); ///Test if difference of two data is less than MGTolerance::rc_zero(). ///Test is performed after changing data1 and data2 proportionally for the bigger one to be 1. MG_DLL_DECLR friend bool MGREqual2(double data1, double data2); ///Test if difference of two data is equal. ///Comparison is: ///test if abs(data1-data2)/base_length is less than MGTolerance::rc_zero(). MG_DLL_DECLR friend bool MGREqual_base(double data1, double data2, double base_length); MG_DLL_DECLR friend bool MGREqual_base(MGEReal data1, MGEReal data2, const MGEReal& base_length); ///Test if data is less or equal to rc_zero(). ///トレランスを考慮して与えられた値が0か調べる1-----Relative Version MG_DLL_DECLR friend bool MGRZero(double data); ///Test if data is less or equal to rc_zero() compared to base_length. ///トレランスを考慮して与えられた値が0か調べる2-----Relative Version ///Comparison is done after data and base_length are so changed ///that base_length is 1. ///If base_length is zero, MGRZero2 returns always false. MG_DLL_DECLR friend bool MGRZero2(double data, double base_length); MG_DLL_DECLR friend bool MGRZero2(double data, const MGEReal& base_length); ///Test if angle is right from the value cos(angle). /// 角度のコサイン値を入力して,角度が直角か調べる。 ///(トレランスを考慮する) MG_DLL_DECLR friend bool MGRight_angle(double cos_data); ///Test if data is zero angle taking tolerance into account. /// トレランスを考慮して与えられた角度(Radian) が0か調べる。 /// If data is small enough, data is almost equal to sin(data). /// This fact says we can use sine value instead of radian as data input. MG_DLL_DECLR friend bool MGZero_angle (double data); //////////// Destructor. 仮想デストラクタ //////////// ~MGTolerance(); //////////// Member function. メンバ関数 ////////// ///Get the tolerance instance. ///Returned is a singleton. static MGTolerance& instance(); //Update. 更新 ///Return currently used tolerance stack length. int stack_length() const{return m_count;}; ///Return maximum tolerance stack size. int max_stack_size() const{return MG_MAX_TOL_STACK_SIZE;}; ///Update m_mach_zero. Returned is old mach_zero used so far. ///m_mach_zeroを変更する。それまで使用されていたデータが返却される. static double set_mach_zero( double ); ///Update m_wc_zero. Returned is old wc_zero used so far. ///m_wc_zeroを変更する。それまで使用されていたデータが返却される。 static double set_wc_zero( double ); ///Update m_rc_zero. Returned is old rc_zero used so far. /// m_rc_zeroを変更する。それまで使用されていたデータが返却される。 static double set_rc_zero( double ); ///Update m_angle_zero. Returned is old angle_zero used so far. ///m_angle_zeroを変更する。それまで使用されていたデータが返却される。 static double set_angle_zero( double ); ///Update m_line_zero. Returned is old line_zero used so far. ///m_line_zeroを変更する。それまで使用されていたデータが返却される. static double set_line_zero( double ); ///Update m_max_knot_ratio. Returned is old max_knot_ratio used so far. ///m_max_knot_ratioを変更する。それまで使用されていたデータが返却される. static double set_max_knot_ratio( double ); ///Push all the tolerance to stack. static void push( ); ///Pop all the tolerance from stack. static void pop( ); //Reference. 参照 ///Return machine zero. static double mach_zero() {return instance().m_mach_zero;}; ///Return world zero. static double wc_zero() {return instance().m_wc_zero;}; ///Return square of world zero. static double wc_zero_sqr(){return instance().m_wc_zero_sqr;}; ///Return relative zero. static double rc_zero() {return instance().m_rc_zero;}; ///Return square of relative zero. static double rc_zero_sqr(){return instance().m_rc_zero_sqr;}; ///Return angle zero. static double angle_zero(){return instance().m_angle_zero;}; ///Return line zero. static double line_zero(){return instance().m_line_zero;}; ///Return maximum knot ratio. static double max_knot_ratio(){return instance().m_max_knot_ratio;}; ///Dump Functions. int dump_size() const; ///Dump Function. int dump(MGOfstream& ) const; ///Restore Function. int restore(MGIfstream& ); private: //////////// Memeber data. メンバデータ ////////// double m_mach_zero; ///< 有効値として割り算ができる最小の数値 ///= m_max_knot_ratio, t(i+1) and ///