388 lines
9.6 KiB
C++
388 lines
9.6 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2005 Imetric 3D GmbH *
|
|
* *
|
|
* This file is part of the FreeCAD CAx development system. *
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Library General Public *
|
|
* License as published by the Free Software Foundation; either *
|
|
* version 2 of the License, or (at your option) any later version. *
|
|
* *
|
|
* This library is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Library General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Library General Public *
|
|
* License along with this library; see the file COPYING.LIB. If not, *
|
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
|
* Suite 330, Boston, MA 02111-1307, USA *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
|
|
#ifndef BASE_TOOLS2D_H
|
|
#define BASE_TOOLS2D_H
|
|
|
|
|
|
#include <algorithm>
|
|
#include <cmath>
|
|
#include <stdio.h>
|
|
#include <list>
|
|
#include <vector>
|
|
|
|
#include "Vector3D.h"
|
|
|
|
namespace Base {
|
|
|
|
class Vector2D;
|
|
class BoundBox2D;
|
|
class Line2D;
|
|
class Polygon2D;
|
|
|
|
/**
|
|
* The vector class for 2D calculations.
|
|
*/
|
|
class BaseExport Vector2D
|
|
{
|
|
public:
|
|
double fX, fY;
|
|
|
|
inline Vector2D (void);
|
|
inline Vector2D (float x, float y);
|
|
inline Vector2D (double x, double y);
|
|
inline Vector2D (const Vector2D &rclVct);
|
|
|
|
// methods
|
|
inline double Length (void) const;
|
|
|
|
// operators
|
|
inline Vector2D& operator= (const Vector2D &rclVct);
|
|
inline double operator* (const Vector2D &rclVct) const;
|
|
inline bool operator== (const Vector2D &rclVct) const;
|
|
inline Vector2D operator+ (const Vector2D &rclVct) const;
|
|
inline Vector2D operator- (const Vector2D &rclVct) const;
|
|
inline Vector2D operator/ (double c) const;
|
|
|
|
inline void Set (double fPX, double fPY);
|
|
inline void Scale (double fS);
|
|
inline void Normalize (void);
|
|
double GetAngle (const Vector2D &rclVect) const;
|
|
void ProjToLine (const Vector2D &rclPt, const Vector2D &rclLine);
|
|
};
|
|
|
|
/** BoundBox2D ********************************************/
|
|
|
|
/**
|
|
* Two dimensional bounding box.
|
|
*/
|
|
class BaseExport BoundBox2D
|
|
{
|
|
public:
|
|
double fMinX, fMinY, fMaxX, fMaxY;
|
|
|
|
inline BoundBox2D (void);
|
|
inline BoundBox2D (const BoundBox2D &rclBB);
|
|
inline BoundBox2D (double fX1, double fY1, double fX2, double fY2);
|
|
inline bool IsValid (void);
|
|
|
|
// operators
|
|
inline BoundBox2D& operator= (const BoundBox2D& rclBB);
|
|
inline bool operator== (const BoundBox2D& rclBB) const;
|
|
bool Intersect(const Line2D &rclLine) const;
|
|
bool Intersect(const BoundBox2D &rclBB) const;
|
|
bool Intersect(const Polygon2D &rclPoly) const;
|
|
inline void Add(const Vector2D &rclVct);
|
|
|
|
void SetVoid (void) { fMinX = fMinY = DOUBLE_MAX; fMaxX = fMaxY = -DOUBLE_MAX; }
|
|
|
|
// misc
|
|
bool Contains (const Vector2D &rclV) const;
|
|
};
|
|
|
|
/** Line2D ********************************************/
|
|
|
|
/**
|
|
* 2D line class.
|
|
*/
|
|
class BaseExport Line2D
|
|
{
|
|
public:
|
|
Vector2D clV1, clV2;
|
|
|
|
Line2D (void) {}
|
|
inline Line2D (const Line2D &rclLine);
|
|
inline Line2D (const Vector2D &rclV1, const Vector2D &rclV2);
|
|
|
|
// methods
|
|
inline double Length (void) const;
|
|
BoundBox2D CalcBoundBox (void) const;
|
|
|
|
// operators
|
|
inline Line2D& operator= (const Line2D& rclLine);
|
|
inline bool operator== (const Line2D& rclLine) const;
|
|
|
|
// misc
|
|
inline bool Contains (const Vector2D &rclV) const;
|
|
bool Intersect (const Line2D& rclLine, Vector2D &rclV) const;
|
|
bool Intersect (const Vector2D &rclV, double eps) const;
|
|
bool IntersectAndContain (const Line2D& rclLine, Vector2D &rclV) const;
|
|
Vector2D FromPos (double fDistance) const;
|
|
};
|
|
|
|
/** Polygon2D ********************************************/
|
|
|
|
/**
|
|
* 2D polygon class.
|
|
*/
|
|
class BaseExport Polygon2D
|
|
{
|
|
public:
|
|
Polygon2D (void) {}
|
|
inline Polygon2D (const Polygon2D &rclPoly);
|
|
virtual ~Polygon2D () {}
|
|
|
|
inline Polygon2D& operator = (const Polygon2D &rclP);
|
|
|
|
// admin-interface
|
|
inline size_t GetCtVectors (void) const;
|
|
inline bool Add (const Vector2D &rclVct);
|
|
inline Vector2D& operator[] (size_t ulNdx) const;
|
|
inline Vector2D& At (size_t ulNdx) const;
|
|
inline bool Delete (size_t ulNdx);
|
|
inline void DeleteAll (void);
|
|
|
|
// misc
|
|
BoundBox2D CalcBoundBox (void) const;
|
|
bool Contains (const Vector2D &rclV) const;
|
|
void Intersect (const Polygon2D &rclPolygon, std::list<Polygon2D> &rclResultPolygonList) const;
|
|
bool Intersect (const Vector2D &rclV, double eps) const;
|
|
|
|
private:
|
|
std::vector<Vector2D> _aclVct;
|
|
};
|
|
|
|
/** INLINES ********************************************/
|
|
|
|
inline Vector2D::Vector2D (void)
|
|
: fX(0.0), fY(0.0)
|
|
{
|
|
}
|
|
|
|
inline Vector2D::Vector2D (float x, float y)
|
|
: fX (x), fY (y)
|
|
{
|
|
}
|
|
|
|
inline Vector2D::Vector2D (double x, double y)
|
|
: fX(x),
|
|
fY(y)
|
|
{
|
|
}
|
|
|
|
inline Vector2D::Vector2D (const Vector2D &rclVct)
|
|
: fX(rclVct.fX), fY(rclVct.fY)
|
|
{
|
|
}
|
|
|
|
inline double Vector2D::Length (void) const
|
|
{
|
|
return sqrt ((fX * fX) + (fY * fY));
|
|
}
|
|
|
|
inline Vector2D& Vector2D::operator= (const Vector2D &rclVct)
|
|
{
|
|
fX = rclVct.fX;
|
|
fY = rclVct.fY;
|
|
return *this;
|
|
}
|
|
|
|
inline bool Vector2D::operator== (const Vector2D &rclVct) const
|
|
{
|
|
return (fX == rclVct.fX) && (fY == rclVct.fY);
|
|
}
|
|
|
|
inline Vector2D Vector2D::operator+ (const Vector2D &rclVct) const
|
|
{
|
|
return Vector2D(fX + rclVct.fX, fY + rclVct.fY);
|
|
}
|
|
|
|
inline Vector2D Vector2D::operator- (const Vector2D &rclVct) const
|
|
{
|
|
return Vector2D(fX - rclVct.fX, fY - rclVct.fY);
|
|
}
|
|
|
|
inline double Vector2D::operator* (const Vector2D &rclVct) const
|
|
{
|
|
return (fX * rclVct.fX) + (fY * rclVct.fY);
|
|
}
|
|
|
|
inline Vector2D Vector2D::operator/ (double c) const
|
|
{
|
|
return Vector2D(fX / c, fY / c);
|
|
}
|
|
|
|
inline void Vector2D::Scale (double fS)
|
|
{
|
|
fX *= fS;
|
|
fY *= fS;
|
|
}
|
|
|
|
inline void Vector2D::Normalize (void)
|
|
{
|
|
double fLen = Length();
|
|
if (fLen != 0.0f)
|
|
{
|
|
fX /= fLen;
|
|
fY /= fLen;
|
|
}
|
|
}
|
|
|
|
inline void Vector2D::Set (double fPX, double fPY)
|
|
{
|
|
fX = fPX;
|
|
fY = fPY;
|
|
}
|
|
|
|
inline Polygon2D::Polygon2D (const Polygon2D &rclPoly)
|
|
{
|
|
*this = rclPoly;
|
|
}
|
|
|
|
inline Polygon2D& Polygon2D::operator = (const Polygon2D &rclP)
|
|
{
|
|
_aclVct = rclP._aclVct;
|
|
return *this;
|
|
}
|
|
|
|
inline void Polygon2D::DeleteAll (void)
|
|
{
|
|
_aclVct.clear();
|
|
}
|
|
|
|
inline size_t Polygon2D::GetCtVectors (void) const
|
|
{
|
|
return _aclVct.size ();
|
|
}
|
|
|
|
inline bool Polygon2D::Add (const Vector2D &rclVct)
|
|
{
|
|
_aclVct.push_back (rclVct);
|
|
return true;
|
|
}
|
|
|
|
inline bool Polygon2D::Delete (size_t ulNdx)
|
|
{
|
|
if ( ulNdx < _aclVct.size() )
|
|
{
|
|
std::vector<Vector2D>::iterator it = _aclVct.begin() + ulNdx;
|
|
_aclVct.erase ( it );
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
inline Vector2D& Polygon2D::operator[] (size_t ulNdx) const
|
|
{
|
|
return (Vector2D&) _aclVct[ulNdx];
|
|
}
|
|
|
|
inline Vector2D& Polygon2D::At (size_t ulNdx) const
|
|
{
|
|
return (Vector2D&) _aclVct[ulNdx];
|
|
}
|
|
|
|
|
|
inline Line2D::Line2D (const Line2D &rclLine)
|
|
: clV1 (rclLine.clV1),
|
|
clV2 (rclLine.clV2)
|
|
{
|
|
}
|
|
|
|
inline Line2D::Line2D (const Vector2D &rclV1, const Vector2D &rclV2)
|
|
: clV1 (rclV1), clV2 (rclV2)
|
|
{
|
|
}
|
|
|
|
inline double Line2D::Length (void) const
|
|
{
|
|
return (clV2 - clV1).Length ();
|
|
}
|
|
|
|
inline Line2D& Line2D::operator= (const Line2D& rclLine)
|
|
{
|
|
clV1 = rclLine.clV1;
|
|
clV2 = rclLine.clV2;
|
|
return *this;
|
|
}
|
|
|
|
inline bool Line2D::operator== (const Line2D& rclLine) const
|
|
{
|
|
return (clV1 == rclLine.clV1) && (clV2 == rclLine.clV2);
|
|
}
|
|
|
|
inline bool Line2D::Contains (const Vector2D &rclV) const
|
|
{
|
|
return CalcBoundBox ().Contains (rclV);
|
|
}
|
|
|
|
inline BoundBox2D::BoundBox2D (void)
|
|
{
|
|
fMinX = fMinY = DOUBLE_MAX;
|
|
fMaxX = fMaxY = - DOUBLE_MAX;
|
|
}
|
|
|
|
inline BoundBox2D::BoundBox2D (const BoundBox2D &rclBB)
|
|
: fMinX (rclBB.fMinX),
|
|
fMinY (rclBB.fMinY),
|
|
fMaxX (rclBB.fMaxX),
|
|
fMaxY (rclBB.fMaxY)
|
|
{
|
|
}
|
|
|
|
inline BoundBox2D::BoundBox2D (double fX1, double fY1, double fX2, double fY2)
|
|
{
|
|
fMinX = std::min<double>( fX1, fX2 );
|
|
fMaxX = std::max<double>( fX1, fX2 );
|
|
fMinY = std::min<double>( fY1, fY2 );
|
|
fMaxY = std::max<double>( fY1, fY2 );
|
|
}
|
|
|
|
inline bool BoundBox2D::IsValid (void)
|
|
{
|
|
return (fMaxX >= fMinX) && (fMaxY >= fMinY);
|
|
}
|
|
|
|
inline BoundBox2D& BoundBox2D::operator= (const BoundBox2D& rclBB)
|
|
{
|
|
fMinX = rclBB.fMinX;
|
|
fMinY = rclBB.fMinY;
|
|
fMaxX = rclBB.fMaxX;
|
|
fMaxY = rclBB.fMaxY;
|
|
return *this;
|
|
}
|
|
|
|
inline bool BoundBox2D::operator== (const BoundBox2D& rclBB) const
|
|
{
|
|
return
|
|
(fMinX == rclBB.fMinX) &&
|
|
(fMinY == rclBB.fMinY) &&
|
|
(fMaxX == rclBB.fMaxX) &&
|
|
(fMaxY == rclBB.fMaxY);
|
|
}
|
|
|
|
inline void BoundBox2D::Add(const Vector2D &rclVct)
|
|
{
|
|
fMinX = std::min<double>(fMinX, rclVct.fX);
|
|
fMinY = std::min<double>(fMinY, rclVct.fY);
|
|
fMaxX = std::max<double>(fMaxX, rclVct.fX);
|
|
fMaxY = std::max<double>(fMaxY, rclVct.fY);
|
|
}
|
|
|
|
} // namespace Base
|
|
|
|
#endif // BASE_TOOLS2D_H
|
|
|
|
|