| |
|
|
| |
|
|
| |
|
|
| |
| |
| |
| |
| |
| |
| #pragma once |
| #ifdef _MSC_VER |
| # pragma warning(disable : 4996) |
| # ifndef WINVER |
| # define WINVER 0x501 |
| # endif |
| #endif |
|
|
| #include <cmath> |
| #include <algorithm> |
| #include <vector> |
| #include <list> |
| #include <iostream> |
| #include <fstream> |
| #include <string.h> |
|
|
| using namespace std; |
|
|
|
|
| namespace geoff_geometry |
| { |
|
|
| |
| enum OFFSET_METHODS |
| { |
| NO_ELIMINATION = 0, |
| BASIC_OFFSET, |
| ROLLINGBALL_OFFSET |
| }; |
|
|
| enum SPAN_IDS |
| { |
| UNMARKED = 0xe0000000, |
| ROLL_AROUND, |
| INTERSECTION, |
| FULL_CIRCLE_KURVE |
| }; |
|
|
|
|
| class Vector2d; |
| class Vector3d; |
| class Point; |
| class Point3d; |
| class CLine; |
| class Circle; |
| class Span; |
| class Kurve; |
| class Line; |
|
|
|
|
| enum UNITS_TYPE |
| { |
| MM = 0, |
| METRES, |
| INCHES |
| }; |
|
|
| extern int UNITS; |
| extern double TOLERANCE; |
| extern double TOLERANCE_SQ; |
| extern double TIGHT_TOLERANCE; |
| extern double UNIT_VECTOR_TOLERANCE; |
| extern double SMALL_ANGLE; |
| extern double SIN_SMALL_ANGLE; |
| extern double COS_SMALL_ANGLE; |
| extern double RESOLUTION; |
|
|
| void set_Tolerances(int mode); |
| double mm(double value); |
|
|
| inline bool FEQ(double a, double b, double tolerance = TOLERANCE) |
| { |
| return fabs(a - b) <= tolerance; |
| } |
| inline bool FNE(double a, double b, double tolerance = TOLERANCE) |
| { |
| return fabs(a - b) > tolerance; |
| } |
|
|
| inline bool FEQZ(double a, double tolerance = TIGHT_TOLERANCE) |
| { |
| return fabs(a) <= tolerance; |
| } |
| inline bool FNEZ(double a, double tolerance = TIGHT_TOLERANCE) |
| { |
| return fabs(a) > tolerance; |
| } |
|
|
| #define PI 3.1415926535897932384626433832795e0 |
| #define DegreesToRadians (PI / 180.0e0) |
| #define RadiansToDegrees (180.0e0 / PI) |
| #define NEARLY_ONE 0.99999999999e0 |
| #define CPTANGENTTOL 1.0e-04 |
|
|
| #define TANTO -1 |
| #define ANTITANTO 1 |
|
|
| #define TANGENT 0 |
|
|
| #define NEARINT 1 |
| #define FARINT -1 |
|
|
| #define LEFTINT 1 |
| #define RIGHTINT -1 |
|
|
| #define CFILLET 0 |
| #define CHAMFER 1 |
|
|
| #define GEOFF_LEFT 1 |
| #define NONE 0 |
| #define GEOFF_RIGHT -1 |
|
|
|
|
| #define LINEAR 0 |
| #define ACW 1 |
| #define CW -1 |
|
|
| const wchar_t* getMessage(const wchar_t* original); |
| void FAILURE(const wchar_t* str); |
| void FAILURE(const std::wstring& str); |
|
|
| enum MESSAGE_GROUPS |
| { |
| GENERAL_MESSAGES, |
| GEOMETRY_ERROR_MESSAGES, |
| PARAMSPMP |
| }; |
|
|
| enum GENERAL_MESSAGES |
| { |
| MES_TITLE = 0, |
| MES_UNFINISHEDCODING, |
| MES_ERRORFILENAME, |
| MES_LOGFILE, |
| MES_LOGFILE1, |
| MES_P4CMENU, |
| MES_P4CMENUHINT |
| }; |
|
|
| enum GEOMETRY_ERROR_MESSAGES |
| { |
| MES_DIFFSCALE = 1000, |
| MES_POINTONCENTRE, |
| MES_INVALIDARC, |
| MES_LOFTUNEQUALSPANCOUNT, |
| MES_EQUALSPANCOUNTFAILED, |
| MES_CANNOTTRIMSPAN, |
| MES_INDEXOUTOFRANGE, |
| MES_BAD_VERTEX_NUMBER, |
| MES_BAD_REF_OFFSET, |
| MES_BAD_SEC_OFFSET, |
| MES_ROLLINGBALL4AXIS_ERROR, |
| MES_INPUT_EQUALSPANCOUNT, |
| MES_INVALIDPLANE |
| }; |
|
|
| |
| class Matrix |
| { |
| protected: |
| public: |
| double e[16]; |
| bool m_unit; |
| int m_mirrored; |
|
|
| public: |
| |
| Matrix(); |
| Matrix(double m[16]); |
| |
|
|
| ~Matrix() {}; |
|
|
| |
| bool operator==(const Matrix& m) const; |
| bool operator!=(const Matrix& m) const |
| { |
| return !(*this == m); |
| } |
|
|
| |
| void Unit(); |
| void Get(double* p) const; |
| void Put(double* p); |
| void Translate(double x, double y, double z = 0); |
|
|
| void Rotate(double sinang, double cosang, Vector3d* rotAxis); |
| void Rotate(double angle, Vector3d* rotAxis); |
|
|
| void Rotate(double sinang, double cosang, int Axis); |
| void Rotate(double angle, int Axis); |
|
|
| void Scale(double scale); |
| void Scale(double scalex, double scaley, double scalez); |
|
|
| void Multiply(Matrix& m); |
| |
| void Transform(double p0[3]) const; |
| void Transform(double p0[3], double p1[3]) const; |
| void Transform2d(double p0[2], double p1[2]) const; |
|
|
| int IsMirrored(); |
| int IsUnit(); |
| void GetTranslate(double& x, double& y, double& z) const; |
| void GetScale(double& sx, double& sy, double& sz) const; |
| bool GetScale(double& sx) const; |
| void GetRotation(double& ax, double& ay, double& az) const; |
|
|
| Matrix Inverse(); |
| }; |
|
|
| extern Matrix UnitMatrix; |
|
|
|
|
| |
| class Point |
| { |
| friend wostream& operator<<(wostream& op, Point& p); |
|
|
| public: |
| bool ok; |
| double x; |
| double y; |
|
|
| |
| inline Point() |
| { |
| x = 0; |
| y = 0; |
| ok = false; |
| } |
| inline Point(double xord, double yord, bool okay = true) |
| { |
| x = xord; |
| y = yord; |
| ok = okay; |
| } |
|
|
| |
| |
| |
| |
| |
| |
|
|
| Point(const Point3d& p); |
| Point(const Vector2d& v); |
|
|
| |
| bool operator==(const Point& p) const; |
| bool operator!=(const Point& p) const |
| { |
| return !(*this == p); |
| } |
| inline Point operator+(const Point& p) const |
| { |
| return Point(x + p.x, y + p.y); |
| } |
| inline Point operator+=(const Point& p) |
| { |
| return Point(x += p.x, y += p.y); |
| } |
| Point operator+(const Vector2d& v) const; |
|
|
| |
| |
|
|
| |
| Point Transform(const Matrix& m); |
| double Dist(const Point& p) const; |
| double DistSq(const Point& p) const; |
| double Dist(const CLine& cl) const; |
| Point Mid(const Point& p, double factor = .5) const; |
| void get(double xyz[2]) |
| { |
| xyz[0] = x; |
| xyz[1] = y; |
| } |
| }; |
|
|
|
|
| #define INVALID_POINT Point(9.9999999e50, 0, false) |
| #define INVALID_POINT3D Point3d(9.9999999e50, 0, 0, false) |
| #define INVALID_CLINE CLine(INVALID_POINT, 1, 0, false) |
| #define INVALID_CIRCLE Circle(INVALID_POINT, 0) |
|
|
| |
| class Point3d |
| { |
| friend wostream& operator<<(wostream& op, Point3d& p); |
|
|
| public: |
| |
| double x; |
| double y; |
| double z; |
|
|
| |
| inline Point3d() |
| { |
| x = 0; |
| y = 0; |
| z = 0; |
| } |
| inline Point3d(const double* xyz) |
| { |
| x = xyz[0], y = xyz[1]; |
| z = xyz[2]; |
| } |
| inline Point3d(double xord, double yord, double zord = 0 ) |
| { |
| x = xord; |
| y = yord; |
| z = zord; |
| } |
| |
| |
| |
| |
| inline Point3d(const Point& p) |
| { |
| x = p.x; |
| y = p.y; |
| z = 0; |
| } |
| |
| inline Point3d(const Point& p, double zord) |
| { |
| x = p.x; |
| y = p.y; |
| z = zord; |
| } |
| Point3d(const Vector3d& v); |
|
|
| |
| |
|
|
| |
| bool operator==(const Point3d& p) const; |
| bool operator!=(const Point3d& p) const |
| { |
| return !(*this == p); |
| } |
| Point3d operator+(const Vector3d& v) const; |
|
|
|
|
| |
| #ifdef PEPSDLL |
| void ToPeps(int id, bool draw = true); |
| #endif |
| Point3d Transform(const Matrix& m); |
| double Dist(const Point3d& p) const; |
| double DistSq(const Point3d& p) const; |
| Point3d Mid(const Point3d& p, double factor = 0.5) const; |
| void get(double xyz[3]) |
| { |
| xyz[0] = x; |
| xyz[1] = y; |
| xyz[2] = z; |
| } |
| double* getBuffer() |
| { |
| return &this->x; |
| }; |
| const double* getBuffer() const |
| { |
| return &this->x; |
| }; |
| }; |
|
|
| |
| class Vector2d |
| { |
| friend wostream& operator<<(wostream& op, Vector2d& v); |
|
|
| private: |
| double dx, dy; |
|
|
| public: |
| |
| inline Vector2d() |
| { |
| dx = 0; |
| dy = 0; |
| } |
| |
| Vector2d(const Vector3d& v); |
| inline Vector2d(double x, double y) |
| { |
| dx = x, dy = y; |
| } |
| inline Vector2d(const Point& p0, const Point& p1) |
| { |
| dx = p1.x - p0.x; |
| dy = p1.y - p0.y; |
| } |
| inline Vector2d(const Point* p0, const Point* p1) |
| { |
| dx = p1->x - p0->x; |
| dy = p1->y - p0->y; |
| } |
| inline Vector2d(const Point& p) |
| { |
| dx = p.x; |
| dy = p.y; |
| } |
| inline Vector2d(double angle) |
| { |
| dx = cos(angle *= DegreesToRadians); |
| dy = sin(angle); |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| inline Vector2d operator+(const Vector2d& v) const |
| { |
| return Vector2d(dx + v.dx, dy + v.dy); |
| } |
| inline Point operator+(const Point& p) const |
| { |
| return Point(this->dx + p.x, this->dy + p.y); |
| } |
| inline Vector2d operator+(const double d) |
| { |
| return Vector2d(dx + d, dy + d); |
| }; |
|
|
| inline const Vector2d& operator+=(const Vector2d& v) |
| { |
| dx += v.dx; |
| dy += v.dy; |
| return *this; |
| } |
| inline Vector2d operator-(const Vector2d& v) const |
| { |
| return Vector2d(dx - v.dx, dy - v.dy); |
| } |
| inline const Vector2d& operator-=(const Vector2d& v) |
| { |
| dx -= v.dx; |
| dy -= v.dy; |
| return *this; |
| } |
| inline Vector2d operator-(const double d) |
| { |
| return Vector2d(dx - d, dy - d); |
| }; |
|
|
| inline const Vector2d operator-(void) const |
| { |
| return Vector2d(-dx, -dy); |
| } |
|
|
| inline double operator*(const Vector2d& v) const |
| { |
| return (dx * v.dx + dy * v.dy); |
| } |
| inline Vector2d operator*(double c) const |
| { |
| return Vector2d(dx * c, dy * c); |
| } |
| inline const Vector2d& operator*=(double c) |
| { |
| dx *= c; |
| dy *= c; |
| return *this; |
| } |
| inline Vector2d operator*(int c) const |
| { |
| return Vector2d(dx * (double)c, dy * (double)c); |
| } |
|
|
| inline double operator^(const Vector2d& v) const |
| { |
| return (dx * v.dy - dy * v.dx); |
| } |
| inline Vector2d operator~(void) const |
| { |
| return Vector2d(-dy, dx); |
| } |
|
|
| bool operator==(const Vector2d& v) const; |
| inline bool operator!=(const Vector2d& v) const |
| { |
| return !(*this == v); |
| } |
|
|
|
|
| |
| void get(double xyz[2]) |
| { |
| xyz[0] = dx; |
| xyz[1] = dy; |
| } |
| inline double getx() const |
| { |
| return dx; |
| } |
| inline double gety() const |
| { |
| return dy; |
| } |
| inline void putx(double x) |
| { |
| dx = x; |
| } |
| inline void puty(double y) |
| { |
| dy = y; |
| } |
| double normalise() |
| { |
| double m = magnitude(); |
| if (m < TIGHT_TOLERANCE) { |
| dx = dy = 0; |
| return 0; |
| } |
| dx /= m; |
| dy /= m; |
| return m; |
| } |
| inline double magnitudesqd(void) const |
| { |
| return (dx * dx + dy * dy); |
| } |
| inline double magnitude(void) const |
| { |
| return (sqrt(magnitudesqd())); |
| } |
| void Rotate(double cosa, double sina) |
| { |
| double temp = -dy * sina + dx * cosa; |
| dy = dx * sina + cosa * dy; |
| dx = temp; |
| } |
| inline void Rotate(double angle) |
| { |
| if (FEQZ(angle) == true) { |
| return; |
| } |
| Rotate(cos(angle), sin(angle)); |
| } |
| void Transform(const Matrix& m); |
|
|
| |
| |
| }; |
|
|
|
|
| |
| class Vector3d |
| { |
| friend wostream& operator<<(wostream& op, Vector3d& v); |
|
|
| private: |
| double dx, dy, dz; |
|
|
| public: |
| |
| Vector3d() |
| { |
| dx = 0; |
| dy = 0; |
| dz = 0; |
| } |
| |
| Vector3d(double x, double y, double z = 0) |
| { |
| dx = x, dy = y; |
| dz = z; |
| } |
| Vector3d(const double* x) |
| { |
| dx = x[0], dy = x[1]; |
| dz = x[2]; |
| } |
| Vector3d(const double* x0, const double* x1) |
| { |
| dx = x1[0] - x0[0], dy = x1[1] - x0[1]; |
| dz = x1[2] - x0[2]; |
| } |
| Vector3d(const Point3d& p0, const Point3d& p1) |
| { |
| dx = p1.x - p0.x; |
| dy = p1.y - p0.y; |
| dz = p1.z - p0.z; |
| } |
| Vector3d(const Point3d& p) |
| { |
| dx = p.x; |
| dy = p.y; |
| dz = p.z; |
| } |
| Vector3d(const Vector2d& v) |
| { |
| dx = v.getx(); |
| dy = v.gety(); |
| dz = 0; |
| } |
|
|
| |
| bool operator==(const Vector3d& v) const |
| { |
| return ( |
| FEQ(dx, v.dx, UNIT_VECTOR_TOLERANCE) && FEQ(dy, v.dy, UNIT_VECTOR_TOLERANCE) |
| && FEQ(dz, v.dz, UNIT_VECTOR_TOLERANCE) |
| ); |
| } |
| bool operator!=(const Vector3d& v) const |
| { |
| return (!(*this == v)); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| inline Point3d operator+(const Point3d& p) const |
| { |
| return Point3d(dx + p.x, dy + p.y, dz + p.z); |
| } |
| Vector3d operator+(const Vector3d& v) const |
| { |
| return Vector3d(dx + v.dx, dy + v.dy, dz + v.dz); |
| } |
| const Vector3d& operator+=(const Vector3d& v) |
| { |
| dx += v.dx; |
| dy += v.dy; |
| dz += v.dz; |
| return *this; |
| } |
| Vector3d operator-(const Vector3d& v) const |
| { |
| return Vector3d(dx - v.dx, dy - v.dy, dz - v.dz); |
| } |
| const Vector3d& operator-=(const Vector3d& v) |
| { |
| dx -= v.dx; |
| dy -= v.dy; |
| dz -= v.dz; |
| return *this; |
| } |
|
|
| const Vector3d operator-(void) const |
| { |
| return Vector3d(-dx, -dy, -dz); |
| } |
|
|
| double operator*(const Vector3d& v) const |
| { |
| return (dx * v.dx + dy * v.dy + dz * v.dz); |
| } |
|
|
| const Vector3d& operator*=(double c) |
| { |
| dx *= c; |
| dy *= c; |
| dz *= c; |
| return *this; |
| } |
| friend const Vector3d operator*(const Vector3d& v, double c) |
| { |
| return Vector3d(v.dx * c, v.dy * c, v.dz * c); |
| } |
| friend const Vector3d operator*(double c, const Vector3d& v) |
| { |
| return Vector3d(v.dx * c, v.dy * c, v.dz * c); |
| } |
| friend const Vector3d operator/(const Vector3d& v, double c) |
| { |
| return Vector3d(v.dx / c, v.dy / c, v.dz / c); |
| } |
|
|
| const Vector3d operator^(const Vector3d& v) const |
| { |
| return Vector3d(dy * v.dz - dz * v.dy, dz * v.dx - dx * v.dz, dx * v.dy - dy * v.dx); |
| } |
|
|
| |
| |
| |
| inline void get(double xyz[3]) const |
| { |
| xyz[0] = dx; |
| xyz[1] = dy; |
| xyz[2] = dz; |
| } |
| inline double getx() const |
| { |
| return dx; |
| } |
| inline double gety() const |
| { |
| return dy; |
| } |
| inline double getz() const |
| { |
| return dz; |
| } |
| inline void putx(double x) |
| { |
| dx = x; |
| } |
| inline void puty(double y) |
| { |
| dy = y; |
| } |
| inline void putz(double z) |
| { |
| dz = z; |
| } |
| double normalise() |
| { |
| double m = magnitude(); |
| if (m < 1.0e-09) { |
| dx = dy = dz = 0; |
| return 0; |
| } |
| dx /= m; |
| dy /= m; |
| dz /= m; |
| return m; |
| } |
| inline double magnitude(void) const |
| { |
| return (sqrt(dx * dx + dy * dy + dz * dz)); |
| } |
| inline double magnitudeSq(void) const |
| { |
| return (dx * dx + dy * dy + dz * dz); |
| } |
| void Transform(const Matrix& m); |
| void arbitrary_axes(Vector3d& x, Vector3d& y); |
| int setCartesianAxes(Vector3d& b, Vector3d& c); |
| double* getBuffer() |
| { |
| return &this->dx; |
| }; |
| const double* getBuffer() const |
| { |
| return &this->dx; |
| }; |
|
|
| |
| |
| }; |
|
|
| #define ORIGIN Point3d(0, 0, 0) |
| #define NULL_VECTOR Vector3d(0, 0, 0) |
| #define Z_VECTOR Vector3d(0, 0, 1) |
| #define Y_VECTOR Vector3d(0, 1, 0) |
| #define X_VECTOR Vector3d(1, 0, 0) |
|
|
| |
| class CLine |
| { |
| friend wostream& operator<<(wostream& op, CLine& cl); |
|
|
| public: |
| bool ok; |
| Point p; |
| Vector2d v; |
|
|
| |
| inline CLine() |
| { |
| ok = false; |
| }; |
| inline CLine(const Point& p0, double dx, double dy, bool normalise = true) |
| { |
| p = p0; |
| v = Vector2d(dx, dy); |
| if (normalise) { |
| Normalise(); |
| } |
| }; |
| inline CLine(const Point& p0, const Vector2d& v0, bool normalise = true) |
| { |
| p = p0; |
| v = v0; |
| if (normalise) { |
| Normalise(); |
| } |
| }; |
| |
| |
| |
| |
| |
| |
| inline CLine(const Point& p0, const Point& p1) |
| { |
| p = p0; |
| v = Vector2d(p0, p1); |
| Normalise(); |
| }; |
| CLine(const Span& sp); |
|
|
| |
| const CLine operator~(void); |
| const CLine& operator=(const Point& p0) |
| { |
| p.x = p0.x; |
| p.y = p0.y; |
| return *this; |
| }; |
|
|
| |
| double c(); |
| void Normalise(); |
| #ifdef PEPSDLL |
| void ToPeps(int id, bool draw = true); |
| void DelPeps(int id); |
| #endif |
| CLine Transform(Matrix& m); |
| Point Intof(const CLine& s); |
| Point Intof(int NF, const Circle& c); |
| Point Intof(int NF, const Circle& c, Point& otherInters); |
| double Dist(const Point& p1) const; |
| CLine Bisector(const CLine& s); |
|
|
| |
| |
| }; |
|
|
| #define HORIZ_CLINE CLine(geoff_geometry::Point(0, 0), 1.0, 0.0, true) |
|
|
|
|
| |
| class Circle |
| { |
| friend wostream& operator<<(wostream& op, Circle& c); |
|
|
| public: |
| bool ok; |
| Point pc; |
| double radius; |
|
|
| |
| inline Circle() |
| { |
| ok = false; |
| radius = 0; |
| } |
| Circle(const Point& p, double r); |
| Circle(const Point& p, const Point& pc); |
| |
| |
| |
| |
| Circle(const Span& sp); |
|
|
| |
| #ifdef PEPSDLL |
| void ToPeps(int id, bool draw = true); |
| void DelPeps(int id); |
| #endif |
| bool operator==(const Circle& c) const; |
| bool operator!=(const Circle& c) const |
| { |
| return !(*this == c); |
| } |
| Circle Transform(Matrix& m); |
| Point Intof(int LR, const Circle& c1); |
| Point Intof( |
| int LR, |
| const Circle& c1, |
| Point& otherInters |
| ); |
| int Intof( |
| const Circle& c1, |
| Point& leftInters, |
| Point& rightInters |
| ); |
| |
| CLine Tanto(int AT, double angle, const CLine& s0) const; |
| |
| }; |
|
|
| |
| class Box |
| { |
| public: |
| Point min; |
| Point max; |
| bool ok; |
|
|
| Box() |
| { |
| min.x = min.y = 1.0e61; |
| max.x = max.y = -1.0e61; |
| ok = false; |
| }; |
| Box(Point& pmin, Point& pmax) |
| { |
| min = pmin; |
| max = pmax; |
| ok = true; |
| }; |
|
|
| bool outside(const Box& b) const; |
| void combine(const Box& b); |
| }; |
|
|
| |
| class Box3d |
| { |
| public: |
| Point3d min; |
| Point3d max; |
| bool ok; |
|
|
| Box3d() |
| { |
| min.x = min.y = min.z = 1.0e61; |
| max.x = max.y = max.z = -1.0e61; |
| ok = false; |
| }; |
| Box3d(const Point3d& pmin, const Point3d& pmax) |
| { |
| min = pmin; |
| max = pmax; |
| ok = true; |
| }; |
|
|
| bool outside(const Box3d& b) const; |
| void combine(const Box3d& b); |
| }; |
|
|
| inline void MinMax(const Point& p, Point& pmin, Point& pmax) |
| { |
| if (p.x > pmax.x) { |
| pmax.x = p.x; |
| } |
| if (p.y > pmax.y) { |
| pmax.y = p.y; |
| } |
| if (p.x < pmin.x) { |
| pmin.x = p.x; |
| } |
| if (p.y < pmin.y) { |
| pmin.y = p.y; |
| } |
| } |
|
|
| inline void MinMax(const Point3d& p, Point3d& pmin, Point3d& pmax) |
| { |
| if (p.x > pmax.x) { |
| pmax.x = p.x; |
| } |
| if (p.y > pmax.y) { |
| pmax.y = p.y; |
| } |
| if (p.z > pmax.z) { |
| pmax.z = p.z; |
| } |
| if (p.x < pmin.x) { |
| pmin.x = p.x; |
| } |
| if (p.y < pmin.y) { |
| pmin.y = p.y; |
| } |
| if (p.z < pmin.z) { |
| pmin.z = p.z; |
| } |
| } |
|
|
|
|
| |
| class Span |
| { |
| friend wostream& operator<<(wostream& op, Span& span); |
|
|
| public: |
| Point p0; |
| Point p1; |
| Point pc; |
| int dir; |
| int ID; |
| bool ok; |
|
|
| bool returnSpanProperties; |
| Vector2d vs; |
| Vector2d ve; |
|
|
| double length; |
| double radius; |
| double angle; |
|
|
| Box box; |
|
|
| bool NullSpan; |
|
|
| |
| void SetProperties(bool returnProperties); |
| Span Offset(double offset); |
| int Split(double tolerance); |
| void SplitMatrix(int num_vectors, Matrix* matrix); |
| void minmax(Box& box, bool start = true); |
| void minmax(Point& pmin, Point& pmax, bool start = true); |
| int Intof(const Span& sp, Point& pInt1, Point& pInt2, double t[4]) const; |
| void Transform(const Matrix& m, bool setprops = true); |
| Point Near(const Point& p) const; |
| Point NearOn(const Point& p) const; |
| Point Mid() const; |
| Point MidPerim(double d) const; |
| Point MidParam(double param) const; |
| bool OnSpan(const Point& p) const; |
| |
| bool OnSpan( |
| const Point& p, |
| double* t |
| ) const; |
| bool JoinSeparateSpans(Span& sp); |
| Span BlendTwoSpans(Span& sp2, double radius, double maxt); |
| bool isJoinable(const Span& sp) const; |
| Vector2d GetVector(double fraction) const; |
| |
|
|
| |
| Span() |
| { |
| dir = 0; |
| ID = 0; |
| ok = false; |
| returnSpanProperties = false; |
| length = 0; |
| radius = 0; |
| angle = 0; |
| NullSpan = false; |
| } |
| Span(int spandir, const Point& pn, const Point& pf, const Point& c) |
| { |
| dir = spandir; |
| p0 = pn, p1 = pf, pc = c; |
| ID = 0; |
| SetProperties(true); |
| ok = p0.ok; |
| }; |
|
|
| |
| |
| |
| }; |
|
|
| |
| double atn360(double dx, double dy); |
|
|
| |
| |
| |
| |
|
|
| double Dist(const Point3d* p, const Vector3d* vl, const Point3d* pf); |
| |
| double DistSq( |
| const Point3d* p, |
| const Vector3d* vl, |
| const Point3d* pf |
| ); |
| double Dist(const Circle& c, const Point& p); |
| double Dist( |
| const Point& p0, |
| const Circle& c, |
| const Point& p1 |
| ); |
| double Dist(const CLine& s, const Circle& c); |
| double Dist(const Circle& c0, const Circle& c1); |
| double IncludedAngle(const Vector2d& v0, const Vector2d& v1, int dir = 1); |
| double IncludedAngle(const Vector3d& v0, const Vector3d& v1, const Vector3d& normal, int dir = 1); |
| inline double IncludedAngle(const CLine& s0, const CLine& s1, int dir = 1) |
| { |
| return IncludedAngle(s0.v, s1.v, dir); |
| } |
|
|
|
|
| |
| Point Mid(const Point& p0, const Point& p1, double factor = 0.5); |
| Point Mid(const Span& sp); |
| Point Rel(const Point& p, double x, double y); |
| Point Polar(const Point& p, double angle, double r); |
| Point AtAngle(const Circle& c, double angle); |
| Point XonCLine(const CLine& s, double xval); |
| Point YonCLine(const CLine& s, double yval); |
| Point Intof(const CLine& s0, const CLine& s1); |
| Point Intof(int NF, const CLine& s, const Circle& c); |
| Point Intof( |
| int NF, |
| const CLine& s, |
| const Circle& c, |
| Point& otherInters |
| ); |
| Point Intof(int LR, const Circle& c0, const Circle& c1); |
| Point Intof( |
| int LR, |
| const Circle& c0, |
| const Circle& c1, |
| Point& otherInters |
| ); |
| int Intof(const Circle& c0, const Circle& c1, Point& pLeft, Point& pRight); |
| Point Along(const CLine& s, double d); |
| Point Along(const CLine& s, double d, const Point& p); |
| Point Around(const Circle& c, double d, const Point& p); |
| Point On(const CLine& s, const Point& p); |
| Point On(const Circle& c, const Point& p); |
|
|
| |
|
|
| CLine AtAngle( |
| double angle, |
| const Point& p, |
| const CLine& s = HORIZ_CLINE |
| ); |
| CLine Tanto( |
| int AT, |
| const Circle& c, |
| double angle, |
| const CLine& s0 = HORIZ_CLINE |
| ); |
| CLine Tanto(int AT, const Circle& c, const Point& p); |
| CLine Tanto(int AT0, const Circle& c0, int AT1, const Circle& c1); |
| CLine Normal(const CLine& s); |
| CLine Normal(const CLine& s, const Point& p); |
| CLine Parallel(int LR, const CLine& s, double distance); |
| CLine Parallel(const CLine& cl, const Point& p); |
|
|
|
|
| |
| Circle Thro(const Point& p0, const Point& p1); |
| Circle Thro(const Point& p0, const Point& p1, const Point& p2); |
| Circle Tanto( |
| int NF, |
| const CLine& s0, |
| const Point& p, |
| double rad |
| ); |
| Circle Thro(int LR, const Point& p0, const Point& p1, double rad); |
| Circle Tanto( |
| int AT1, |
| const CLine& s1, |
| int AT2, |
| const CLine& s2, |
| double rad |
| ); |
| Circle Tanto( |
| int AT1, |
| const CLine& s1, |
| int AT2, |
| const CLine& s2, |
| int AT3, |
| const CLine& s3 |
| ); |
| Circle Tanto( |
| int LR, |
| int AT, |
| const Circle& c, |
| const Point& p, |
| double rad |
| ); |
| Circle Tanto( |
| int NF, |
| int AT0, |
| const CLine& s0, |
| int AT1, |
| const Circle& c1, |
| double rad |
| ); |
| Circle Tanto( |
| int LR, |
| int AT0, |
| const Circle& c0, |
| int AT1, |
| const Circle& c1, |
| double rad |
| ); |
| Circle Tanto( |
| int LR, |
| int AT1, |
| const Circle& c1, |
| int AT2, |
| const Circle& c2, |
| int AT3, |
| const Circle c3 |
| ); |
| int apolloniusProblem( |
| int AT1, |
| const Circle& c1, |
| int AT2, |
| const Circle& c2, |
| int AT3, |
| const Circle& c3, |
| Circle& Solution1, |
| Circle& Solution2 |
| ); |
| int apolloniusProblem( |
| int AT1, |
| const Circle& c1, |
| int AT2, |
| const Circle& c2, |
| int AT3, |
| const CLine& cl3, |
| Circle& Solution1, |
| Circle& Solution2 |
| ); |
| int apolloniusProblem( |
| int AT1, |
| const Circle& c1, |
| int AT2, |
| const CLine& cl2, |
| int AT3, |
| const CLine& cl3, |
| Circle& Solution1, |
| Circle& Solution2 |
| ); |
|
|
| |
| |
| |
| |
| |
| |
| Circle Parallel(int LR, const Circle& c, double distance); |
|
|
|
|
| |
| inline double Radians(double degrees) |
| { |
| return degrees * PI / 180; |
| } |
| inline double Degrees(double radians) |
| { |
| return radians * 180 / PI; |
| } |
| int quadratic(double a, double b, double c, double& x0, double& x1); |
|
|
| int corner( |
| const Vector2d& v0, |
| const Vector2d& v1, |
| double cpTol = CPTANGENTTOL |
| ); |
| inline int corner(const Span& span, const Span& next, double cpTol = CPTANGENTTOL) |
| { |
| return corner((Vector2d)span.ve, (Vector2d)next.vs, cpTol); |
| } |
|
|
| Line IsPtsLine(const double* a, int n, double tolerance, double* deviation); |
| |
|
|
| class Plane |
| { |
| friend wostream& operator<<(wostream& op, Plane& pl); |
|
|
| public: |
| bool ok; |
| double d; |
| Vector3d normal; |
| |
| Plane() |
| { |
| ok = false; |
| d = 0; |
| } |
| Plane(double dist, const Vector3d& n); |
| Plane(const Point3d& p0, const Point3d& p1, const Point3d& p2); |
| Plane(const Point3d& p0, const Vector3d& n, bool normalise = true); |
|
|
| |
| double Dist(const Point3d& p) const; |
| bool Intof(const Line& l, Point3d& intof, double& t) const; |
| |
| bool Intof(const Plane& pl, Line& intof) const; |
| bool Intof(const Plane& pl0, const Plane& pl1, Point3d& intof) const; |
| Point3d Near(const Point3d& p) const; |
| void Mirrored(Matrix* m); |
| }; |
|
|
|
|
| #define SPANSTORAGE 32 |
|
|
| class spVertex |
| { |
| friend wostream& operator<<(wostream& op, spVertex& sp); |
|
|
| public: |
| int type; |
| int spanid; |
| Point p; |
| Point pc; |
| spVertex() |
| { |
| type = 0; |
| spanid = 0; |
| } |
| spVertex(int t, const Point& point, const Point& centre) |
| : type(t) |
| , spanid(0) |
| , p(point) |
| , pc(centre) {}; |
|
|
| bool operator==(spVertex& spv) |
| { |
| |
| if (this->type != spv.type) { |
| return false; |
| } |
| if (this->p != spv.p) { |
| return false; |
| } |
| if (this->type != LINEAR) { |
| if (this->pc != spv.pc) { |
| return false; |
| } |
| } |
| return true; |
| } |
|
|
| bool operator!=(spVertex& spv) |
| { |
| return !(*this == spv); |
| } |
| }; |
|
|
|
|
| class SpanDataObject |
| { |
| |
| public: |
| int method; |
|
|
| SpanDataObject(int meth) |
| { |
| method = meth; |
| }; |
| SpanDataObject(const SpanDataObject* obj) |
| { |
| method = obj->method; |
| }; |
| }; |
|
|
| class SpanVertex |
| { |
| public: |
| int type[SPANSTORAGE]; |
| int spanid[SPANSTORAGE]; |
| const SpanDataObject* index[SPANSTORAGE]; |
| double x[SPANSTORAGE], y[SPANSTORAGE]; |
| double xc[SPANSTORAGE], yc[SPANSTORAGE]; |
| public: |
| |
| void Add(int offset, int type, const Point& p0, const Point& pc, int ID = UNMARKED); |
| const SpanDataObject* GetIndex(int offset) const; |
| void AddSpanID(int offset, int ID); |
| SpanVertex(); |
| ~SpanVertex(); |
| const SpanVertex& operator=(const SpanVertex& spv); |
|
|
| void Add(int offset, const SpanDataObject* Index); |
| const SpanDataObject* Get(int offset); |
| int Get(int offset, Point& pe, Point& pc); |
| int GetSpanID(int offset); |
| }; |
|
|
|
|
| #ifdef _MSC_VER |
| # pragma warning(disable : 4522) |
| #endif |
|
|
| class Kurve: public Matrix |
| { |
| friend wofstream& operator<<(wofstream& op, Kurve& k); |
| friend wifstream& operator>>(wifstream& op, Kurve& k); |
|
|
| protected: |
| vector<SpanVertex*> m_spans; |
| bool m_started; |
| int m_nVertices; |
| bool m_isReversed; |
|
|
| public: |
| |
| struct spanCompare |
| { |
| int dir; |
| double length; |
| double cp; |
| double dp; |
| }; |
| |
| Kurve() |
| { |
| m_started = false; |
| m_nVertices = 0; |
| m_isReversed = false; |
| }; |
| Kurve(const Kurve& k0); |
| const Kurve& operator=(const Kurve& k); |
| const Kurve& operator=(const Matrix& m); |
|
|
| bool operator==(const Kurve& k) const; |
| bool operator!=(const Kurve& k) const |
| { |
| return !(*this == k); |
| } |
|
|
|
|
| |
| ~Kurve(); |
|
|
| |
| inline int nSpans() const |
| { |
| return (m_nVertices) ? m_nVertices - 1 : 0; |
| } |
| bool Closed() const; |
| inline bool Started() const |
| { |
| return m_started; |
| }; |
| void FullCircle(int dir, const Point& c, double radius); |
| void Start(); |
| void Start(const Point& p); |
| bool Add(const spVertex& spv, bool AddNullSpans = true); |
| void Get(int vertex, spVertex& spv) const; |
| bool Add(const Span& sp, bool AddNullSpans = true); |
| bool Add(int type, const Point& p0, const Point& pc, bool AddNullSpans = true); |
| void AddSpanID(int ID); |
| bool Add(const Point& p0, bool AddNullSpans = true); |
| void Add(); |
| void Add(const Kurve* k, bool AddNullSpans = true); |
| void StoreAllSpans(std::vector<Span>& kSpans) const; |
| |
| void Clear(); |
|
|
| void Replace(int vertexnumber, const spVertex& spv); |
| void Replace(int vertexnumber, int type, const Point& p, const Point& pc, int ID = UNMARKED); |
| int GetSpanID(int spanVertexNumber) const; |
| int Get(int spanVertexNumber, Point& p, Point& pc) const; |
| void Get(std::vector<Span>* all, bool ignoreNullSpans) const; |
| int Get(int spanVertexNumber, Point3d& p, Point3d& pc) const |
| { |
| Point p2d, pc2d; |
| int d = Get(spanVertexNumber, p2d, pc2d); |
| p = p2d; |
| pc = pc2d; |
| return d; |
| } |
| int Get(int spannumber, Span& sp, bool returnSpanProperties = false, bool transform = false) const; |
| |
| |
| |
| |
| void Get(Point& ps, Point& pe) const; |
| const SpanDataObject* GetIndex(int vertexNumber) const; |
| inline double GetLength() const |
| { |
| return Perim(); |
| }; |
|
|
| void minmax(Point& pmin, Point& pmax); |
| void minmax(Box& b); |
|
|
| Point NearToVertex(const Point& p, int& nearSpanNumber) const; |
| Point NearToVertex(const Point& p) const |
| { |
| int nearSpanNumber; |
| return NearToVertex(p, nearSpanNumber); |
| }; |
| Point Near(const Point& p, int& nearSpanNumber) const; |
| Point Near(const Point& p) const |
| { |
| int nearSpanNumber; |
| return Near(p, nearSpanNumber); |
| }; |
| double Perim() const; |
| double Area() const; |
| void Reverse(); |
| bool Reverse(bool isReversed) |
| { |
| bool tmp = m_isReversed; |
| m_isReversed = isReversed; |
| return tmp; |
| }; |
| int Reduce(double tolerance); |
|
|
| int Offset( |
| vector<Kurve*>& OffsetKurves, |
| double offset, |
| int direction, |
| int method, |
| int& ret |
| ) const; |
| int OffsetMethod1(Kurve& kOffset, double off, int direction, int method, int& ret) const; |
| int OffsetISOMethod( |
| Kurve& kOffset, |
| double off, |
| int direction, |
| bool BlendAll |
| ) const; |
| int Intof(const Span& sp, vector<Point>& p) const; |
| int Intof(const Kurve& k, vector<Point>& p) const; |
| bool Compare(const Kurve* k, Matrix* m, bool bAllowMirror = true) const; |
| void ChangeStart(const Point* pNewStart, int startSpanno); |
| void ChangeEnd(const Point* pNewEnd, int endSpanno); |
|
|
| private: |
| bool compareKurves( |
| const std::vector<struct spanCompare>& first, |
| const std::vector<struct spanCompare>& second, |
| int& nOffset |
| ) const; |
| bool calculateMatrix(const Kurve* k, Matrix* m, int nOffset, bool bMirror = false) const; |
|
|
| public: |
| void AddIndex(int vertexNumber, const SpanDataObject* data); |
| bool Split( |
| double MaximumRadius, |
| double reslution |
| ); |
| int IntExtWire( |
| Kurve& kSec, |
| double Ref, |
| double Sec, |
| double height, |
| Kurve* kOut |
| ); |
| void SetZ(double z) |
| { |
| e[11] = z; |
| if (fabs(z) > 1.0e-6) { |
| m_unit = false; |
| } |
| } |
|
|
| void Part(int startVertex, int EndVertex, Kurve* part); |
| Kurve Part( |
| int fromSpanno, |
| const Point& fromPt, |
| int toSpanno, |
| const Point& toPt |
| ); |
| int Break( |
| double atParam, |
| const Kurve* secInput, |
| Kurve* refOut, |
| Kurve* secOut |
| ); |
| void Part( |
| double fromParam, |
| double toParam, |
| const Kurve* secInput, |
| Kurve* refOut, |
| Kurve* secOut |
| ); |
| Kurve Part(double fromParam, double toParam); |
| void AddSections(const Kurve* k, bool endOfSection); |
| void AddEllipse( |
| int dir, |
| const Point& pStart, |
| const Point& pEnd, |
| const Point& pCentre, |
| const Vector2d& majorAxis, |
| double majorRadius, |
| double minorRadius, |
| double tolerance |
| ); |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| void Spiral( |
| const Point& centre, |
| double startAngle, |
| double startRadius, |
| double radiusRisePerRevolution, |
| double endRadius |
| ); |
| #ifdef PARASOLID |
| int ToPKcurve( |
| PK_CURVE_t* curves, |
| PK_INTERVAL_t* ranges, |
| int start_spanno, |
| int n_spans |
| ); |
|
|
| PK_BODY_t ToPKwire(); |
| PK_BODY_t ToPKwire(int start_spanno, int n_spans); |
|
|
| PK_BODY_t ToPKsheet(); |
| PK_BODY_t ToPKextrudedBody(PK_VECTOR1_t path, bool solidbody = true); |
| |
| PK_BODY_t ToPKlofted_sheet_body(Kurve& sec); |
| PK_BODY_t ToPKlofted_thickened_body(Kurve& sec, double thickness); |
| #endif |
| }; |
| #ifdef _MSC_VER |
| # pragma warning(default : 4522) |
| #endif |
|
|
| void tangential_arc(const Point& p0, const Point& p1, const Vector2d& v0, Point& c, int& dir); |
|
|
| int EqualiseSpanCount( |
| Kurve& k1, |
| Kurve& k2, |
| Kurve& k1equal, |
| Kurve& k2equal, |
| bool equalise_same_span_count |
| ); |
| void EqualiseSpanCountAfterOffset( |
| Kurve& k1, |
| Kurve& k2, |
| Kurve& k1Out, |
| Kurve& k2Out |
| ); |
| void EqualiseSpanCountAfterOffsetFromRollAround( |
| Kurve& k1, |
| Kurve& k2, |
| Kurve& k1Out, |
| Kurve& k2Out |
| ); |
|
|
| Point IntofIso(Span& one, Span& two, Span& three); |
|
|
| inline double CPTOL(double offset, double maxOffset) |
| { |
| |
| |
| |
| |
|
|
| offset = fabs(offset); |
|
|
| if (offset <= RESOLUTION) { |
| offset = maxOffset; |
| } |
|
|
| return RESOLUTION / offset; |
| } |
|
|
|
|
| |
| int Intof(const Span& sp0, const Span& sp1, Point& p0, Point& p1, double t[4]); |
| int LineLineIntof(const Span& L0, const Span& L1, Point& p, double t[2]); |
| int LineArcIntof(const Span& line, const Span& arc, Point& p0, Point& p1, double t[4]); |
| int ArcArcIntof(const Span& arc0, const Span& arc1, Point& pLeft, Point& pRight); |
|
|
| bool OnSpan(const Span& sp, const Point& p); |
| bool OnSpan( |
| const Span& sp, |
| const Point& p, |
| bool nearPoints, |
| Point& pNear, |
| Point& pOnSpan |
| ); |
| |
| |
|
|
|
|
| int Intof(const Line& v0, const Line& v1, Point3d& intof); |
| double Dist( |
| const Line& l, |
| const Point3d& p, |
| Point3d& pnear, |
| double& t |
| ); |
| Point3d Near(const Line& l, const Point3d& p, double& t); |
| double Dist( |
| const Span& sp, |
| const Point& p, |
| Point& pnear |
| ); |
|
|
| |
|
|
| int biarc(CLine& cl0, CLine& cl1, Span* sp0, Span* sp1); |
|
|
| |
| class Line |
| { |
| public: |
| Point3d p0; |
| Vector3d v; |
| double length; |
| Box3d box; |
| bool ok; |
|
|
| |
| Line() |
| { |
| ok = false; |
| length = 0; |
| } |
| Line(const Point3d& p0, const Vector3d& v0, bool boxed = true); |
| Line(const Point3d& p0, const Point3d& p1); |
| Line(const Span& sp); |
|
|
| |
| void minmax(); |
| Point3d Near( |
| const Point3d& p, |
| double& t |
| ) const; |
| int Intof(const Line& l, Point3d& intof) const |
| { |
| return geoff_geometry::Intof(*this, l, intof); |
| }; |
| bool atZ(double z, Point3d& p) const; |
| bool Shortest( |
| const Line& l2, |
| Line& lshort, |
| double& t1, |
| double& t2 |
| ) const; |
| }; |
|
|
|
|
| class Triangle3d |
| { |
| Point3d vert1; |
| Point3d vert2; |
| Point3d vert3; |
| Vector3d v0; |
| Vector3d v1; |
| bool ok; |
|
|
| Box3d box; |
|
|
| public: |
| |
| Triangle3d() |
| { |
| ok = false; |
| }; |
| Triangle3d(const Point3d& vert1, const Point3d& vert2, const Point3d& vert3); |
|
|
| |
| bool Intof(const Line& l, Point3d& intof) const; |
| }; |
|
|
|
|
| } |
|
|