# pragma once
# include <algorithm>
# include <functional>
# include <chrono>
# include <ctime>
# include <iomanip>
# include "DrawOperator/RTree.h"
# include "VoronoiMap/InterfaceElements.h"
/**
* CList <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ list CList <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ pos POSITION <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ԫ <EFBFBD> ص <EFBFBD> λ <EFBFBD> ã <EFBFBD> Ҫ ȡ <EFBFBD> <EFBFBD> Ӧ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <EFBFBD> list . GetAt ( pos )
*/
# define CListForEach(pos, list) \
for ( POSITION pos = ( list ) . GetHeadPosition ( ) ; pos ! = nullptr ; ( list ) . GetNext ( pos ) )
/**
* CList <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ list CList <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ pos POSITION <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ԫ <EFBFBD> ص <EFBFBD> λ <EFBFBD> ã <EFBFBD> Ҫ ȡ <EFBFBD> <EFBFBD> Ӧ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <EFBFBD> list . GetAt ( pos )
*/
# define CListForEachReverse(pos, list) \
for ( POSITION pos = ( list ) . GetTailPosition ( ) ; pos ! = nullptr ; ( list ) . GetPrev ( pos ) )
template < typename T >
inline CString ToCString ( const T & value )
{
return _T ( " " ) ;
}
template < >
inline CString ToCString < int32_t > ( const int32_t & value )
{
CString str ;
str . Format ( _T ( " %d " ) , value ) ;
return str ;
}
template < >
inline CString ToCString < uint32_t > ( const uint32_t & value )
{
CString str ;
str . Format ( _T ( " %u " ) , value ) ;
return str ;
}
template < >
inline CString ToCString < long > ( const long & value )
{
CString str ;
str . Format ( _T ( " %ld " ) , value ) ;
return str ;
}
template < >
inline CString ToCString < unsigned long > ( const unsigned long & value )
{
CString str ;
str . Format ( _T ( " %lu " ) , value ) ;
return str ;
}
template < >
inline CString ToCString < int64_t > ( const int64_t & value )
{
CString str ;
str . Format ( _T ( " %lld " ) , value ) ;
return str ;
}
template < >
inline CString ToCString < uint64_t > ( const uint64_t & value )
{
CString str ;
str . Format ( _T ( " %llu " ) , value ) ;
return str ;
}
template < >
inline CString ToCString < float > ( const float & value )
{
CString str ;
str . Format ( _T ( " %f " ) , value ) ;
return str ;
}
template < >
inline CString ToCString < double > ( const double & value )
{
CString str ;
str . Format ( _T ( " %f " ) , value ) ;
return str ;
}
template < >
inline CString ToCString < bool > ( const bool & value )
{
return value ? _T ( " true " ) : _T ( " false " ) ;
}
template < >
inline CString ToCString < CString > ( const CString & value )
{
return value ;
}
template < typename T >
T & GetInstance ( )
{
static T instance ;
return instance ;
}
/**
* CList <EFBFBD> б <EFBFBD> <EFBFBD> ϲ <EFBFBD>
*
* \ param source Դ <EFBFBD> б <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ᱻ <EFBFBD> <EFBFBD>
* \ param target <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ӵ <EFBFBD> Ԫ <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD>
*/
template < typename T , typename E >
void CListAddRange ( CList < T , E > & source , const CList < T , E > & target )
{
for ( POSITION pos = ( target ) . GetHeadPosition ( ) ; pos ! = nullptr ; ( target ) . GetNext ( pos ) )
{
source . AddTail ( target . GetAt ( pos ) ) ;
}
}
/**
* CList <EFBFBD> б <EFBFBD> <EFBFBD> Ƴ <EFBFBD>
*
* <EFBFBD> <EFBFBD> source <EFBFBD> <EFBFBD> <EFBFBD> Ƴ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> target <EFBFBD> д <EFBFBD> <EFBFBD> ڵ <EFBFBD> Ԫ <EFBFBD> <EFBFBD>
*
* \ param source Դ <EFBFBD> б <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ᱻ <EFBFBD> <EFBFBD>
* \ param target Ҫ <EFBFBD> Ƴ <EFBFBD> <EFBFBD> <EFBFBD> Ԫ <EFBFBD> ؼ <EFBFBD> <EFBFBD> <EFBFBD>
*/
template < typename T , typename E >
void CListRemoveRange ( CList < T , E > & source , const CList < T , E > & target )
{
// <20> <> <EFBFBD> <EFBFBD> Դ<EFBFBD> б <EFBFBD>
POSITION pos = source . GetHeadPosition ( ) ;
while ( pos ! = nullptr )
{
POSITION currentPos = pos ;
T & element = source . GetNext ( pos ) ;
if ( target . Find ( element ) ! = nullptr )
{
source . RemoveAt ( currentPos ) ;
}
}
}
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param first
* \ param second
* \ return
*/
bool IsEqual ( const CCurveEx * first , const CCurveEx * second ) ;
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param first
* \ param second
* \ return
*/
bool IsEqual ( const CPolyline & first , const CPolyline & second ) ;
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param first
* \ param second
* \ return
*/
bool IsEqual ( const CPointXYZ & first , const CPointXYZ & second ) ;
/**
* double <EFBFBD> е Ȳ <EFBFBD> <EFBFBD> <EFBFBD> ֱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> =
*/
bool IsEqual ( double a , double b ) ;
/**
* double <EFBFBD> Ĵ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж <EFBFBD>
*/
bool IsGreaterThan ( double a , double b ) ;
/**
* double <EFBFBD> <EFBFBD> С <EFBFBD> <EFBFBD> <EFBFBD> ж <EFBFBD>
*/
bool IsLessThan ( double a , double b ) ;
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Dz <EFBFBD> <EFBFBD> Ƕ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Σ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȼ <EFBFBD> <EFBFBD> ж <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> β <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
bool IsPolygon ( const CCurveEx * pCurve ) ;
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Σ <EFBFBD> <EFBFBD> <EFBFBD> ע <EFBFBD> ⣬ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֻ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> x , y <EFBFBD> <EFBFBD> <EFBFBD> 곤 <EFBFBD> ȣ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> z ֵ
* \ return <EFBFBD> <EFBFBD> β δ <EFBFBD> <EFBFBD> <EFBFBD> ӳ <EFBFBD> <EFBFBD> <EFBFBD> С <EFBFBD> ڵ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ܳ <EFBFBD> <EFBFBD> ȵ <EFBFBD> ʮ <EFBFBD> <EFBFBD> ֮ һ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> true <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> false <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƕ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҳ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> true
*/
bool IsApproximatePolygon ( const CCurveEx * pCurve ) ;
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> պ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߣ <EFBFBD> <EFBFBD> <EFBFBD> β <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ return <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> pCurve <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߣ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> nullptr , <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ѿ <EFBFBD> <EFBFBD> DZ պ ϵ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߣ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߣ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> պ ϵ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ note <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 沢 û <EFBFBD> п <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD> ͬ һ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ȼ <EFBFBD> <EFBFBD> <EFBFBD> պ <EFBFBD>
*/
CCurveEx * CreateCloseCurve ( const CCurveEx * pCurve ) ;
/**
* <EFBFBD> ж <EFBFBD> ij <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> ij <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڣ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ﲻ <EFBFBD> <EFBFBD> <EFBFBD> ж <EFBFBD> polyline <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> û <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڣ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ж <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> ڼ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param polylines
* \ param polyline
* \ return
*/
bool CPolylinesContains ( const std : : list < CPolyline > & polylines , const CPolyline & polyline ) ;
/**
* <EFBFBD> ж <EFBFBD> ij <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param pointXYZs
* \ param pointXYZ
*/
bool CPointXYZContains ( const std : : vector < CPointXYZ > & pointXYZs , const CPointXYZ & pointXYZ ) ;
/**
* <EFBFBD> ж <EFBFBD> x y <EFBFBD> <EFBFBD> <EFBFBD> ɵ ĵ <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> rect <EFBFBD> <EFBFBD>
*
* \ param x x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param y y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param rect <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ return
*/
inline bool IsInRect ( double x , double y , const NBase : : CRect8 & rect )
{
return x > = rect . left & & x < = rect . right & & y > = rect . bottom & & y < = rect . top ;
}
inline bool IsInRect ( const NBase : : CRect8 & subRect , const NBase : : CRect8 & rect )
{
return ( subRect . left > = rect . left ) & &
( subRect . right < = rect . right ) & &
( subRect . bottom > = rect . bottom ) & &
( subRect . top < = rect . top ) ;
}
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> ཻ
* \ param
*/
inline bool IsIntersecting ( const NBase : : CRect8 & rect1 , const NBase : : CRect8 & rect2 )
{
return rect1 . right > rect2 . left
& & rect1 . left < rect2 . right
& & rect1 . top > rect2 . bottom
& & rect1 . bottom < rect2 . top ;
}
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> ± <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߵ <EFBFBD> <EFBFBD> <EFBFBD> ʼ <EFBFBD> ± <EFBFBD>
*
* \ param curve <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param index <EFBFBD> ± <EFBFBD>
* \ return
*/
inline bool IsFirstIndex ( CCurveEx & curve , int32_t index )
{
return curve . num > 0 & & index = = 0 ;
}
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> ± <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߵ Ľ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ± <EFBFBD>
*
* \ param curve <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param index <EFBFBD> ± <EFBFBD>
* \ return
*/
inline bool IsLastIndex ( CCurveEx & curve , int32_t index )
{
return curve . num > 0 & & index = = curve . num - 1 ;
}
/**
* @ brief <EFBFBD> ж ϵ <EFBFBD> ( px0 , py0 ) <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶ <EFBFBD> ( px1 , py1 ) - ( px2 , py2 ) <EFBFBD> <EFBFBD>
*
* @ param px0 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param py0 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param px1 <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param py1 <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param px2 <EFBFBD> ߶ <EFBFBD> <EFBFBD> յ <EFBFBD> <EFBFBD> <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param py2 <EFBFBD> ߶ <EFBFBD> <EFBFBD> յ <EFBFBD> <EFBFBD> <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ return true <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD>
* @ return false <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 㲻 <EFBFBD> <EFBFBD> <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline bool IsPointOnLine ( double px0 , double py0 , double px1 , double py1 , double px2 , double py2 )
{
double crossProduct = ( px1 - px0 ) * ( py2 - py0 ) - ( px2 - px0 ) * ( py1 - py0 ) ;
return ( std : : abs ( crossProduct ) < std : : numeric_limits < double > : : epsilon ( ) ) & &
( ( px0 - px1 ) * ( px0 - px2 ) < = 0 ) & &
( ( py0 - py1 ) * ( py0 - py2 ) < = 0 ) ;
}
/**
* @ brief <EFBFBD> ж <EFBFBD> <EFBFBD> ߶ <EFBFBD> ( px1 , py1 ) - ( px2 , py2 ) <EFBFBD> <EFBFBD> <EFBFBD> ߶ <EFBFBD> ( px3 , py3 ) - ( px4 , py4 ) <EFBFBD> Ƿ <EFBFBD> <EFBFBD> ཻ
*
* @ note <EFBFBD> <EFBFBD> <EFBFBD> 㷨 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶ β <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ص <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƽ <EFBFBD> <EFBFBD> <EFBFBD> ߵ Ľ <EFBFBD> <EFBFBD> <EFBFBD>
* @ param px1 <EFBFBD> <EFBFBD> һ <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param py1 <EFBFBD> <EFBFBD> һ <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param px2 <EFBFBD> <EFBFBD> һ <EFBFBD> ߶ <EFBFBD> <EFBFBD> յ <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param py2 <EFBFBD> <EFBFBD> һ <EFBFBD> ߶ <EFBFBD> <EFBFBD> յ <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param px3 <EFBFBD> ڶ <EFBFBD> <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param py3 <EFBFBD> ڶ <EFBFBD> <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param px4 <EFBFBD> ڶ <EFBFBD> <EFBFBD> ߶ <EFBFBD> <EFBFBD> յ <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param py4 <EFBFBD> ڶ <EFBFBD> <EFBFBD> ߶ <EFBFBD> <EFBFBD> յ <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ return true <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶ <EFBFBD> <EFBFBD> ڷ ǹ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ཻ
* @ return false <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶ β <EFBFBD> <EFBFBD> ཻ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline bool IsIntersect ( double px1 , double py1 , double px2 , double py2 , double px3 , double py3 , double px4 , double py4 )
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĸ
double denominator = ( px2 - px1 ) * ( py4 - py3 ) - ( py2 - py1 ) * ( px4 - px3 ) ;
// ƽ <> <C6BD> <EFBFBD> <EFBFBD> ֱ<EFBFBD> ӷ<EFBFBD> <D3B7> <EFBFBD>
if ( std : : abs ( denominator ) < std : : numeric_limits < double > : : epsilon ( ) )
{
return false ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϵ<EFBFBD> <CFB5>
double r_numerator = ( py1 - py3 ) * ( px4 - px3 ) - ( px1 - px3 ) * ( py4 - py3 ) ;
double s_numerator = ( py1 - py3 ) * ( px2 - px1 ) - ( px1 - px3 ) * ( py2 - py1 ) ;
double r = r_numerator / denominator ;
double s = s_numerator / denominator ;
return ( r > = 0 & & r < = 1 & & s > = 0 & & s < = 1 ) ;
}
/**
* @ brief <EFBFBD> ж ϵ <EFBFBD> ( x , y ) <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> curve <EFBFBD> <EFBFBD> ʾ <EFBFBD> Ķ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* @ note ʹ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߷ <EFBFBD> <EFBFBD> <EFBFBD> Ray Casting Algorithm <EFBFBD> <EFBFBD> ʵ <EFBFBD> ֣ <EFBFBD>
* <EFBFBD> ӵ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ˮ ƽ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߣ <EFBFBD> ͳ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> α ߵ Ľ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <EFBFBD> <EFBFBD> ڲ <EFBFBD> / <EFBFBD> <EFBFBD> <EFBFBD> ϣ <EFBFBD> ż <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʾ <EFBFBD> <EFBFBD> <EFBFBD> ⲿ <EFBFBD> <EFBFBD>
* https : //www.cnblogs.com/charlee44/p/10704156.html
*
* @ param x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ param curve <EFBFBD> <EFBFBD> ʾ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ε <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD>
* @ return true <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڲ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* @ return false <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ⲿ
*/
inline bool IsPointInPolygon ( double x , double y , const CCurveEx & curve )
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߣ<EFBFBD> <DFA3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 㹻Զ<E3B9BB> <D4B6>
const double RAY_LENGTH = 1e9 ; // ʹ <> ù̶<C3B9> <CCB6> <EFBFBD>
double rayEndX = x - RAY_LENGTH ;
int intersectCount = 0 ; // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ÿ<EFBFBD> <C3BF> <EFBFBD> <EFBFBD>
for ( int i = 0 ; i < curve . num ; + + i ) {
int next = ( i + 1 ) % curve . num ; // <20> Զ<EFBFBD> <D4B6> պ϶<D5BA> <CFB6> <EFBFBD> <EFBFBD> <EFBFBD>
double x1 = curve . x [ i ] ;
double y1 = curve . y [ i ] ;
double x2 = curve . x [ next ] ;
double y2 = curve . y [ next ] ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶<EFBFBD> <DFB6> <EFBFBD> ֱ<EFBFBD> ӷ<EFBFBD> <D3B7> <EFBFBD> true
if ( IsPointOnLine ( x , y , x1 , y1 , x2 , y2 ) )
{
return true ;
}
// <20> ų<EFBFBD> ˮƽ <CBAE> ߶<EFBFBD>
if ( std : : abs ( y2 - y1 ) < std : : numeric_limits < double > : : epsilon ( ) ) continue ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <C7B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ཻ
if ( IsIntersect ( x1 , y1 , x2 , y2 , x , y , rayEndX , y ) ) {
// <20> <> ȡ<EFBFBD> ߶ζ˵<CEB6> Y<EFBFBD> <59> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֵ
# pragma warning(push) // <20> <> <EFBFBD> 浱ǰ<E6B5B1> <C7B0> <EFBFBD> <EFBFBD> ״̬
# pragma warning(disable:4068) // <20> <> <EFBFBD> <EFBFBD> C4068
# pragma push_marco("max")
# undef max
double topY = std : : max ( y1 , y2 ) ;
# pragma pop_marco("max")
# pragma warning(pop)
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶ζ<DFB6> <CEB6> <EFBFBD> ʱ
if ( IsPointOnLine ( x1 , y1 , x , y , rayEndX , y ) ) {
if ( y1 = = topY ) intersectCount + + ;
}
else if ( IsPointOnLine ( x2 , y2 , x , y , rayEndX , y ) ) {
if ( y2 = = topY ) intersectCount + + ;
}
else {
intersectCount + + ;
}
}
}
// <20> <> ż<EFBFBD> ж<EFBFBD>
return ( intersectCount % 2 = = 1 ) ;
}
/**
* <EFBFBD> ϲ <EFBFBD> <EFBFBD> ཻ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param rects <EFBFBD> <EFBFBD> <EFBFBD> о <EFBFBD> <EFBFBD> <EFBFBD>
* \ return <EFBFBD> ϲ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ľ <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline std : : vector < NBase : : CRect8 > MergeRects ( const std : : vector < NBase : : CRect8 > & rects )
{
if ( rects . empty ( ) )
{
return { } ;
}
std : : vector < NBase : : CRect8 > data = rects ;
std : : sort ( data . begin ( ) , data . end ( ) , [ ] ( const NBase : : CRect8 & a , const NBase : : CRect8 & b )
{
return a . left < b . left ;
} ) ;
bool changed ;
do {
changed = false ;
for ( size_t i = 0 ; i < data . size ( ) ; + + i ) {
for ( size_t j = i + 1 ; j < data . size ( ) & & ! changed ; + + j ) {
if ( IsIntersecting ( data [ i ] , data [ j ] ) ) {
double newLeft = min ( data [ i ] . left , data [ j ] . left ) ;
double newTop = max ( data [ i ] . top , data [ j ] . top ) ;
double newRight = max ( data [ i ] . right , data [ j ] . right ) ;
double newBottom = min ( data [ i ] . bottom , data [ j ] . bottom ) ;
data [ i ] = NBase : : CRect8 ( newLeft , newTop , newRight , newBottom ) ;
data . erase ( data . begin ( ) + j ) ;
changed = true ;
}
}
}
} while ( changed ) ;
return data ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ظ <EFBFBD> <EFBFBD> ĵ <EFBFBD>
*
* \ param curve
* \ return
*/
inline std : : unique_ptr < CCurveEx > DeduplicateCurvePoints ( const CCurveEx & curve )
{
if ( curve . num = = 0 )
{
return std : : make_unique < CCurveEx > ( ) ;
}
auto pNewCurve = std : : make_unique < CCurveEx > ( ) ;
pNewCurve - > Create ( curve . num ) ; // Ԥ<> <D4A4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڴ棨curve.num<75> <6D>
double lastX = curve . x [ 0 ] ;
double lastY = curve . y [ 0 ] ;
double lastZ = curve . z [ 0 ] ;
pNewCurve - > x [ 0 ] = lastX ;
pNewCurve - > y [ 0 ] = lastY ;
pNewCurve - > z [ 0 ] = lastZ ;
int32_t index = 1 ;
for ( int32_t i = 1 ; i < curve . num ; i + + )
{
double currentX = curve . x [ i ] ;
double currentY = curve . y [ i ] ;
double currentZ = curve . z [ i ] ;
if ( currentX ! = lastX | | currentY ! = lastY | | currentZ ! = lastZ )
{
pNewCurve - > x [ index ] = currentX ;
pNewCurve - > y [ index ] = currentY ;
pNewCurve - > z [ index ] = currentZ ;
lastX = currentX ;
lastY = currentY ;
lastZ = currentZ ;
index + + ;
}
}
pNewCurve - > num = index ; // <20> <> <EFBFBD> ǵ<EFBFBD> x y z <20> <> <EFBFBD> ܻ<EFBFBD> <DCBB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڴ棬<DAB4> <E6A3AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͨ<EFBFBD> <CDA8> num <20> <> <EFBFBD> Ʋ<EFBFBD> Ҫȥ<D2AA> <C8A5> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
pNewCurve - > GetLocation ( ) ;
return pNewCurve ;
}
/**
* <EFBFBD> Ƴ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ָ <EFBFBD> <EFBFBD> <EFBFBD> ± <EFBFBD> <EFBFBD> Ľ ڵ <EFBFBD>
*
* \ param pCurve <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param index Ҫ <EFBFBD> <EFBFBD> <EFBFBD> Ƴ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ± <EFBFBD>
* \ return <EFBFBD> <EFBFBD> <EFBFBD> ߱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĵ <EFBFBD> ַ
*/
inline void RemoveCurveIndex ( CCurveEx & pCurve , int index )
{
if ( index < 0 | | index > = pCurve . num )
{
return ;
}
for ( int i = index ; i + 1 < pCurve . num ; i + + )
{
pCurve . x [ i ] = pCurve . x [ i + 1 ] ;
pCurve . y [ i ] = pCurve . y [ i + 1 ] ;
pCurve . z [ i ] = pCurve . z [ i + 1 ] ;
}
pCurve . num - = 1 ;
pCurve . GetLocation ( ) ;
}
/**
* \ brief <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 㵽 <EFBFBD> ߶ ε <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 㣨 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ͷ Ӱ <EFBFBD> <EFBFBD>
* <EFBFBD> ú <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> pos <EFBFBD> <EFBFBD> <EFBFBD> ߶ <EFBFBD> ( x1 , y1 ) - ( x2 , y2 ) <EFBFBD> ϵ Ĵ <EFBFBD> <EFBFBD> <EFBFBD> Ͷ Ӱ <EFBFBD> <EFBFBD>
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ͷ Ӱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ࣬ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ķ ˵ 㡣
* \ param pos <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĵ <EFBFBD> ǰ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param x1 <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> X
* \ param y1 <EFBFBD> ߶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Y
* \ param x2 <EFBFBD> ߶ <EFBFBD> <EFBFBD> յ <EFBFBD> X
* \ param y2 <EFBFBD> ߶ <EFBFBD> <EFBFBD> յ <EFBFBD> Y
* \ return CPoint2D <EFBFBD> ߶ <EFBFBD> <EFBFBD> ϵ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline NBase : : CPoint2D GetClosestPointOnSegment ( const NBase : : CPoint2D & pos , double x1 , double y1 , double x2 , double y2 )
{
double dx = x2 - x1 ;
double dy = y2 - y1 ;
double denominator = dx * dx + dy * dy ;
// 1e-9 <20> <> һ <EFBFBD> <D2BB> <EFBFBD> dz<EFBFBD> С <EFBFBD> <D0A1> <EFBFBD> <EFBFBD> (0.000000001)<29> <> <EFBFBD> <EFBFBD> <EFBFBD> ڸ<EFBFBD> <DAB8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƚϣ<C8BD> <CFA3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ϊ<EFBFBD> ˱<EFBFBD> <CBB1> <EFBFBD> <EFBFBD> <EFBFBD> 0 <20> õ<EFBFBD> NaN
if ( denominator < 1e-9 )
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ߶γ <DFB6> <CEB3> <EFBFBD> Ϊ0<CEAA> <30> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> յ<EFBFBD> <D5B5> غϣ<D8BA> <CFA3> <EFBFBD> ֱ<EFBFBD> ӷ<EFBFBD> <D3B7> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 㣬<EFBFBD> <E3A3AC> ֹ<EFBFBD> <D6B9> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
return NBase : : CPoint2D ( x1 , y1 ) ;
}
double t = ( ( pos . x0 - x1 ) * dx + ( pos . y0 - y1 ) * dy ) / denominator ;
t = std : : clamp ( t , 0.0 , 1.0 ) ;
double x = x1 + t * dx ;
double y = y1 + t * dy ;
return NBase : : CPoint2D ( x , y ) ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> R <EFBFBD> <EFBFBD>
*
* \ param xy ͼ <EFBFBD> <EFBFBD>
* \ param filter <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֻ <EFBFBD> <EFBFBD> ƥ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ Ԫ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> R <EFBFBD> <EFBFBD>
* \ return R <EFBFBD> <EFBFBD>
*/
inline std : : unique_ptr < RTree < POSITION , double , 2 > > BuildRTree ( CXy & xy , const CXyElementFilter & filter )
{
auto tree = std : : make_unique < RTree < POSITION , double , 2 > > ( ) ;
NBase : : CPositionList select ;
xy . GetElement ( filter , select ) ;
POSITION pos = select . GetHeadPosition ( ) ;
while ( pos ! = nullptr )
{
POSITION pt = select . GetNext ( pos ) ;
COne * pOne = xy . GetAt ( pt ) ;
if ( pOne = = nullptr )
{
continue ;
}
NBase : : CRect8 range ( 1e100 , - 1e100 , - 1e100 , 1e100 ) ;
pOne - > GetRange ( range ) ;
double minX = min ( range . left , range . right ) ;
double minY = min ( range . top , range . bottom ) ;
double maxX = max ( range . left , range . right ) ;
double maxY = max ( range . top , range . bottom ) ;
double minValue [ 2 ] { minX , minY } ;
double maxValue [ 2 ] { maxX , maxY } ;
tree - > Insert ( minValue , maxValue , pt ) ;
}
return tree ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> ݿ ɵ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ( <EFBFBD> <EFBFBD> vector , list ) <EFBFBD> Ƶ <EFBFBD> Ԫ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
template < typename IteratorType >
using ItemType = typename std : : iterator_traits < typename IteratorType : : iterator > : : value_type ;
/**
* ForEach , std : : for_each <EFBFBD> 棬 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ٴ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param items
* \ param pred
*/
template < typename IteratorType >
void ForEach ( IteratorType & items , std : : function < void ( ItemType < IteratorType > & item ) > pred )
{
for ( typename IteratorType : : iterator ptr = items . begin ( ) ; ptr ! = items . end ( ) ; ptr + + )
{
pred ( * ptr ) ;
}
}
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> Ԫ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param items
* \ param pred
* \ return
*/
template < typename IteratorType >
bool AnyOf ( const IteratorType & items , std : : function < bool ( const ItemType < IteratorType > & item ) > pred )
{
return std : : any_of ( items . begin ( ) , items . end ( ) , pred ) ;
}
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ԫ <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param items
* \ param pred
* \ return
*/
template < typename IteratorType >
bool NoneOf ( const IteratorType & items , std : : function < bool ( const ItemType < IteratorType > & item ) > pred )
{
return std : : none_of ( items . begin ( ) , items . end ( ) , pred ) ;
}
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ԫ <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param items
* \ param pred
* \ return
*/
template < typename IteratorType >
bool AllOf ( const IteratorType & items , std : : function < bool ( const ItemType < IteratorType > & item ) > pred )
{
return std : : all_of ( items . begin ( ) , items . end ( ) , pred ) ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> ˳ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ԫ <EFBFBD> <EFBFBD>
*
* \ param items
* \ param pred
* \ return
*/
template < typename IteratorType >
IteratorType Filter ( const IteratorType & items , std : : function < bool ( const ItemType < IteratorType > & item ) > pred )
{
IteratorType filteredIterator { } ;
ForEach < IteratorType > ( const_cast < IteratorType & > ( items ) , [ & filteredIterator , & pred ] ( auto & item )
{
if ( pred ( item ) )
{
filteredIterator . push_back ( item ) ;
}
} ) ;
return filteredIterator ;
}
/**
* <EFBFBD> ͷ ż <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> е <EFBFBD> ָ <EFBFBD> 룬 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param items
*/
template < typename IteratorType >
void DeleteAll ( IteratorType & items )
{
static_assert ( std : : is_pointer < ItemType < IteratorType > > : : value ) ;
for ( auto * p : items )
{
delete p ;
}
items . clear ( ) ;
}
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ij <EFBFBD> <EFBFBD> Ԫ <EFBFBD> <EFBFBD>
*
* \ param items
* \ param item
* \ return
*/
template < typename IteratorType >
bool Contains ( const IteratorType & items , const ItemType < IteratorType > & item )
{
for ( const auto & e : items )
{
if ( e = = item )
{
return true ;
}
}
return false ;
}
/**
* <EFBFBD> <EFBFBD> ȡ ͼ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ <EFBFBD> 㣺
*
* \ param xy
* \ return
*/
inline std : : vector < CLayer * > CollectAllLayers ( const CXy & xy )
{
std : : vector < CLayer * > layers ;
CClassList * pClassList = const_cast < CXy & > ( xy ) . GetClassList ( ) ;
for ( POSITION classPos = pClassList - > GetHeadPosition ( ) ; classPos ! = nullptr ; pClassList - > GetNext ( classPos ) )
{
CLayerList * pLayerList = pClassList - > GetAt ( classPos ) ;
for ( POSITION pos = pLayerList - > GetHeadPosition ( ) ; pos ! = nullptr ; pLayerList - > GetNext ( pos ) )
{
CLayer * pLayer = pLayerList - > GetAt ( pos ) ;
layers . push_back ( pLayer ) ;
}
}
return layers ;
}
/**
* <EFBFBD> <EFBFBD> CList ת <EFBFBD> <EFBFBD> Ϊ std : : vector <EFBFBD> <EFBFBD> <EFBFBD> ʺ <EFBFBD> ֻ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĵ <EFBFBD> CList Ԫ <EFBFBD> <EFBFBD> <EFBFBD> г <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param list
* \ return
*/
template < typename T >
std : : vector < T > CListToStdVector ( const CList < T , T > & list )
{
std : : vector < T > result ;
CListForEach ( pos , list )
{
result . push_back ( list . GetAt ( pos ) ) ;
}
return result ;
}
/**
* <EFBFBD> <EFBFBD> CList ת <EFBFBD> <EFBFBD> Ϊ std : : list <EFBFBD> <EFBFBD> <EFBFBD> ʺ <EFBFBD> ֻ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ĵ <EFBFBD> CList Ԫ <EFBFBD> <EFBFBD> <EFBFBD> г <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param list
* \ return
*/
template < typename T >
std : : list < T > CListToStdList ( const CList < T , T > & list )
{
std : : list < T > result ;
CListForEach ( pos , list )
{
result . push_back ( list . GetAt ( pos ) ) ;
}
return result ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ <EFBFBD> <EFBFBD> CList <EFBFBD> <EFBFBD> ɾ <EFBFBD> <EFBFBD> Ԫ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ POSITION <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> POSITION <EFBFBD> <EFBFBD> Ԫ <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param list
* \ return
*/
template < typename T >
std : : list < std : : pair < POSITION , T > > CListToStdList2 ( const CList < T , T > & list )
{
std : : list < std : : pair < POSITION , T > > result ;
CListForEach ( pos , list )
{
result . push_back ( { pos , list . GetAt ( pos ) } ) ;
}
return result ;
}
/**
* <EFBFBD> <EFBFBD> POSITION <EFBFBD> б <EFBFBD> ת <EFBFBD> <EFBFBD> Ϊ COne <EFBFBD> б <EFBFBD>
*
* \ param positions <EFBFBD> 洢 <EFBFBD> <EFBFBD> ͼ Ԫ POSITION <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD>
* \ return
*/
std : : list < COne * > PtrsToCOnes ( const CPtrList & pList ) ;
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Cone <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɸ ѡ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȡ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> COne
*
* \ param list
* \ param pred <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ return
*/
std : : list < COne * > ConesFilter ( const std : : list < COne * > & cones , std : : function < bool ( COne * ) > pred ) ;
/**
* CList <EFBFBD> <EFBFBD> ֧ <EFBFBD> <EFBFBD> = <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Щ ʵ <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> ͨ <EFBFBD> ú <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param target <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֵ <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ൱ <EFBFBD> <EFBFBD> = <EFBFBD> <EFBFBD> <EFBFBD> ߵ <EFBFBD> <EFBFBD> б <EFBFBD>
* \ param source <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ൱ <EFBFBD> <EFBFBD> = <EFBFBD> ұ ߵ <EFBFBD> <EFBFBD> б <EFBFBD>
*/
template < typename T >
void Assign ( CList < T , T > & target , const CList < T , T > & source )
{
CListForEach ( pos , source )
{
target . AddTail ( source . GetAt ( pos ) ) ;
}
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƽ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ <EFBFBD> <EFBFBD> ֻ <EFBFBD> ڶ Ա Ⱦ <EFBFBD> <EFBFBD> <EFBFBD> Զ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 㾫 ȷ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ij <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline double DistanceSq ( double x1 , double y1 , double x2 , double y2 )
{
double dx = x2 - x1 ;
double dy = y2 - y1 ;
return dx * dx + dy * dy ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ƽ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ <EFBFBD> <EFBFBD> ֻ <EFBFBD> ڶ Ա Ⱦ <EFBFBD> <EFBFBD> <EFBFBD> Զ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 㾫 ȷ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ij <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline double DistanceSq ( const NBase : : CPoint2D & pt1 , const NBase : : CPoint2D & pt2 )
{
return DistanceSq ( pt1 . x0 , pt1 . y0 , pt2 . x0 , pt2 . y0 ) ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֮ <EFBFBD> <EFBFBD> <EFBFBD> ľ <EFBFBD> <EFBFBD> <EFBFBD>
*/
double CalcDistance ( double x1 , double y1 , double x2 , double y2 ) ;
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߵ ij <EFBFBD> <EFBFBD> <EFBFBD>
*/
double CalcCurveDistance ( const CCurveEx * pCurve ) ;
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> <EFBFBD>
* x1 x2 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͬ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʵ <EFBFBD> Ͼ ͼ <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD> ʶ <EFBFBD> <EFBFBD> ԣ <EFBFBD> y1 y2 Ҳ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͬ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ <EFBFBD> <EFBFBD> <EFBFBD> ÷ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
double CalcSlope ( double x1 , double y1 , double x2 , double y2 ) ;
/**
* <EFBFBD> <EFBFBD> CList ȥ <EFBFBD> <EFBFBD>
*
* \ param items <EFBFBD> <EFBFBD> <EFBFBD> Σ <EFBFBD> <EFBFBD> <EFBFBD> ȥ <EFBFBD> ص <EFBFBD> items
*/
template < typename T >
void CListUnique ( CList < T , T > & items )
{
std : : vector < T > cacheItems ;
std : : vector < POSITION > removePositions ;
CListForEach ( pos , items )
{
T & value = items . GetAt ( pos ) ;
if ( Contains ( cacheItems , value ) )
{
removePositions . push_back ( pos ) ;
}
else
{
cacheItems . push_back ( value ) ;
}
}
for ( POSITION pos : removePositions )
{
items . RemoveAt ( pos ) ;
}
}
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> ܹ <EFBFBD> ƥ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param source <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD>
* \ param search <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param ignoreCase <EFBFBD> <EFBFBD> <EFBFBD> Դ <EFBFBD> С д
* \ param matchWholeWord <EFBFBD> <EFBFBD> ȫ ƥ <EFBFBD> <EFBFBD>
* \ return
*/
bool SearchMatch ( const CString & source , const CString & search , bool ignoreCase , bool matchWholeWord ) ;
// <20> <> ȡ<EFBFBD> <C8A1> ͼ<EFBFBD> <CDBC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
CString GetParentLayerPath ( const CString & pLayer ) ;
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> ͬ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ᴦ <EFBFBD> <EFBFBD> ͼ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> п ո <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Լ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> class <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param layerName1 ͼ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 1
* \ param layerName2 ͼ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 2
* \ return ͼ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> ͬ
*/
bool IsSameLayerName ( const CString & layerName1 , const CString & layerName2 ) ;
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD>
* \ param <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> б <EFBFBD>
* \ param delimiter <EFBFBD> <EFBFBD> <EFBFBD> ӷ <EFBFBD>
* \ return <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ӻ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD>
*/
CString JoinStrings ( const std : : vector < CString > & strings , const CString & delimiter ) ;
/**
* <EFBFBD> <EFBFBD> ָ <EFBFBD> <EFBFBD> <EFBFBD> ָ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ָ <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param string <EFBFBD> <EFBFBD> <EFBFBD> и <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD>
* \ param delimiter <EFBFBD> ָ <EFBFBD> <EFBFBD> <EFBFBD>
* \ return <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> и <EFBFBD> <EFBFBD> õ <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD>
*/
std : : vector < CString > SplitString ( const CString & string , const CString & delimiter ) ;
/**
* <EFBFBD> ж <EFBFBD> position <EFBFBD> Ƿ <EFBFBD> <EFBFBD> Ϸ <EFBFBD>
* \ param pXy
* \ param position <EFBFBD> <EFBFBD> <EFBFBD> ж ϵ <EFBFBD> position
* \ return
*/
bool IsValidPosition ( CXy * pXy , POSITION position ) ;
/**
* <EFBFBD> <EFBFBD> ȡ <EFBFBD> Ϸ <EFBFBD> <EFBFBD> <EFBFBD> position <EFBFBD> б <EFBFBD>
* \ param pXy
* \ param position <EFBFBD> <EFBFBD> <EFBFBD> ж ϵ <EFBFBD> position <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param count position <EFBFBD> <EFBFBD> <EFBFBD> 鳤 <EFBFBD> <EFBFBD>
* \ return
*/
std : : vector < POSITION > GetValidPositions ( CXy * pXy , POSITION positions [ ] , int count ) ;
std : : wstring StringToWString ( const std : : string & str ) ;
std : : string WStringToString ( const std : : wstring & wstr ) ;
/**
* <EFBFBD> <EFBFBD> CString ת <EFBFBD> <EFBFBD> Ϊ utf8 std : : string
*
* \ param str Ҫ ת <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ return <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline std : : string ToUtf8String ( const CString & str )
{
# ifdef UNICODE
CW2A utf8Str ( str , CP_UTF8 ) ;
return std : : string ( utf8Str ) ;
# else
CStringW wstr ( str ) ;
CW2A utf8Str ( wstr , CP_UTF8 ) ;
return std : : string ( utf8Str ) ;
# endif
}
/**
* <EFBFBD> <EFBFBD> std : : string ת <EFBFBD> <EFBFBD> Ϊ BYTE * <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param src <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> std : : string <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param buffer <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> BYTE * <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param length <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ļ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline void StringToBuffer ( const std : : string & src , BYTE * & buffer , int & length )
{
length = static_cast < int > ( src . size ( ) ) ;
buffer = ( BYTE * ) malloc ( length ) ;
memcpy ( buffer , src . data ( ) , length ) ;
}
/**
* <EFBFBD> <EFBFBD> std : : string ת <EFBFBD> <EFBFBD> Ϊ utf - 8 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> BYTE * <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param src <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> std : : string <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param buffer <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> BYTE * <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param length <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ļ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline void CStringToBufferUtf8 ( const CString & src , BYTE * & buffer , int & length )
{
std : : string utf8 = ToUtf8String ( src ) ;
StringToBuffer ( utf8 , buffer , length ) ;
}
/**
* CString ת utf - 8
*
* \ param str Ҫ <EFBFBD> <EFBFBD> ת <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD>
* \ return ת <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD>
*/
std : : string CStringToUtf8String ( const CString & str ) ;
/**
* utf8 std : : string ת CString
*/
CString Utf8StringToCString ( const std : : string & utf8Str ) ;
/**
* Ĩ ƽ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> С ѡ <EFBFBD> <EFBFBD> С <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ѡ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param value Ŀ <EFBFBD> <EFBFBD> ֵ
* \ param min <EFBFBD> <EFBFBD> С ֵ
* \ param max <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֵ
* \ return
*/
inline double Flatten ( double value , double min , double max )
{
assert ( min < = max ) ;
if ( value < min )
{
return min ;
}
if ( value > max )
{
return max ;
}
return value ;
}
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> ڷ <EFBFBD> Χ <EFBFBD> <EFBFBD>
*
* \ param value Ŀ <EFBFBD> <EFBFBD> ֵ
* \ param min <EFBFBD> <EFBFBD> С ֵ
* \ param max <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֵ
* \ return
*/
inline bool InRange ( double value , double min , double max )
{
assert ( min < max ) ;
return ( value > = min & & value < = max ) ;
}
/**
* <EFBFBD> ж <EFBFBD> <EFBFBD> Ƿ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڷ <EFBFBD> Χ <EFBFBD> <EFBFBD>
*
* \ param value Ŀ <EFBFBD> <EFBFBD> ֵ
* \ param min <EFBFBD> <EFBFBD> С ֵ
* \ param max <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֵ
* \ return
*/
inline bool OutOfRange ( double value , double min , double max )
{
assert ( min < max ) ;
return ! InRange ( value , min , max ) ;
}
/**
* <EFBFBD> <EFBFBD> COne <EFBFBD> <EFBFBD> <EFBFBD> л <EFBFBD> Ϊ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param pOne
* \ return
*/
inline std : : vector < BYTE > SerializeCOneToByteArray ( COne * pOne )
{
CMemFile memFile ;
CArchive archive ( & memFile , CArchive : : store ) ;
pOne - > Serialize ( archive , 2022 ) ;
archive . Close ( ) ;
size_t dataSize = memFile . GetLength ( ) ;
std : : vector < BYTE > result ( dataSize ) ;
memFile . SeekToBegin ( ) ;
memFile . Read ( result . data ( ) , static_cast < UINT > ( dataSize ) ) ;
return result ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ݷ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> л <EFBFBD> COne
*
* \ param array
* \ return
*/
inline std : : unique_ptr < COne > DeserializeCOneFromByteArray ( const std : : vector < BYTE > & byteArray )
{
CMemFile memFile ( const_cast < BYTE * > ( byteArray . data ( ) ) , static_cast < UINT > ( byteArray . size ( ) ) ) ;
CArchive archive ( & memFile , CArchive : : load ) ;
std : : unique_ptr < COne > pOne = std : : make_unique < COne > ( ) ;
pOne - > Serialize ( archive , 2022 ) ;
return pOne ;
}
/**
* <EFBFBD> <EFBFBD> ʱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ת <EFBFBD> <EFBFBD> Ϊ " <EFBFBD> <EFBFBD> .<2E> <> .<2E> <> ʱ:<3A> <> :<3A> <> .<2E> <> <EFBFBD> <EFBFBD> " <EFBFBD> <EFBFBD> ʽ <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param timepoint ʱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ return <EFBFBD> <EFBFBD> ʽ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline std : : string FormatTime ( const std : : chrono : : system_clock : : time_point & timepoint )
{
std : : time_t time_t = std : : chrono : : system_clock : : to_time_t ( timepoint ) ;
std : : tm tm = * std : : localtime ( & time_t ) ;
std : : stringstream ss ;
ss < < std : : put_time ( & tm , " %Y-%m-%d %H:%M:%S " ) ;
// <20> <> ȷ<EFBFBD> <C8B7> <EFBFBD> <EFBFBD> <EFBFBD> 룬<EFBFBD> <EBA3AC> <EFBFBD> Ļ<EFBFBD> <C4BB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ̫<EFBFBD> <CCAB> <EFBFBD> ظ<EFBFBD> <D8B8> <EFBFBD> <EFBFBD> <EFBFBD>
auto now_ms = std : : chrono : : duration_cast < std : : chrono : : milliseconds > ( timepoint . time_since_epoch ( ) ) % 1000 ;
ss < < " . " < < now_ms . count ( ) ;
return ss . str ( ) ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʽ Ϊ " <EFBFBD> <EFBFBD> .<2E> <> .<2E> <> ʱ:<3A> <> :<3A> <> .<2E> <> <EFBFBD> <EFBFBD> " <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD> ת <EFBFBD> <EFBFBD> Ϊ ʱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param timeString <EFBFBD> <EFBFBD> ʽ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD>
* \ return ʱ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline std : : chrono : : system_clock : : time_point ParseTime ( const std : : string & timeString )
{
std : : stringstream ss ( timeString ) ;
std : : tm tm { } ;
ss > > std : : get_time ( & tm , " %Y-%m-%d %H:%M:%S " ) ;
std : : time_t time_t = std : : mktime ( & tm ) ;
auto timePoint = std : : chrono : : system_clock : : from_time_t ( time_t ) ;
// <20> <> ȡ<EFBFBD> <C8A1> <EFBFBD> 벿<EFBFBD> <EBB2BF>
char dot = 0 ; // <20> Ⱥ<EFBFBD> <C8BA> Ե<EFBFBD> "."
ss > > dot ;
int ms = 0 ;
ss > > ms ;
timePoint + = std : : chrono : : milliseconds ( ms ) ;
return timePoint ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> uuid
*
* \ return
*/
inline std : : string GenerateUUID ( )
{
GUID guid { } ;
CoInitialize ( & guid ) ;
HRESULT hr = CoCreateGuid ( & guid ) ;
char buf [ 40 ] = { 0 } ;
sprintf_s ( buf , sizeof ( buf ) ,
" %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X " ,
guid . Data1 , guid . Data2 , guid . Data3 ,
guid . Data4 [ 0 ] , guid . Data4 [ 1 ] , guid . Data4 [ 2 ] , guid . Data4 [ 3 ] ,
guid . Data4 [ 4 ] , guid . Data4 [ 5 ] , guid . Data4 [ 6 ] , guid . Data4 [ 7 ] ) ;
return std : : string ( buf ) ;
}
/**
* <EFBFBD> <EFBFBD> ȡ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ return
*/
template < typename T >
T & GetInstace ( )
{
static T instance ;
return instance ;
}
/**
* <EFBFBD> ļ <EFBFBD> · <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ࣬ ʹ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> װ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Path <EFBFBD> IJ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
class Path
{
public :
/**
* · <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ļ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> չ <EFBFBD> <EFBFBD>
*
* \ param path
* \ return
*/
static CString GetFileName ( const CString & path )
{
return PathFindFileName ( path ) ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ļ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ļ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ֻ <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD> Χ <EFBFBD> <EFBFBD> ʾ <EFBFBD> <EFBFBD> <EFBFBD> ļ <EFBFBD> · <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> չ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param path <EFBFBD> ļ <EFBFBD> · <EFBFBD> <EFBFBD>
* \ return <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ( . ) <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD>
*/
static CString GetFileNameWithoutExtension ( const CString & path )
{
CString fileName = PathFindFileName ( path ) ;
CString fileExtenstion = PathFindExtension ( path ) ;
return fileName . Left ( fileName . GetLength ( ) - fileExtenstion . GetLength ( ) ) ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ָ <EFBFBD> <EFBFBD> · <EFBFBD> <EFBFBD> <EFBFBD> ַ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> չ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 㡰 . <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param path
* \ return
*/
static CString GetExtension ( const CString & path )
{
return PathFindExtension ( path ) ;
}
} ;
/**
* <EFBFBD> ж <EFBFBD> z <EFBFBD> Dz <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ч ֵ
* \ param z Ҫ <EFBFBD> ж ϵ <EFBFBD> z ֵ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline bool IsUnvalidValue ( double z )
{
const double invalidZ = - 1E300 ;
return z < = invalidZ ;
}
/**
* <EFBFBD> ͷ <EFBFBD> CPtrList <EFBFBD> е <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ԫ <EFBFBD> أ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ڴ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ҫ <EFBFBD> <EFBFBD> new <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param T <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 洢 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Щ Ԫ <EFBFBD> ص <EFBFBD> ָ <EFBFBD> 룬 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȷ ָ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȷ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ɺ ܶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param ptrList Ҫ <EFBFBD> ͷ ŵ <EFBFBD> <EFBFBD> б <EFBFBD>
*/
template < typename T >
void DeleteAll ( CPtrList & ptrList )
{
for ( POSITION pos = ptrList . GetHeadPosition ( ) ; pos ! = nullptr ; ptrList . GetNext ( pos ) )
{
delete reinterpret_cast < T * > ( ptrList . GetAt ( pos ) ) ;
}
ptrList . RemoveAll ( ) ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ָ <EFBFBD> 룬 <EFBFBD> <EFBFBD> ͬ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ָ <EFBFBD> 뽻 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Σ <EFBFBD> յ ģ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Բ <EFBFBD> Ҫ ʹ <EFBFBD> <EFBFBD> void * <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> T *
*
* \ param first
* \ param second
*/
template < typename T >
void SwapPointer ( T * & first , T * & second )
{
T * temp = first ;
first = second ;
second = temp ;
}
/**
* <EFBFBD> <EFBFBD> ԭ ʼ <EFBFBD> <EFBFBD> CPtrList <EFBFBD> <EFBFBD> ȥ <EFBFBD> <EFBFBD> <EFBFBD> ظ <EFBFBD> <EFBFBD> <EFBFBD> ָ <EFBFBD> 룬 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ψ һ <EFBFBD> <EFBFBD> ָ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ӵ <EFBFBD> <EFBFBD> µ <EFBFBD> CPtrList <EFBFBD> <EFBFBD>
*
* @ param ԭ ʼ <EFBFBD> <EFBFBD> CPtrList <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ظ <EFBFBD> <EFBFBD> <EFBFBD> ָ <EFBFBD> <EFBFBD>
* @ param ȥ <EFBFBD> غ <EFBFBD> <EFBFBD> <EFBFBD> CPtrList <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ψ һ <EFBFBD> <EFBFBD> ָ <EFBFBD> <EFBFBD>
*/
inline void UniquePtrList ( const CPtrList & ptrList , CPtrList & newPtrList )
{
newPtrList . RemoveAll ( ) ;
for ( POSITION pos = ptrList . GetHeadPosition ( ) ; pos ! = nullptr ; ptrList . GetNext ( pos ) )
{
void * ptr = const_cast < CPtrList & > ( ptrList ) . GetAt ( pos ) ;
if ( newPtrList . Find ( ptr ) = = nullptr )
{
newPtrList . AddTail ( ptr ) ;
}
}
}
/**
* <EFBFBD> <EFBFBD> ԭ ʼ <EFBFBD> <EFBFBD> CPositionList <EFBFBD> <EFBFBD> ȥ <EFBFBD> <EFBFBD> <EFBFBD> ظ <EFBFBD> <EFBFBD> <EFBFBD> POSITION <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ψ һ <EFBFBD> <EFBFBD> POSITION <EFBFBD> <EFBFBD> <EFBFBD> ӵ <EFBFBD> <EFBFBD> µ <EFBFBD> CPositionList <EFBFBD> <EFBFBD>
*
* @ param posList ԭ ʼ <EFBFBD> <EFBFBD> CPositionList <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ظ <EFBFBD> <EFBFBD> <EFBFBD> POSITION
* @ param newPosList ȥ <EFBFBD> غ <EFBFBD> <EFBFBD> <EFBFBD> CPositionList <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ψ һ <EFBFBD> <EFBFBD> POSITION
*/
inline void UniquePositionList ( const NBase : : CPositionList & posList , NBase : : CPositionList & newPosList )
{
newPosList . RemoveAll ( ) ;
std : : unordered_set < POSITION > seenPositions ;
for ( POSITION pos = posList . GetHeadPosition ( ) ; pos ! = nullptr ; posList . GetNext ( pos ) )
{
POSITION pt = posList . GetAt ( pos ) ;
if ( seenPositions . find ( pt ) = = seenPositions . end ( ) )
{
seenPositions . insert ( pt ) ;
newPosList . AddTail ( pt ) ;
}
}
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ߶ ν <EFBFBD> <EFBFBD> <EFBFBD>
* https : //stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect/565282#
*
* \ param p0_x <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param p0_y <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param p1_x <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> յ <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param p1_y <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> յ <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param p2_x <EFBFBD> ڶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param p2_y <EFBFBD> ڶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param p3_x <EFBFBD> ڶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> յ <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param p3_y <EFBFBD> ڶ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> յ <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param i_x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param i_y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> y <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ return 1 <EFBFBD> <EFBFBD> ʾ <EFBFBD> н <EFBFBD> <EFBFBD> 㣬 0 <EFBFBD> <EFBFBD> ʾ û <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
inline int GetLineIntersection ( double p0_x , double p0_y , double p1_x , double p1_y ,
double p2_x , double p2_y , double p3_x , double p3_y ,
double & i_x , double & i_y )
{
double s1_x = p1_x - p0_x ;
double s1_y = p1_y - p0_y ;
double s2_x = p3_x - p2_x ;
double s2_y = p3_y - p2_y ;
double s = ( - s1_y * ( p0_x - p2_x ) + s1_x * ( p0_y - p2_y ) ) / ( - s2_x * s1_y + s1_x * s2_y ) ;
double t = ( s2_x * ( p0_y - p2_y ) - s2_y * ( p0_x - p2_x ) ) / ( - s2_x * s1_y + s1_x * s2_y ) ;
if ( s > = 0 & & s < = 1 & & t > = 0 & & t < = 1 )
{
// Collision detected
i_x = p0_x + ( t * s1_x ) ;
i_y = p0_y + ( t * s1_y ) ;
return 1 ;
}
return 0 ; // No collision
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param first <EFBFBD> <EFBFBD> һ <EFBFBD> <EFBFBD> ͼ Ԫ
* \ param second <EFBFBD> ڶ <EFBFBD> <EFBFBD> <EFBFBD> ͼ Ԫ
*/
inline void SwapHowtoView ( COne & first , COne & second )
{
auto * pViewPoint = first . HowToViewPoint ;
auto * pViewCurve = first . HowToViewCurve ;
first . HowToViewPoint = second . HowToViewPoint ;
first . HowToViewCurve = second . HowToViewCurve ;
second . HowToViewPoint = pViewPoint ;
second . HowToViewCurve = pViewCurve ;
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param sourceLayer <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ε <EFBFBD> ͼ <EFBFBD> <EFBFBD>
* \ param targetLayer <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ <EFBFBD> <EFBFBD> ͼ <EFBFBD> <EFBFBD>
*/
inline void CopyLayerHowtoViewTo ( const CLayer * pSourceLayer , CLayer * pTargetLayer )
{
assert ( pSourceLayer ! = nullptr ) ;
assert ( pTargetLayer ! = nullptr ) ;
SafeDelete ( pTargetLayer - > HowToViewCurve ) ;
SafeDelete ( pTargetLayer - > HowToViewPoint ) ;
if ( pSourceLayer - > HowToViewCurve ! = nullptr )
{
pTargetLayer - > HowToViewCurve = new CHowToViewCurve ( ) ;
* ( pTargetLayer - > HowToViewCurve ) = * ( pSourceLayer - > HowToViewCurve ) ;
}
if ( pSourceLayer - > HowToViewPoint ! = nullptr )
{
pTargetLayer - > HowToViewPoint = new CHowToViewPoint ( ) ;
* ( pTargetLayer - > HowToViewPoint ) = * ( pSourceLayer - > HowToViewPoint ) ;
}
}
/**
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ͼ Ԫ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*
* \ param sourceOne <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ε <EFBFBD> ͼ <EFBFBD> <EFBFBD>
* \ param targetOne <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŀ <EFBFBD> <EFBFBD> ͼ <EFBFBD> <EFBFBD>
*/
inline void CopyOneHowtoViewTo ( const COne * pSourceOne , COne * pTargetOne )
{
assert ( pSourceOne ! = nullptr ) ;
assert ( pTargetOne ! = nullptr ) ;
SafeDelete ( pTargetOne - > HowToViewCurve ) ;
SafeDelete ( pTargetOne - > HowToViewPoint ) ;
if ( pSourceOne - > HowToViewCurve ! = nullptr )
{
pTargetOne - > HowToViewCurve = new CHowToViewCurve ( ) ;
* ( pTargetOne - > HowToViewCurve ) = * ( pSourceOne - > HowToViewCurve ) ;
}
if ( pSourceOne - > HowToViewPoint ! = nullptr )
{
pTargetOne - > HowToViewPoint = new CHowToViewPoint ( ) ;
* ( pTargetOne - > HowToViewPoint ) = * ( pSourceOne - > HowToViewPoint ) ;
}
}
/**
* <EFBFBD> <EFBFBD> ֤ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ˳ <EFBFBD> ʱ ִ <EFBFBD> <EFBFBD> ָ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
class FinalAction
{
public :
/**
* <EFBFBD> <EFBFBD> <EFBFBD> 캯 <EFBFBD> <EFBFBD>
*
* \ param func <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
* \ param . . . args <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
*/
template < typename Callable , typename . . . Args >
explicit FinalAction ( Callable & & func , Args & & . . . args )
: callable ( std : : bind ( std : : forward < Callable > ( func ) , std : : forward < Args > ( args ) . . . ) ) , active ( true )
{
}
FinalAction ( FinalAction & & other ) noexcept
: callable ( std : : move ( other . callable ) ) , active ( other . active )
{
}
FinalAction ( const FinalAction & ) = delete ;
FinalAction & operator = ( const FinalAction & ) = delete ;
void Cancel ( )
{
active = false ;
}
~ FinalAction ( ) noexcept
{
if ( active )
{
callable ( ) ;
}
}
private :
std : : function < void ( ) > callable ;
bool active = true ;
} ;
/**
* CFile RAII <EFBFBD> <EFBFBD> װ
*/
class CFileHelper
{
public :
CFileHelper ( const CFileHelper & ) = delete ;
CFileHelper & operator = ( const CFileHelper & ) = delete ;
CFileHelper ( const CFileHelper & & ) = delete ;
CFileHelper & operator = ( const CFileHelper & & ) = delete ;
CFileHelper ( const CString & filePath , UINT openFlags )
{
m_isOpen = m_file . Open ( filePath , CFile : : modeCreate | CFile : : modeWrite ) ;
}
~ CFileHelper ( )
{
if ( m_isOpen )
{
m_file . Close ( ) ;
}
m_isOpen = false ;
}
bool IsOpen ( ) const
{
return m_isOpen ;
}
UINT Read ( void * lpBuf , UINT nCount )
{
Validate ( ) ;
return m_file . Read ( lpBuf , nCount ) ;
}
void Write ( const void * lpBuf , UINT nCount )
{
Validate ( ) ;
m_file . Write ( lpBuf , nCount ) ;
}
ULONGLONG GetPosition ( ) const
{
Validate ( ) ;
return m_file . GetPosition ( ) ;
}
ULONGLONG Seek ( LONGLONG lOff , UINT nFrom )
{
Validate ( ) ;
return m_file . Seek ( lOff , nFrom ) ;
}
ULONGLONG GetLength ( ) const
{
Validate ( ) ;
return m_file . GetLength ( ) ;
}
void SetLength ( ULONGLONG nLength )
{
Validate ( ) ;
return m_file . SetLength ( nLength ) ;
}
CString GetFileName ( ) const
{
Validate ( ) ;
return m_file . GetFileName ( ) ;
}
CString GetFilePath ( ) const
{
Validate ( ) ;
return m_file . GetFilePath ( ) ;
}
CString GetFileTitle ( ) const
{
Validate ( ) ;
return m_file . GetFileTitle ( ) ;
}
CFile & GetFile ( )
{
Validate ( ) ;
return m_file ;
}
private :
void Validate ( ) const
{
if ( ! m_isOpen )
{
throw std : : runtime_error ( " File not open " ) ;
}
}
bool m_isOpen = false ;
CFile m_file ;
} ;