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