mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 05:24:10 +08:00
161 lines
3.0 KiB
C++
161 lines
3.0 KiB
C++
|
|
#pragma once
|
|
|
|
#include <ippdefs.h>
|
|
|
|
namespace Geometry
|
|
{
|
|
class CDot
|
|
{
|
|
public:
|
|
double x, y;
|
|
|
|
public:
|
|
CDot()
|
|
: x( 0 ), y( 0 )
|
|
{
|
|
}
|
|
|
|
CDot( double dX, double dY )
|
|
: x( dX ), y( dY )
|
|
{
|
|
}
|
|
|
|
double SqrLength() const
|
|
{
|
|
// âîçâðàùàåò êâàäðàò äëèíû âåêòîðà
|
|
return x * x + y * y;
|
|
}
|
|
|
|
double Length() const
|
|
{
|
|
// âîçâðàùàåò äëèíó âåêòîðà
|
|
return ::sqrt( SqrLength() );
|
|
}
|
|
|
|
void Normalize()
|
|
{
|
|
// íîðìàëèçóåò âåêòîð
|
|
double dL = SqrLength();
|
|
if( dL > IPP_EPS52 )
|
|
{
|
|
x = x * abs(x) / dL;
|
|
y = y * abs(y) / dL;
|
|
}
|
|
else
|
|
{
|
|
x = 0;
|
|
y = 0;
|
|
}
|
|
}
|
|
|
|
void Move( double dX, double dY )
|
|
{
|
|
x += dX;
|
|
y += dY;
|
|
}
|
|
|
|
void Scale( double dX, double dY )
|
|
{
|
|
x *= dX;
|
|
y *= dY;
|
|
}
|
|
|
|
void Rotate( double dSinA, double dCosA )
|
|
{
|
|
// âðàùåíèå òî÷êè: dSinA = sin(A), dCosA = cos(A)
|
|
double temp = x * dCosA - y * dSinA;
|
|
y = y * dCosA + x * dSinA;
|
|
x = temp;
|
|
}
|
|
|
|
void Rotate( double dAngle )
|
|
{
|
|
// âðàùåíèå òî÷êè; dAngle â ðàäèàíàõ
|
|
Rotate( ::sin( dAngle ), ::cos( dAngle ) );
|
|
}
|
|
|
|
double Orient( const CDot& a, const CDot& b ) const
|
|
{
|
|
// âîçâðàùàåò çíàê ïîëóïëîñêîñòè äàííîé òî÷êè îòíîñèòåëüíî ïðÿìîé (a, b)
|
|
return (a.x - x) * (b.y - y) - (a.y - y) * (b.x - x);
|
|
}
|
|
|
|
double Distance( const CDot& a, const CDot& b )
|
|
{
|
|
// âîçâðàùàåò ðàñòîÿíèå äàííîé òî÷êè äî ïðÿìîé (a, b)
|
|
CDot c( a.x - b.x, a.y - b.y);
|
|
double D = c.x * (y - a.y) - c.y * (x - a.x);
|
|
return D * D / c.SqrLength();
|
|
}
|
|
|
|
BOOL IntersectLines( const CDot& a1, const CDot& b1, const CDot& a2, const CDot& b2 )
|
|
{
|
|
// ïåðåñå÷åíèå ïðÿìûõ (a1, b1), (a2, b2)
|
|
CDot ad( b1.x - a1.x, a1.y - b1.y );
|
|
CDot bd( b2.x - a2.x, a2.y - b2.y );
|
|
|
|
// îïðåäåëèòåëü ñèñòåìû
|
|
double D = ad.y * bd.x - ad.x * bd.y;
|
|
if( abs( D ) > IPP_EPS52 )
|
|
{
|
|
double aC = ad.x * a1.y + ad.y * a1.x;
|
|
double bC = bd.x * a2.y + bd.y * a2.x;
|
|
|
|
x = (aC * bd.x - ad.x * bC) / D;
|
|
y = (ad.y * bC - aC * bd.y) / D;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE; // íåò ðåøåíèÿ
|
|
}
|
|
};
|
|
|
|
class CTriangle
|
|
{
|
|
public:
|
|
CDot v1, v2, v3; // âåðøèíû òðåóãîëüíèêà
|
|
|
|
BOOL bClockWise; // îáõîä ïî ÷àñîâîé ñòðåëêå
|
|
|
|
public:
|
|
CTriangle()
|
|
{
|
|
bClockWise = TRUE;
|
|
}
|
|
|
|
CTriangle( double x1, double y1, double x2, double y2, double x3, double y3 )
|
|
: v1( x1, y1 ), v2( x2, y2 ), v3( x3, y3 )
|
|
{
|
|
CheckClockWise();
|
|
}
|
|
|
|
CTriangle( const CDot& a, const CDot& b, const CDot& c )
|
|
: v1( a ), v2( b ), v3( c )
|
|
{
|
|
CheckClockWise();
|
|
}
|
|
|
|
|
|
void CheckClockWise()
|
|
{
|
|
bClockWise = v3.Orient( v1, v2 ) > 0;
|
|
}
|
|
|
|
BOOL IsInnerPoint( const CDot& dot ) const
|
|
{
|
|
if( (dot.Orient( v1, v2 ) > 0) != bClockWise )
|
|
return FALSE;
|
|
|
|
if( (dot.Orient( v2, v3 ) > 0) != bClockWise )
|
|
return FALSE;
|
|
|
|
if( (dot.Orient( v3, v1 ) > 0) != bClockWise )
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
};
|
|
|
|
} |