1 2 ///////////////////////////////////////////////////////////////////////////////////////// 3 4 // geometry.lib header 5 6 // g.j.hawkesford August 2003 7 // modified with 2d & 3d vector methods 2006 8 // 9 // This program is released under the BSD license. See the file COPYING for details. 10 // 11 ///////////////////////////////////////////////////////////////////////////////////////// 12 #pragma once 13 #ifdef WIN32 14 #pragma warning( disable : 4996 ) 15 #ifndef WINVER 16 #define WINVER 0x501 17 #endif 18 #endif 19 20 #include <math.h> 21 #include <algorithm> 22 #include <vector> 23 #include <list> 24 #include <iostream> 25 #include <fstream> 26 #include <string.h> 27 28 using namespace std; 29 30 31 namespace geoff_geometry { 32 33 // offset methods 34 enum OFFSET_METHODS { 35 NO_ELIMINATION = 0, 36 BASIC_OFFSET, 37 ROLLINGBALL_OFFSET // unfinished 38 }; 39 40 enum SPAN_IDS { 41 UNMARKED = 0xe0000000, 42 ROLL_AROUND, 43 INTERSECTION, 44 FULL_CIRCLE_KURVE 45 }; 46 47 48 class Vector2d; 49 class Vector3d; 50 class Point; 51 class Point3d; 52 class CLine; 53 class Circle; 54 class Span; 55 class Kurve; 56 class Line; 57 58 59 enum UNITS_TYPE{ 60 MM = 0, 61 METRES, 62 INCHES 63 }; 64 65 extern int UNITS; // may be enum UNITS_TYPE (MM METRES or INCHES) 66 extern double TOLERANCE; // CAD Geometry resolution (inexact, eg. from import) 67 extern double TOLERANCE_SQ; // tolerance squared for faster coding. 68 extern double TIGHT_TOLERANCE; 69 extern double UNIT_VECTOR_TOLERANCE; 70 extern double SMALL_ANGLE; // small angle tangency test eg isConvex 71 extern double SIN_SMALL_ANGLE; 72 extern double COS_SMALL_ANGLE; 73 extern double RESOLUTION; // CNC resolution 74 75 void set_Tolerances(int mode); 76 double mm(double value); // convert to current units from mm 77 78 inline bool FEQ(double a, double b, double tolerance = TOLERANCE) {return fabs(a - b) <= tolerance;} 79 inline bool FNE(double a, double b, double tolerance = TOLERANCE) {return fabs(a - b) > tolerance;} 80 81 inline bool FEQZ(double a, double tolerance = TIGHT_TOLERANCE) {return fabs(a) <= tolerance;} 82 inline bool FNEZ(double a, double tolerance = TIGHT_TOLERANCE) {return fabs(a) > tolerance;} 83 84 #define PI 3.1415926535897932384626433832795e0 85 #define DegreesToRadians (PI / 180.0e0) 86 #define RadiansToDegrees (180.0e0 / PI) 87 #define NEARLY_ONE 0.99999999999e0 88 #define CPTANGENTTOL 1.0e-04 // normalised vector crossproduct tolerance sin A so A = .0057deg 89 90 #define TANTO -1 91 #define ANTITANTO 1 92 93 #define TANGENT 0 94 95 #define NEARINT 1 96 #define FARINT -1 97 98 #define LEFTINT 1 99 #define RIGHTINT -1 100 101 #define CFILLET 0 // corner fillet 102 #define CHAMFER 1 // chamfer 103 104 #define GEOFF_LEFT 1 105 #define NONE 0 106 #define GEOFF_RIGHT -1 107 108 109 #define LINEAR 0 // linear 110 #define ACW 1 // anti-clockwise 111 #define CW -1 // clockwise 112 113 const wchar_t* getMessage(const wchar_t* original); // dummy 114 void FAILURE(const wchar_t* str); 115 void FAILURE(const std::wstring& str); 116 117 enum MESSAGE_GROUPS { 118 GENERAL_MESSAGES, 119 GEOMETRY_ERROR_MESSAGES, 120 PARAMSPMP 121 }; 122 123 enum GENERAL_MESSAGES { 124 MES_TITLE = 0, 125 MES_UNFINISHEDCODING, 126 MES_ERRORFILENAME, 127 MES_LOGFILE, 128 MES_LOGFILE1, 129 MES_P4CMENU, 130 MES_P4CMENUHINT 131 }; 132 133 enum GEOMETRY_ERROR_MESSAGES{ // For geometry.lib 134 MES_DIFFSCALE = 1000, 135 MES_POINTONCENTRE, 136 MES_INVALIDARC, 137 MES_LOFTUNEQUALSPANCOUNT, 138 MES_EQUALSPANCOUNTFAILED, 139 MES_CANNOTTRIMSPAN, 140 MES_INDEXOUTOFRANGE, 141 MES_BAD_VERTEX_NUMBER, 142 MES_BAD_REF_OFFSET, 143 MES_BAD_SEC_OFFSET, 144 MES_ROLLINGBALL4AXIS_ERROR, 145 MES_INPUT_EQUALSPANCOUNT, 146 MES_INVALIDPLANE 147 }; 148 149 // homogenous 4 x 4 Matrix class 150 class Matrix{ 151 protected: 152 public: 153 double e[16]; 154 bool m_unit; // true if unit matrix 155 int m_mirrored; // 1 if mirrored, 0 if not and -1 if unknown 156 157 public: 158 // constructors etc... 159 Matrix(); // create a unit matrix 160 Matrix(double m[16]); // from an array 161 Matrix(const Matrix& m); // copy constructor 162 ~Matrix()163 ~Matrix(){}; 164 165 //operators 166 bool operator==(const Matrix &m)const; 167 bool operator!=(const Matrix &m)const { return !(*this == m);} 168 169 // methods 170 void Unit(); // unit matrix 171 void Get(double* p) const; // get the matrix into p 172 void Put(double*p); // put p[16] into matrix 173 void Translate(double x, double y, double z=0); // Translation 174 175 void Rotate(double sinang, double cosang, Vector3d *rotAxis); // Rotation about rotAxis 176 void Rotate(double angle, Vector3d *rotAxis); // Rotation about rotAxis 177 178 void Rotate(double sinang, double cosang, int Axis); // Rotation with cp & dp 179 void Rotate(double angle, int Axis); // Rotation with angle 180 181 void Scale(double scale); // Scale 182 void Scale(double scalex, double scaley, double scalez); 183 184 void Multiply(Matrix& m); // Multiply 2 Matrices 185 // void Transform(Point& p); 186 void Transform(double p0[3]) const; // Transform p0 thro' this matrix 187 void Transform(double p0[3], double p1[3]) const; // Transform p0 to p1 thro' this matrix 188 void Transform2d(double p0[2], double p1[2]) const; // Transform p0 to p1 thro' this matrix 189 190 int IsMirrored(); // true if matrix has a mirror transformation 191 int IsUnit(); // true if matrix is unit matrix 192 void GetTranslate(double& x, double& y, double& z) const; // get translation from matrix 193 void GetScale(double& sx, double& sy, double& sz) const; // get scale from matrix 194 bool GetScale(double& sx) const; // get scale from matrix (true if uniform scale) 195 void GetRotation(double& ax, double& ay, double& az) const; // get rotation from matrix 196 197 Matrix Inverse(); // inverts this matrix 198 }; 199 200 extern Matrix UnitMatrix; // a Unit Matrix 201 202 203 // 2d Point class 204 class Point { 205 friend wostream& operator << (wostream& op, Point& p); 206 207 public: 208 bool ok; // true if this point is defined correctly 209 double x; // x value 210 double y; // y value 211 212 // constructors etc... Point()213 inline Point(){ ok=false;}; // Point p1 214 inline Point( double xord, double yord, bool okay = true) { // Point p1(10,30); 215 x = xord; y = yord; ok = okay;} Point(const Point & p)216 inline Point( const Point& p ) { // copy constructor Point p1(p2); 217 x = p.x; y = p.y; ok = p.ok;} 218 Point( const Point3d& p ); // copy constructor Point p1(p2); 219 Point(const Vector2d& v); 220 221 // operators 222 bool operator==(const Point &p)const; 223 bool operator!=(const Point &p)const { return !(*this == p);} 224 inline Point operator+(const Point &p)const{return Point(x + p.x, y + p.y);} // p0 = p1 + p2; 225 inline Point operator+=(const Point &p){return Point(x += p.x, y += p.y);} // p0 += p1; 226 Point operator+(const Vector2d &v)const; // p1 = p0 + v0; 227 228 // destructor 229 //~Point(){}; 230 231 // methods 232 Point Transform(const Matrix& m); // transform point 233 double Dist(const Point& p)const; // distance between 2 points 234 double DistSq(const Point& p)const; // distance squared 235 double Dist(const CLine& cl)const; // distance p to cl 236 Point Mid(const Point& p, double factor=.5)const; // mid point get(double xyz[2])237 void get(double xyz[2]) {xyz[0] = x; xyz[1] = y;} // return to array 238 }; 239 240 241 #define INVALID_POINT Point(9.9999999e50, 0, false) 242 #define INVALID_POINT3D Point3d(9.9999999e50, 0, 0, false) 243 #define INVALID_CLINE CLine(INVALID_POINT, 1, 0, false) 244 #define INVALID_CIRCLE Circle(INVALID_POINT, 0) 245 246 // 3d point class 247 class Point3d { 248 friend wostream& operator <<(wostream& op, Point3d& p); 249 public: 250 // bool ok; // true if this point is defined correctly 251 double x; // x value 252 double y; // y value 253 double z; // z value 254 255 // constructors Point3d()256 inline Point3d(){};// {z=0; /*ok=false;*/}; // Point p1 Point3d(const double * xyz)257 inline Point3d(const double* xyz) {x = xyz[0], y = xyz[1]; z = xyz[2];} 258 inline Point3d( double xord, double yord, double zord = 0/*, bool okay = true*/) { // Point p1(10,30.5); 259 x = xord; y = yord; z = zord;/* ok = okay;*/} Point3d(const Point3d & p)260 inline Point3d( const Point3d& p ) { // copy constructor Point p1(p2); 261 x = p.x; y = p.y; z = p.z;/* ok = p.ok;*/} Point3d(const Point & p)262 inline Point3d( const Point& p ) { // copy constructor Point p1(p2); 263 x = p.x; y = p.y; z = 0; /*ok = p.ok;*/} Point3d(const Point & p,double zord)264 inline Point3d( const Point& p, double zord ) { // copy constructor Point p1(p2, z); 265 x = p.x; y = p.y; z = zord;/* ok = p.ok;*/} 266 Point3d(const Vector3d& v); 267 268 // destructor 269 // ~Point3d(); 270 271 // operators 272 bool operator==(const Point3d &p)const; 273 bool operator!=(const Point3d &p)const { return !(*this == p);} 274 Point3d operator+(const Vector3d &v)const; // p1 = p0 + v0; 275 276 277 // methods 278 #ifdef PEPSDLL 279 void ToPeps(int id, bool draw = true); // copy Point to Peps 280 #endif 281 Point3d Transform(const Matrix& m); 282 double Dist(const Point3d& p)const; // distance between 2 points 283 double DistSq(const Point3d& p)const; // distance squared between 2 points 284 Point3d Mid(const Point3d& p, double factor = 0.5)const; // midpoint get(double xyz[3])285 void get(double xyz[3]) {xyz[0] = x; xyz[1] = y; xyz[2] = z;} getBuffer()286 double* getBuffer(){return &this->x;}; // returns ptr to data getBuffer()287 const double* getBuffer()const{return &this->x;}; // returns ptr to data 288 289 }; 290 291 // 2d vector class 292 class Vector2d{ 293 friend wostream& operator <<(wostream& op, Vector2d& v); 294 private: 295 double dx, dy; 296 public: 297 298 // constructors Vector2d()299 Vector2d() {}; Vector2d(const Vector2d & v)300 inline Vector2d(const Vector2d &v) { dx = v.dx; dy = v.dy;} 301 Vector2d(const Vector3d &v); // careful Vector2d(double x,double y)302 inline Vector2d(double x, double y) {dx = x, dy = y;} Vector2d(const Point & p0,const Point & p1)303 inline Vector2d(const Point& p0, const Point& p1) {dx = p1.x - p0.x; dy = p1.y - p0.y;} Vector2d(const Point * p0,const Point * p1)304 inline Vector2d(const Point *p0, const Point *p1) {dx = p1->x - p0->x; dy = p1->y - p0->y;} Vector2d(const Point & p)305 inline Vector2d(const Point& p) { dx = p.x; dy = p.y;} // from 0,0 to p Vector2d(double angle)306 inline Vector2d(double angle) {dx = cos(angle *= DegreesToRadians); dy = sin(angle);} // constructs a vector from an angle (0° - 360°) 307 308 309 // operators 310 inline const Vector2d& operator=(const Vector2d &v){dx = v.dx; dy = v.dy; return *this;} // v1 = v2; 311 inline Vector2d operator+(const Vector2d &v)const{return Vector2d(dx + v.dx, dy + v.dy);} // v2 = v0 + v1; 312 inline Point operator+(const Point &p)const{return Point(this->dx + p.x, this->dy + p.y);} // p1 = v0 + p0; 313 inline Vector2d operator+(const double d){ return Vector2d(dx + d, dy + d); }; 314 315 inline const Vector2d& operator+=(const Vector2d &v){dx += v.dx; dy += v.dy; return *this;} // v1 += v0; 316 inline Vector2d operator-(const Vector2d &v)const{return Vector2d( dx - v.dx, dy - v.dy);} // v2 = v0 - v1; 317 inline const Vector2d& operator-=(const Vector2d &v){dx -= v.dx; dy =- v.dy; return *this;} // v1 -= v0; 318 inline Vector2d operator-(const double d){ return Vector2d(dx - d, dy - d); }; 319 320 inline const Vector2d operator-(void)const{return Vector2d(-dx, -dy);} // v1 = -v0; (unary minus) 321 322 inline const double operator*(const Vector2d &v)const{return (dx * v.dx + dy * v.dy);} // dot product m0.m1.cos a = v0 * v1 323 inline Vector2d operator*(double c)const{return Vector2d(dx*c, dy*c);} // scalar product 324 inline const Vector2d& operator*=(double c){dx *= c; dy *= c; return *this;} // scalar product 325 inline Vector2d operator*(int c)const{return Vector2d(dx*(double)c, dy*(double)c);} // scalar product 326 327 inline const double operator^(const Vector2d &v)const{return (dx * v.dy - dy * v.dx);} // cross product m0.m1.sin a = v0 ^ v1 328 inline Vector2d operator~(void)const{return Vector2d(-dy, dx);} // perp to left 329 330 bool operator==(const Vector2d &v)const; // v1 == v2 331 inline bool operator!=(const Vector2d &v)const { return !(*this == v);} // v1 != v2 332 333 334 335 // methods get(double xyz[2])336 void get(double xyz[2]) {xyz[0] = dx; xyz[1] = dy;} // return to array getx()337 inline double getx()const{return dx;} gety()338 inline double gety()const{return dy;} putx(double x)339 inline void putx(double x){dx = x;} puty(double y)340 inline void puty(double y){dy = y;} normalise()341 double normalise() 342 {double m = magnitude(); if(m < TIGHT_TOLERANCE) {dx=dy=0; return 0;} dx/=m; dy/=m; return m;} // normalise & returns magnitude magnitudesqd(void)343 inline double magnitudesqd(void)const{return(dx * dx + dy * dy);} // magnitude squared magnitude(void)344 inline double magnitude(void)const{return(sqrt(magnitudesqd()));} // magnitude Rotate(double cosa,double sina)345 void Rotate(double cosa, double sina){ // rotate vector by angle 346 double temp = -dy * sina + dx * cosa; 347 dy = dx * sina + cosa * dy; 348 dx = temp; 349 } Rotate(double angle)350 inline void Rotate(double angle) { if(FEQZ(angle) == true) return; Rotate(cos(angle), sin(angle));} 351 void Transform( const Matrix& m); // transform vector 352 353 // destructor 354 //~Vector2d(){} 355 356 }; 357 358 359 // 3d vector class 360 class Vector3d{ 361 friend wostream& operator <<(wostream& op, Vector3d& v); 362 private: 363 double dx, dy, dz; 364 public: 365 366 // constructors Vector3d()367 Vector3d() {}; Vector3d(const Vector3d & v)368 Vector3d(const Vector3d &v) { dx = v.dx; dy = v.dy; dz = v.dz;} 369 Vector3d(double x, double y, double z = 0) {dx = x, dy = y; dz = z;} Vector3d(const double * x)370 Vector3d(const double* x) {dx = x[0], dy = x[1]; dz = x[2];} Vector3d(const double * x0,const double * x1)371 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)372 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)373 Vector3d(const Point3d& p) { dx = p.x; dy = p.y; dz = p.z;} // from 0,0,0 to p Vector3d(const Vector2d & v)374 Vector3d(const Vector2d& v) {dx = v.getx(); dy = v.gety(); dz = 0;} 375 376 // operators 377 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)); } // v1 == v2 (unit only!) 378 bool operator!=(const Vector3d &v)const { return (!(*this == v)); } // v1 != v2 379 const Vector3d& operator=(const Vector3d &v){dx = v.dx; dy = v.dy; dz = v.dz;return *this;} // v1 = v2; 380 // const Vector3d& operator=(const Vector2d &v){dx = v.getx(); dy = v.gety(); dz = 0.0;return *this;} // v1 = v2; 381 inline Point3d operator+(const Point3d &p)const{return Point3d(dx + p.x, dy + p.y, dz + p.z);} // p1 = v0 + p0; 382 Vector3d operator+(const Vector3d &v)const{return Vector3d(dx + v.dx, dy + v.dy, dz + v.dz);} // v2 = v0 + v1; 383 const Vector3d& operator+=(const Vector3d &v){dx += v.dx; dy += v.dy; dz += v.dz; return *this;} // v1 += v0; 384 Vector3d operator-(const Vector3d &v)const{return Vector3d( dx - v.dx, dy - v.dy, dz - v.dz);} // v2 = v0 - v1; 385 const Vector3d& operator-=(const Vector3d &v){ 386 dx -= v.dx; dy =- v.dy; dz = -v.dz; return *this;} // v1 -= v0; 387 388 const Vector3d operator-(void)const{return Vector3d(-dx, -dy, -dz);} // v1 = -v0; (unary minus) 389 390 const double operator*(const Vector3d &v)const{return (dx * v.dx + dy * v.dy + dz * v.dz);} // dot product m0 m1 cos a = v0 * v1 391 392 const Vector3d& operator*=(double c){dx *= c; dy *= c; dz *= c; return *this;} // scalar products 393 friend const Vector3d operator*(const Vector3d &v, double c){return Vector3d(v.dx*c, v.dy*c, v.dz*c);} 394 friend const Vector3d operator*(double c, const Vector3d &v){return Vector3d(v.dx*c, v.dy*c, v.dz*c);} 395 friend const Vector3d operator/(const Vector3d &v, double c){return Vector3d(v.dx/c, v.dy/c, v.dz/c);} 396 397 const Vector3d operator^(const Vector3d &v)const{ 398 return Vector3d(dy * v.dz - dz * v.dy, dz * v.dx - dx * v.dz, dx * v.dy - dy * v.dx);} // cross product vector 399 400 // = the vector perp to the plane of the 2 vectors 401 // the z component magnitude is m0.m1.sin a 402 // methods get(double xyz[3])403 inline void get(double xyz[3])const {xyz[0] = dx; xyz[1] = dy; xyz[2] = dz;} // return to array getx()404 inline double getx()const{return dx;} gety()405 inline double gety()const{return dy;} getz()406 inline double getz()const{return dz;} putx(double x)407 inline void putx(double x){dx = x;} puty(double y)408 inline void puty(double y){dy = y;} putz(double z)409 inline void putz(double z){dz = z;} normalise()410 double normalise(){double m = magnitude(); if(m < 1.0e-09) {dx=dy=dz=0; return 0;} dx/=m; dy/=m; dz/=m; // normalise & returns magnitude 411 return m;} magnitude(void)412 inline double magnitude(void)const{return(sqrt(dx * dx + dy * dy + dz * dz));} // magnitude magnitudeSq(void)413 inline double magnitudeSq(void)const{return(dx * dx + dy * dy + dz * dz);} // magnitude squared 414 void Transform( const Matrix& m); // transform vector 415 void arbitrary_axes(Vector3d& x, Vector3d& y); 416 int setCartesianAxes(Vector3d& b, Vector3d& c); getBuffer()417 double* getBuffer(){return &this->dx;}; // returns ptr to data getBuffer()418 const double* getBuffer()const{return &this->dx;}; // returns ptr to data 419 420 // destructor 421 //~Vector3d(){} 422 423 }; 424 425 #define ORIGIN Point3d(0,0,0) 426 #define NULL_VECTOR Vector3d(0,0,0) 427 #define Z_VECTOR Vector3d(0,0,1) 428 #define Y_VECTOR Vector3d(0,1,0) 429 #define X_VECTOR Vector3d(1,0,0) 430 431 // 2D cline x = x0 + t * dx; y = y0 + t * dy 432 class CLine{ 433 friend wostream& operator <<(wostream& op, CLine& cl); 434 public: 435 bool ok; 436 Point p; 437 Vector2d v; 438 439 // constructors CLine()440 inline CLine() {ok = false;}; 441 inline CLine(const Point& p0, double dx, double dy, bool normalise = true){ p = p0; v = Vector2d(dx, dy); if(normalise) Normalise();}; 442 inline CLine(const Point& p0, const Vector2d& v0, bool normalise = true) {p = p0; v = v0; if(normalise) Normalise();}; CLine(const CLine & s)443 inline CLine( const CLine& s ) {p = s.p; v = s.v;}; // copy constructor CLine s1(s2); CLine(const Point & p0,const Point & p1)444 inline CLine(const Point& p0, const Point& p1) {p = p0; v = Vector2d(p0, p1); Normalise();}; 445 CLine(const Span& sp); 446 447 // operators 448 const CLine operator~(void);// perp to left 449 const CLine operator=(const Point& p0){p.x=p0.x; p.y=p0.y; return *this;}; // s = p; 450 451 // methods 452 double c(); // returns c 453 void Normalise(); // normalise dx,dy 454 #ifdef PEPSDLL 455 void ToPeps(int id, bool draw = true); // to Peps 456 void DelPeps(int id); // delete Peps CLine 457 #endif 458 CLine Transform(Matrix& m); // transform a CLine 459 Point Intof(const CLine& s); // intersection of 2 clines 460 Point Intof(int NF, const Circle& c); // intersection of cline & circle 461 Point Intof(int NF, const Circle& c, Point& otherInters); double Dist(const Point& p1)const; // ditto & other intersection 462 CLine Bisector(const CLine& s); // Bisector of 2 Clines 463 464 // destructor 465 // ~CLine(); 466 }; 467 468 #define HORIZ_CLINE CLine(geoff_geometry::Point(0,0), 1.0, 0.0, true) 469 470 471 // 2D circle 472 class Circle{ 473 friend wostream& operator <<(wostream& op, Circle& c); 474 public: 475 bool ok; 476 Point pc; 477 double radius; 478 479 // constructors etc... Circle()480 inline Circle() {ok = false;}; 481 Circle( const Point& p, double r); // Circle c1(Point(10,30), 20); 482 Circle( const Point& p, const Point& pc); // Circle c1(p[222], p[223]); Circle(const Circle & c)483 Circle( const Circle& c ){*this = c;} // copy constructor Circle c1(c2); 484 Circle( const Span& sp); // constructor 485 486 // methods 487 #ifdef PEPSDLL 488 void ToPeps(int id, bool draw = true); // to Peps 489 void DelPeps(int id); // delete Peps Circle 490 #endif 491 bool operator==(const Circle &c)const; // c == cc 492 bool operator!=(const Circle &c)const { return !(*this == c);} 493 Circle Transform(Matrix& m); // transform a Circle 494 Point Intof(int LR, const Circle& c1); // intof 2 circles 495 Point Intof(int LR, const Circle& c1, Point& otherInters); // intof 2 circles, (returns the other intersection) 496 int Intof(const Circle& c1, Point& leftInters, Point& rightInters); // intof 2 circles (returns number of intersections & left/right inters) 497 CLine Tanto(int AT, double angle, const CLine& s0)const; // a cline tanto this circle at angle 498 // ~Circle(); // destructor 499 }; 500 501 // 2d box class 502 class Box{ 503 public: 504 Point min; 505 Point max; 506 bool ok; 507 Box()508 Box() { min.x = min.y = 1.0e61; max.x = max.y = -1.0e61; ok = false;}; Box(Point & pmin,Point & pmax)509 Box(Point& pmin, Point& pmax) { min = pmin; max = pmax; ok = true;}; 510 511 bool outside(const Box& b)const; // returns true if box is outside box 512 void combine(const Box& b); // combines this with b 513 }; 514 515 // 3d box class 516 class Box3d{ 517 public: 518 Point3d min; 519 Point3d max; 520 bool ok; 521 Box3d()522 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)523 Box3d(const Point3d& pmin, const Point3d& pmax) { min = pmin; max = pmax; ok = true;}; 524 525 bool outside(const Box3d& b)const; // returns true if box is outside box 526 void combine(const Box3d& b); // combines this with b 527 }; 528 MinMax(const Point & p,Point & pmin,Point & pmax)529 inline void MinMax(const Point& p, Point& pmin, Point& pmax) { 530 if(p.x > pmax.x) pmax.x = p.x; 531 if(p.y > pmax.y) pmax.y = p.y; 532 if(p.x < pmin.x) pmin.x = p.x; 533 if(p.y < pmin.y) pmin.y = p.y; 534 }; 535 MinMax(const Point3d & p,Point3d & pmin,Point3d & pmax)536 inline void MinMax(const Point3d& p, Point3d& pmin, Point3d& pmax) { 537 if(p.x > pmax.x) pmax.x = p.x; 538 if(p.y > pmax.y) pmax.y = p.y; 539 if(p.z > pmax.z) pmax.z = p.z; 540 if(p.x < pmin.x) pmin.x = p.x; 541 if(p.y < pmin.y) pmin.y = p.y; 542 if(p.z < pmin.z) pmin.z = p.z; 543 }; 544 545 546 547 548 // 2D line arc span 549 class Span{ 550 friend wostream& operator <<(wostream& op, Span& span); 551 public: 552 Point p0; // start 553 Point p1; // end 554 Point pc; // centre 555 int dir; // arc direction (CW or ACW or 0 for straight) 556 int ID; // ID (for offset in wire - stores spanID etc. from original kurve) 557 bool ok; 558 559 bool returnSpanProperties; // set if properties below are set 560 Vector2d vs; // direction at start or for straight 561 Vector2d ve; // direction at span end 562 563 double length; // span length 564 double radius; // arc radius 565 double angle; // included arc angle ( now arc is parameterised start -> start + angle 566 567 Box box; // span box 568 569 bool NullSpan; // true if small span 570 571 // methods 572 void SetProperties(bool returnProperties); // set span properties 573 Span Offset(double offset); // offset span method 574 int Split(double tolerance); // returns number of splits 575 void SplitMatrix(int num_vectors, Matrix* matrix); // returns incremental matrix from split 576 void minmax(Box& box, bool start = true); // minmax of span 577 void minmax(Point& pmin, Point& pmax, bool start = true); // minmax of span 578 int Intof(const Span& sp, Point& pInt1, Point& pInt2, double t[4])const; 579 void Transform(const Matrix& m, bool setprops = true); 580 Point Near(const Point& p)const; // returns the near point to span from p (on or off) 581 Point NearOn(const Point& p)const; // returns the near point to span from p (on span) 582 Point Mid()const; // midpoint of a span 583 Point MidPerim(double d)const; // interior point of Span (param 0 - d) 584 Point MidParam(double param)const; // interior point of Span (param 0 - 1) 585 bool OnSpan(const Point& p)const; // tests if p is on sp *** FAST TEST p MUST LIE on unbounded span 586 bool OnSpan(const Point& p, double* t)const; // tests if p is on sp *** FAST TEST p MUST LIE on unbounded span 587 bool JoinSeparateSpans(Span& sp); 588 Span BlendTwoSpans(Span& sp2, double radius, double maxt); // Blends 2 Spans 589 bool isJoinable(const Span& sp)const; // is this & sp joinable to 1 span? 590 Vector2d GetVector(double fraction)const; // the direction along the span, 0.0 for start, 1.0 for end 591 592 // constructor Span()593 Span() {ID = 0; ok = false;}; Span(int spandir,const Point & pn,const Point & pf,const Point & c)594 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;}; 595 596 // operators 597 // bool operator==(const Span &sp)const; 598 // bool operator!=(const Span &sp)const { return !(*this == sp);} 599 }; 600 601 // general 602 double atn360(double dx, double dy); // angle 0 to 2pi 603 604 // distance functions 605 //double Dist(double px, double py, double p1x, double p1y); // diatance between 2 points (2d) 606 //double Dist(Point& p0, Point& p1); // distance between 2 points (3d) 607 //double Dist(CLine& s, Point& p1); // distance between cline & point 608 609 double Dist(const Point3d *p, const Vector3d *vl, const Point3d *pf); // distance from line (p, vl) and pf 610 double DistSq(const Point3d *p, const Vector3d *vl, const Point3d *pf); // distance squared from line (p, vl) and pf 611 double Dist(const Circle& c, const Point& p); // distance between c & p 612 double Dist(const Point& p0, const Circle& c, const Point& p1); // clockwise distance around c from p0 to p1 613 double Dist(const CLine& s, const Circle& c); // distance between line and circle 614 double Dist(const Circle& c0, const Circle& c1); // distance between 2 circles 615 double IncludedAngle(const Vector2d& v0, const Vector2d& v1, int dir = 1); // angle between 2 vectors 616 double IncludedAngle(const Vector3d& v0, const Vector3d& v1, const Vector3d& normal, int dir = 1); 617 inline double IncludedAngle(const CLine& s0, const CLine& s1, int dir = 1) { // angle between 2 Clines 618 return IncludedAngle(s0.v, s1.v, dir); 619 } 620 621 622 // point definitions 623 Point Mid(const Point& p0, const Point& p1, double factor = 0.5); //// midpoint 624 Point Mid(const Span& sp); //// midpoint of a span 625 Point Rel(const Point& p, double x, double y); // relative point 626 Point Polar(const Point& p, double angle, double r); // polar from this point 627 Point AtAngle(const Circle& c, double angle); // Point at angle on a circle 628 Point XonCLine(const CLine& s, double xval); // returns point that has X on this line 629 Point YonCLine(const CLine& s, double yval); // returns point that has Y on this line 630 Point Intof(const CLine& s0, const CLine& s1); //// intof 2 clines 631 Point Intof(int NF, const CLine& s, const Circle& c); //// intof of circle & a cline 632 Point Intof(int NF, const CLine& s, const Circle& c, Point& otherInters); //// intof of circle & a cline (returns the other intersection) 633 Point Intof(int LR, const Circle& c0, const Circle& c1); //// intof 2 circles 634 Point Intof(int LR, const Circle& c0, const Circle& c1, Point& otherInters); //// intof 2 circles, (returns the other intersection) 635 int Intof(const Circle& c0, const Circle& c1, Point& pLeft, Point& pRight); //// ditto 636 Point Along(const CLine& s, double d); // distance along Cline 637 Point Along(const CLine& s, double d, const Point& p); // distance along Cline from point 638 Point Around(const Circle& c, double d, const Point& p); // distance around a circle from point 639 Point On(const CLine& s, const Point& p); // returns a point on s nearest to p 640 Point On(const Circle& c, const Point& p); // returns a point on c nearest to p 641 642 // cline definitons 643 644 CLine AtAngle(double angle, const Point& p, const CLine& s = HORIZ_CLINE); // cline at angle to line thro' point 645 CLine Tanto(int AT, const Circle& c, double angle, const CLine& s0 = HORIZ_CLINE);//// cline tanto circle at angle to optional cline 646 CLine Tanto(int AT, const Circle& c, const Point& p); // cline tanto circle thro' a point 647 CLine Tanto(int AT0, const Circle& c0, int AT1, const Circle& c1); // cline tanto 2 circles 648 CLine Normal(const CLine& s); // noirmal to cline 649 CLine Normal(const CLine& s, const Point& p); // normal to cline thro' p 650 CLine Parallel(int LR, const CLine& s, double distance); // parallel to cline by distance 651 CLine Parallel(const CLine& cl, const Point& p); // parallel to cline thro' a point 652 653 654 // circle definitions 655 Circle Thro(const Point& p0, const Point& p1); // circle thro 2 points (diametric) 656 Circle Thro(const Point& p0, const Point& p1, const Point& p2); // circle thro 3 points 657 Circle Tanto(int NF, const CLine& s0, const Point& p, double rad); // circle tanto a CLine thro' a point with radius 658 Circle Thro(int LR, const Point& p0, const Point& p1, double rad); // circle thro' 2 points with radius 659 Circle Tanto(int AT1, const CLine& s1, int AT2, const CLine& s2, double rad); // circle tanto 2 clines with radius 660 Circle Tanto(int AT1, const CLine& s1, int AT2, const CLine& s2, int AT3, const CLine& s3); // circle tanto 3 clines 661 Circle Tanto(int LR, int AT, const Circle& c, const Point& p, double rad); // circle tanto circle & thro' a point 662 Circle Tanto(int NF, int AT0, const CLine& s0, int AT1, const Circle& c1, double rad);// circle tanto cline & circle with radius 663 Circle Tanto(int LR, int AT0, const Circle& c0, int AT1, const Circle& c1, double rad);// circle tanto 2 circles with radius 664 Circle Tanto(int LR, int AT1 , const Circle& c1 , int AT2 , const Circle& c2, int AT3 , const Circle c3); // tanto 3 circles 665 int apolloniusProblem(int AT1 , const Circle& c1 , int AT2 , const Circle& c2, int AT3 , const Circle& c3, Circle& Solution1, Circle& Solution2); 666 int apolloniusProblem(int AT1 , const Circle& c1 , int AT2 , const Circle& c2, int AT3 , const CLine& cl3, Circle& Solution1, Circle& Solution2); 667 int apolloniusProblem(int AT1 , const Circle& c1 , int AT2 , const CLine& cl2, int AT3 , const CLine& cl3, Circle& Solution1, Circle& Solution2); 668 669 // Circle Tanto(int AT0, int NF, int AT1, CLine s1, int AT2, CLine s2); // circle tanto circle, and 2 clines 670 Circle Parallel(int LR, const Circle& c, double distance); // parallel to circle by a distance 671 672 673 // misc Radians(double degrees)674 inline double Radians(double degrees) {return degrees * PI / 180;} Degrees(double radians)675 inline double Degrees(double radians) { return radians * 180 / PI;} 676 int quadratic(double a, double b, double c, double& x0, double& x1); // solve quadratic 677 678 int corner(const Vector2d& v0, const Vector2d& v1, double cpTol = CPTANGENTTOL); // corner (TANGENT, LEFT, RIGHT) 679 inline int corner(const Span& span, const Span& next, double cpTol = CPTANGENTTOL) { 680 return corner((Vector2d)span.ve, (Vector2d)next.vs, cpTol);} 681 682 Line IsPtsLine(const double* a, int n, double tolerance, double* deviation); 683 // Span3d IsPtsSpan3d(const double* a, int n, double tolerance, double* deviation); 684 685 class Plane { 686 friend wostream& operator <<(wostream& op, Plane& pl); 687 688 public: // ax + by + cz + d = 0 689 bool ok; 690 double d; // distance of plane to origin 691 Vector3d normal; // normal to plane a = n.dx, b = n.dy, c = n.dz 692 // constructors Plane()693 Plane(){ok = false;}; 694 Plane(double dist, const Vector3d& n); 695 Plane(const Point3d& p0, const Point3d& p1, const Point3d& p2); 696 Plane(const Point3d& p0, const Vector3d& n, bool normalise = true); 697 698 // methods 699 double Dist(const Point3d& p)const; // signed distance of point to plane 700 bool Intof(const Line& l, Point3d& intof, double& t)const; // intersection of plane & line (0 >= t <= 1 if intersect within line) 701 bool Intof(const Plane& pl, Line& intof)const; // intersection of 2 planes 702 bool Intof(const Plane& pl0, const Plane& pl1, Point3d& intof)const; // intersection of 3 planes 703 Point3d Near(const Point3d& p)const; // returns near point to p on the plane 704 void Mirrored(Matrix* m); // returns a matrix for a mirror about this 705 }; 706 707 708 709 710 #define SPANSTORAGE 32 // lessens number of object pointers 711 712 class spVertex { 713 friend wostream& operator <<(wostream& op, spVertex& sp); 714 715 public: 716 int type; 717 int spanid; 718 Point p; 719 Point pc; spVertex()720 spVertex(){}; spVertex(int t,const Point & point,const Point & centre)721 spVertex(int t, const Point& point, const Point& centre): type(t), spanid(0), p(point), pc(centre){}; 722 723 bool operator==(spVertex &spv){ 724 // vertex == spvertex (vertex check - doesn't check spannid!) 725 if(this->type != spv.type) return false; 726 if(this->p != spv.p) return false; 727 if(this->type != LINEAR) { 728 if(this->pc != spv.pc) return false; 729 } 730 return true; 731 } 732 733 bool operator!=(spVertex &spv){ return !(*this == spv);} 734 735 }; 736 737 738 class SpanDataObject { 739 // holds everything needed for Post-Processing/Simulation 740 public: 741 int method; // holds method type 742 SpanDataObject(int meth)743 SpanDataObject(int meth){method = meth;}; SpanDataObject(const SpanDataObject * obj)744 SpanDataObject(const SpanDataObject* obj){method = obj->method;}; 745 }; 746 747 class SpanVertex{ 748 public: 749 int type[SPANSTORAGE]; // LINEAR CW or ACW // 0 straight (cw = -1 (T) acw = 1 (A) ) 750 int spanid[SPANSTORAGE]; // identification (eg wire offset span info) 751 const SpanDataObject* index[SPANSTORAGE]; // other - pointer to 752 double x[SPANSTORAGE], y[SPANSTORAGE]; // vertex 753 double xc[SPANSTORAGE], yc[SPANSTORAGE]; // centre of arc 754 public: 755 // methods 756 void Add(int offset, int type, const Point& p0, const Point& pc, int ID = UNMARKED); 757 const SpanDataObject* GetIndex(int offset)const; 758 void AddSpanID(int offset, int ID); 759 SpanVertex(); 760 ~SpanVertex(); 761 const SpanVertex& operator= (const SpanVertex& spv ); 762 763 void Add(int offset, const SpanDataObject* Index ); 764 const SpanDataObject* Get(int offset); 765 int Get(int offset, Point& pe, Point& pc); 766 int GetSpanID(int offset); 767 }; 768 769 770 771 772 773 #ifdef WIN32 774 #pragma warning(disable:4522) 775 #endif 776 777 class Kurve : public Matrix{ 778 friend wofstream& operator << (wofstream& op, Kurve& k); 779 friend wifstream& operator >> (wifstream& op, Kurve& k); 780 781 protected: 782 vector<SpanVertex*> m_spans; 783 bool m_started; 784 int m_nVertices; // number of vertices in Kurve 785 bool m_isReversed; // true if get spans reversed 786 787 public: 788 // for comparing kurves 789 struct spanCompare { 790 int dir; // LINEAR, CW or ACW 791 double length; // length of the span 792 double cp; // cross-product to next span (sina) 793 double dp; 794 }; 795 // constructors etc... Kurve()796 Kurve() { 797 m_started = false; 798 m_nVertices = 0; 799 m_isReversed = false; 800 }; 801 Kurve(const Kurve& k0); 802 const Kurve& operator= (const Kurve& k ); 803 const Kurve& operator=(const Matrix &m); 804 805 bool operator==(const Kurve &k)const; // k == kk (vertex check) 806 bool operator!=(const Kurve &k)const { return !(*this == k);} 807 808 809 // destructor 810 ~Kurve(); 811 812 // methods nSpans()813 inline int nSpans( )const {return (m_nVertices)? m_nVertices - 1 : 0;} // returns the number of spans 814 bool Closed()const; // returns true if kurve is closed Started()815 inline bool Started()const {return m_started;}; 816 void FullCircle(int dir, const Point& c, double radius); // make a full circle 817 void Start(); // start a new kurve 818 void Start(const Point& p); // start a new kurve with start point 819 bool Add(const spVertex& spv, bool AddNullSpans = true); // add a vertex 820 void Get(int vertex, spVertex& spv) const; // get a vertex 821 bool Add(const Span& sp, bool AddNullSpans = true); // add a span 822 bool Add(int type, const Point& p0, const Point& pc, bool AddNullSpans = true); // a span 823 void AddSpanID(int ID); 824 bool Add(const Point& p0, bool AddNullSpans = true); // linear 825 void Add(); // add a null span 826 void Add(const Kurve* k, bool AddNullSpans = true); // a kurve 827 void StoreAllSpans(std::vector<Span>& kSpans)const; // store all kurve spans in array, normally when fast access is reqd 828 void Clear(); // remove all the spans 829 830 void Replace(int vertexnumber, const spVertex& spv); 831 void Replace(int vertexnumber, int type, const Point& p, const Point& pc, int ID = UNMARKED); 832 int GetSpanID(int spanVertexNumber) const; // for spanID (wire offset) 833 int Get(int spanVertexNumber, Point& p, Point& pc) const; 834 void Get(std::vector<Span> *all, bool ignoreNullSpans) const; // get all spans to vector Get(int spanVertexNumber,Point3d & p,Point3d & pc)835 int Get(int spanVertexNumber, Point3d& p, Point3d& pc) const 836 { Point p2d, pc2d; int d = Get(spanVertexNumber, p2d, pc2d); p = p2d; pc = pc2d; return d;} 837 int Get(int spannumber, Span& sp, bool returnSpanProperties = false, bool transform = false) const; 838 // int Get(int spannumber, Span3d& sp, bool returnSpanProperties = false, bool transform = false) const; 839 void Get(Point &ps,Point &pe) const; // returns the start- and endpoint of the kurve 840 const SpanDataObject* GetIndex(int vertexNumber)const; GetLength()841 inline double GetLength()const{ return Perim();}; // returns the length of a kurve 842 843 void minmax(Point& pmin, Point& pmax); // minmax of span 844 void minmax(Box& b); 845 846 Point NearToVertex(const Point& p, int& nearSpanNumber)const; NearToVertex(const Point & p)847 Point NearToVertex(const Point& p)const { int nearSpanNumber; return NearToVertex(p, nearSpanNumber);}; 848 Point Near(const Point& p, int& nearSpanNumber)const; Near(const Point & p)849 Point Near(const Point& p) const{ int nearSpanNumber; return Near(p, nearSpanNumber);}; 850 double Perim()const; // perimeter of kurve 851 double Area()const; // area of closed kurve 852 void Reverse(); // reverse kurve direction - obsolete Reverse(bool isReversed)853 bool Reverse(bool isReversed) { // reverse kurve direction - later better method 854 bool tmp = m_isReversed; 855 m_isReversed = isReversed; 856 return tmp; 857 }; 858 int Reduce(double tolerance); // reduce spans which are in tolerance 859 860 int Offset(vector <Kurve*> &OffsetKurves, double offset, int direction, int method, int& ret)const; // offset methods 861 int OffsetMethod1(Kurve& kOffset, double off, int direction, int method, int& ret)const; 862 int OffsetISOMethod(Kurve& kOffset, double off, int direction, bool BlendAll)const; // special offset (ISO radius - no span elimination) 863 int Intof(const Span& sp, vector<Point>& p)const; // intof span 864 int Intof(const Kurve&k, vector<Point>& p)const; // intof kurve 865 bool Compare(const Kurve* k, Matrix* m, bool bAllowMirror = true)const; // compare 2 Kurves 866 void ChangeStart(const Point *pNewStart, int startSpanno); // change the Kurve's startpoint 867 void ChangeEnd(const Point *pNewEnd, int endSpanno); // change the Kurve's endpoint 868 869 private: 870 bool compareKurves(const std::vector<struct spanCompare> &first, const std::vector<struct spanCompare> &second, int &nOffset/*, Kurve *k, Matrix *m*/)const; 871 bool calculateMatrix(const Kurve *k, Matrix *m, int nOffset, bool bMirror = false)const; 872 public: 873 874 875 void AddIndex(int vertexNumber, const SpanDataObject* data); 876 bool Split(double MaximumRadius, double reslution); // split arcs larger than MaximumRadius to resoultion 877 int IntExtWire( Kurve& kSec, double Ref, double Sec, double height, Kurve* kOut); // interpolate / extrapolate a mid height kurve (wire) SetZ(double z)878 void SetZ(double z) { e[11] = z; if(fabs(z) > 1.0e-6) m_unit = false;} // assigns kurve to fixed height (wire) 879 880 void Part(int startVertex, int EndVertex, Kurve *part); 881 Kurve Part(int fromSpanno, const Point& fromPt, int toSpanno, const Point& toPt); // make a Part Kurve 882 int Break(double atParam, const Kurve *secInput, Kurve *refOut, Kurve *secOut);// break kurve perimeter parameterisation with synchronised Kurve (wire) 883 void Part(double fromParam, double toParam, const Kurve *secInput, Kurve *refOut, Kurve *secOut);// part kurve perimeter parameterisation with synchronised Kurve (wire) 884 Kurve Part(double fromParam, double toParam); // part kurve perimeter parameterisation 885 void AddSections(const Kurve* k, bool endOfSection); // special add kurves for rollingball 886 void AddEllipse(int dir, const Point& pStart, const Point& pEnd, const Point& pCentre, const Vector2d& majorAxis, double majorRadius, double minorRadius, double tolerance); 887 // void Kurve::AddEllipse(int dir, Plane *plEllipse, Vector3d *cylAxis, Point3d *cylCentre, double cylradius, Point3d *pStart, Point3d *pEnd, double tolerance); /// elliptical curve - biarc in tolerance 888 889 void Spiral(const Point& centre, double startAngle, double startRadius, double radiusRisePerRevolution, double endRadius); 890 #ifdef PARASOLID 891 int ToPKcurve(PK_CURVE_t *curves, PK_INTERVAL_t *ranges, int start_spanno, int n_spans); // Convert to PK Curve 892 893 PK_BODY_t ToPKwire(); // Convert to PK Wire Body 894 PK_BODY_t ToPKwire(int start_spanno, int n_spans); 895 896 PK_BODY_t ToPKsheet( ); // Convert to PK Sheet Body 897 PK_BODY_t ToPKextrudedBody(PK_VECTOR1_t path, bool solidbody = true); 898 // Convert to PK Body (open kurve >> sheet) 899 PK_BODY_t ToPKlofted_sheet_body(Kurve &sec); // Convert 2 kurves to lofted sheet body 900 PK_BODY_t ToPKlofted_thickened_body(Kurve &sec, double thickness); 901 #endif 902 }; 903 #ifdef WIN32 904 #pragma warning(default:4522) 905 #endif 906 907 void tangential_arc(const Point &p0, const Point &p1, const Vector2d &v0, Point &c, int &dir); 908 909 int EqualiseSpanCount(Kurve& k1, Kurve& k2, Kurve& k1equal, Kurve& k2equal, bool equalise_same_span_count); // span count equalisation 910 void EqualiseSpanCountAfterOffset(Kurve& k1, Kurve&k2, Kurve& k1Out, Kurve& k2Out);// span equalisation after offset 911 void EqualiseSpanCountAfterOffsetFromRollAround(Kurve& k1, Kurve&k2, Kurve& k1Out, Kurve& k2Out/*, double offset, int arc_direction*/);// span equalisation after offset 912 913 Point IntofIso(Span& one, Span& two, Span& three); // for iso blend radiuses - calc intersection 914 CPTOL(double offset,double maxOffset)915 inline double CPTOL(double offset, double maxOffset) { 916 // this returns a suitable tolerance for a cross product 917 // the cp for normalised vectors is the sin of the included angle between the vectors 918 // 919 // this function takes the machine resolution from RESOLUTION 920 921 offset = fabs(offset); 922 923 if(offset <= RESOLUTION) offset = maxOffset; // no known offset so guess one from the application 924 925 return RESOLUTION / offset; 926 } 927 928 929 930 // finite Span routines 931 int Intof(const Span& sp0 , const Span& sp1, Point& p0, Point& p1, double t[4]); 932 int LineLineIntof(const Span& L0 , const Span& L1, Point& p, double t[2]); 933 int LineArcIntof(const Span& line, const Span& arc, Point& p0, Point& p1, double t[4]); 934 int ArcArcIntof(const Span& arc0, const Span& arc1, Point& pLeft, Point& pRight); 935 936 bool OnSpan(const Span& sp, const Point& p); 937 bool OnSpan(const Span& sp, const Point& p, bool nearPoints, Point& pNear, Point& pOnSpan); // function returns true if pNear == pOnSpan 938 // pNear (nearest on unbound span) 939 // pOnSpan (nearest on finite span) 940 941 942 int Intof(const Line& v0, const Line& v1, Point3d& intof); // intof 2 lines 943 double Dist(const Line& l, const Point3d& p, Point3d& pnear, double& t); // distance from a point to a line 944 Point3d Near(const Line& l, const Point3d& p, double& t ); // near point to a line & t in 0-length range 945 double Dist(const Span& sp, const Point& p , Point& pnear ); // distance from p to sp, nearpoint returned as pnear 946 947 // Kurve splineUsingBiarc(CLine& cl0, CLine& cl1, std::vector<pts>); 948 949 int biarc(CLine& cl0, CLine& cl1, Span* sp0, Span* sp1 ); 950 951 // 3d line segment 952 class Line{ 953 public: 954 Point3d p0; // start 955 Vector3d v; // vector (not normalised) 956 double length; // line length 957 Box3d box; 958 bool ok; 959 960 // constructors Line()961 Line() {ok = false;}; 962 Line(const Point3d& p0, const Vector3d& v0, bool boxed = true); 963 Line(const Point3d& p0, const Point3d& p1); 964 Line(const Span& sp); 965 966 // methods 967 void minmax(); 968 Point3d Near(const Point3d& p, double& t)const; // near point to line from point (0 >= t <= 1) in range Intof(const Line & l,Point3d & intof)969 int Intof(const Line& l, Point3d& intof)const {return geoff_geometry::Intof(*this, l, intof);}; // intof 2 lines 970 bool atZ(double z, Point3d& p)const; // returns p at z on line 971 bool Shortest(const Line& l2, Line& lshort, double& t1, double& t2)const; // calculate shortest line between this & l2 972 }; 973 974 975 class Triangle3d { 976 Point3d vert1; // first vertex 977 Point3d vert2; // second vertex 978 Point3d vert3; // third vertex 979 Vector3d v0; // vector from vert1 to vert2 980 Vector3d v1; // vector from vert1 to vert3 981 bool ok; 982 983 Box3d box; // box around triangle 984 985 public: 986 // constructor Triangle3d()987 Triangle3d(){ ok = false;}; 988 Triangle3d(const Point3d& vert1, const Point3d& vert2, const Point3d& vert3); 989 990 // methods 991 bool Intof(const Line& l, Point3d& intof)const; // returns intersection triangle to line 992 }; 993 994 995 996 } // End namespace geoff_geometry 997 998 999 1000 1001