wxArt2D
polyver.h
Go to the documentation of this file.
1 /*! \file wx/artbase/polyver.h
2  \brief general vertexlist and array and vector path functions and classes.
3 
4  All ways to have polygons and polylines stored and drawn by a drawing context
5  are placed here. Polygon or polylines can be list based or array based.
6  The vector path is the structure which can be used to drawn almost anything.
7  Basic primtives can always be converted to a vector path, and drawn that way.
8 
9  \author Klaas Holwerda, Michael Sögtrop, Faust Nijhuis
10  \date Created 01/09/04
11 
12  Copyright: 2001-2004 (C) Klaas Holwerda, Michael Sögtrop
13 
14  Licence: wxWidgets licence
15 
16  RCS-ID: $Id: polyver.h,v 1.37 2009/09/30 18:38:56 titato Exp $
17 */
18 
19 #ifndef _WX_POLYVERH__
20 #define _WX_POLYVERH__
21 
22 #include "wx/geometry.h"
23 
24 #include "wx/general/gen.h"
25 #include "wx/artbase/artglob.h"
26 #include "wx/artbase/afmatrix.h"
27 #include "wx/artbase/liner.h"
28 #include "wx/artbase/bbox.h"
29 
30 //! defines the way a polyline with a contour width is ended.
31 enum a2dPATH_END_TYPE {a2dPATH_END_SQAURE, a2dPATH_END_ROUND, a2dPATH_END_SQAURE_EXT};
32 
33 //! is the angle within the arc segment taking into account drawing from
34 //! start to end in clockwise or anti clocwise direction.
35 A2DARTBASEDLLEXP bool InArc( double angle, double start, double end, bool clockwise );
36 
37 //! struct for how a single object on one layer was hit
38 struct A2DARTBASEDLLEXP a2dHit
39 {
40  //! Basic hit type
41  /*! For a object without childs, this is either hit_none, hit_stroke or hit_fill.
42  A stroke hit is also given if the test-point has a margin distance from the strokes fill.
43  This way 0-width strokes can also be hit. A distinction between a true stroke hit
44  and a stroke margin hit is currently not possible.
45  If the stroke or fill of a child or member is hit, the hit_child or hit_member flag is also set.
46  Note: a2dHit is only used temporarily, so there is no need to save
47  memory using bitfields.
48  */
49  enum Hit
50  {
51  //! The object is not hit. This should not happen, because the parent should include hit childs
52  hit_none = 0x00,
53  //! The point is on the stroke or stroke margin
54  hit_stroke = 0x01,
55  //! The point is in the fill area
56  hit_fill = 0x02,
57  //! The point hits a child of the object
58  hit_child = 0x04,
59  //! The point hits a member of the object (e.g. line begin/end object)
60  hit_member = 0x08,
61  //! a hit which resulted into a captured object, and may now not hit the object itself,
62  //! still the object will recieve mouse events.
63  hit_captured = 0x10
64  } m_hit;
65 
66  friend inline Hit operator | ( Hit a, Hit b ) { return ( Hit )( ( int )a | ( int ) b ); }
67 
68  //! How the point is on the stroke ( in stroke perpendicular direction )
69  enum Stroke1
70  {
71  stroke1_none,
72  // the hit is on the outside (non-fill) margin of the stroke
73  stroke1_outside,
74  // the hit is on the inside (fill) margin of the stroke
75  stroke1_inside
76  } m_stroke1;
77 
78  //! How the point is on the stroke ( in stroke parallel direction )
79  enum Stroke2
80  {
81  stroke2_none,
82  stroke2_vertex,
83  stroke2_edgehor,
84  stroke2_edgevert,
85  stroke2_edgeother
86  } m_stroke2;
87 
88  //! For edge/vertex hits the index of the edge / vertex
89  unsigned int m_index;
90 
91  //! For margin hits, the distance from the stroke center in fractions of the margin
92  /*! Note: using a fraction of the margin makes the distance independent of local scaling */
93  float m_distance;
94 
95  //! Default constructor
96  a2dHit() { memset( this, 0, sizeof( *this ) ); }
97  //! Standard constructor
98  a2dHit( Hit hit, Stroke1 stroke1, Stroke2 stroke2, unsigned int index, float distance )
99  {
100  m_hit = hit;
101  m_stroke1 = stroke1;
102  m_stroke2 = stroke2;
103  m_distance = distance;
104  m_index = index;
105  }
106  //! true if this is a hit
107  bool IsHit() const { return m_hit != hit_none; }
108  //! true if this is a stroke hit (parent or child/member stroke)
109  bool IsStrokeHit() const { return ( m_hit & hit_stroke ) != 0; }
110  //! true if this is a fill hit (parent or child/member fill)
111  bool IsFillHit() const { return ( m_hit & hit_fill ) != 0; }
112  //! true if this is a fill hit or an inside stroke hit (parent or child/member)
113  bool IsInsideHit() const { return ( m_hit & hit_fill ) != 0 || ( m_hit & hit_stroke ) != 0 && m_stroke1 == stroke1_inside; }
114 
115  //! true if this is a direct stroke hit (not a member or child object stroke hit )
116  bool IsDirectStrokeHit() const { return m_hit == hit_stroke; }
117  //! true if this is a direct fill hit (not a member or child object fill hit )
118  bool IsDirectFillHit() const { return m_hit == hit_fill; }
119  //! true if this is child hit
120  bool IsChildHit() const { return ( m_hit & hit_child ) != 0; }
121  //! true if this is member object hit (e.g. line begin/end object)
122  bool IsMemberdHit() const { return ( m_hit & hit_member ) != 0; }
123 
124  //! true if hit on stroke at a vertex
125  bool IsVertexHit() const { return ( IsStrokeHit() && m_stroke2 == stroke2_vertex ) != 0 ; }
126 
127  //! true if this is a stroke hit on an edge
128  bool IsEdgeHit() const
129  {
130  return ( IsStrokeHit() &&
131  ( m_stroke2 == stroke2_edgehor || m_stroke2 == stroke2_edgevert || m_stroke2 == stroke2_edgeother ) ) != 0 ;
132  }
133 
134  //! Stock object for no hit
136  //! Stock object for a fill hit
138  //! Stock object for an outer stroke hit on objects without vertices/edges (like circles)
140  //! Stock object for an inner stroke hit on objects without vertices/edges (like circles)
142 };
143 
144 //! defines the type of a segment in a a2dLineSegment
146 {
147  //! not specific or part of outer contour
148  a2dNORMAL_SEG = 0x0000,
149  //! links an outside contour with a hole
150  a2dLINK_SEG = 0x0001,
151  //! this segmnet is part of a hole
152  a2dHOLE_SEG = 0x0002
153 };
154 
155 //! Normal straight line segment in a2dVertexList and a2dVertexArray
156 /*! baseclass for segments in a a2dVertexList and a2dVertexArray
157 Every segment type in a a2dVertexList and a2dVertexArray has this class as Baseclass.
158 It has/maintains the end position of a segment.
159 But for the first point it is a2dVertexList and a2dVertexArray to give the begin point too.
160 
161  \ingroup vpath
162 */
163 class A2DARTBASEDLLEXP a2dLineSegment
164 {
165 
166 #ifdef CLASS_MEM_MANAGEMENT
167 
168  //! memory manager for speed up to replace system calls allocation and deallocation
169  static a2dMemManager sm_memManager;
170 public:
171  //! overloaded operator new for this class and it all derived classes
172  void* operator new( size_t bytes )
173  {
174  return sm_memManager.Allocate( bytes );
175  }
176 
177  //! overloaded operator delete for this class and it all derived classes
178  /*!
179  This function doesn't free to OS-system memory block by pointer 'space'.
180  It adds memory block by pointer 'space' to internal lists.
181  It is speed up.
182  */
183  void operator delete( void* space, size_t bytes )
184  {
185  sm_memManager.Deallocate( space, bytes );
186  }
187 #endif //CLASS_MEM_MANAGEMENT
188 
189 public:
190 
191  //! constructor
192  /*!
193  \param x endpoint of line
194  \param y endpoint of line
195  */
196  a2dLineSegment( double x = 0, double y = 0 );
197 
198  a2dLineSegment( const a2dPoint2D& point );
199 
200  a2dLineSegment( const a2dLineSegment& other );
201 
202  virtual ~a2dLineSegment();
203 
204  //! create exact copy
205  virtual a2dLineSegment* Clone();
206 
207  inline bool GetArc() const { return m_arc; }
208 
209  //klion: it is for multipoint
210  inline int GetPointCount() const { return m_pntCnt;}
211 
212  inline bool GetBin() const { return m_bin; }
213 
214  inline void SetBin( bool bin ) { m_bin = bin; }
215 
216  //! calculate length
217  virtual double Length( const a2dLineSegment& prev );
218 
219  a2dPoint2D GetPoint() { return a2dPoint2D( m_x, m_y ); }
220 
221  void SetPoint( a2dPoint2D pos ) { m_x = pos.m_x; m_y = pos.m_y; }
222 
223  //! Set the type of the segment
224  void SetSegType( a2dSegType type ) { m_segtype = type; }
225 
226  //! get the type of the segment
227  a2dSegType GetSegType() { return m_segtype; }
228 
229  virtual a2dBoundingBox GetBbox( const a2dLineSegment& prev, const a2dAffineMatrix& lworld = a2dIDENTITY_MATRIX );
230 
231  //!x endpoint of line
232  double m_x;
233 
234  //!y endpoint of line
235  double m_y;
236 
237  //! Marker for walking over the segments
238  bool m_bin: 1;
239 
240  //! arc segment
241  bool m_arc: 1;
242 
243  //klion: it is for multipoint
244  unsigned int m_pntCnt: 2;
245 
246  //! type of segment
247  a2dSegType m_segtype: 3;
248 
249 public:
250 
251 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
252  //! this is a list of all smart pointers pointing to this object
253  a2dSmrtPtr<a2dLineSegment> *m_ownerlist;
254  //! this is needed inside the smart pointer template code
255  typedef a2dSmrtPtr<a2dLineSegment> TOwnerListClass;
256  //! Make a Dump of the objects owner list to the Debug console
257  /*! This function is usually called from the Debuggers watch window */
258  void DumpOwners();
259 #endif
260 
261 private:
262  //!how many references to this object do exist
263  int m_refcount;
264 
265  //! Call to have a new owner for this object
266  /*! This function should only be called by a2dSmrtPtr
267 
268  \remark owning mean that the object calling this member needs to call Release at some time,
269  in order to actually release/delete the object.
270 
271  \return The return value is the object itself, which is now owned on time extra.
272 
273  increment refcount by 1 ( use when adding a reference to this object)
274  */
275  a2dLineSegment* SmrtPtrOwn() { m_refcount++; return this; }
276 
277  //!To release the object, it is not longer owned by the calling object.
278  /*! This function should only be called by a2dSmrtPtr
279  */
280  bool SmrtPtrRelease()
281  {
282  m_refcount--;
283  wxASSERT_MSG( m_refcount >= 0, wxT( "a2dLineSegment Own/Release not matched (extra Release calls)" ) );
284  if ( m_refcount <= 0 )
285  {
286  delete this;
287  return true;
288  }
289  return false;
290  }
291 
292 private:
293  friend class a2dSmrtPtrBase;
294 };
295 
296 //! smart pointer to line segment
298 
299 #if defined(WXART2D_USINGDLL)
300 template class A2DARTBASEDLLEXP a2dSmrtPtr<a2dLineSegment>;
301 #endif
302 
303 #if defined(WXART2D_USINGDLL)
304 // it must be after all internal template declarations
305 template class A2DARTBASEDLLEXP std::allocator<class a2dSmrtPtr<class a2dLineSegment> >;
306 template class A2DARTBASEDLLEXP std::allocator< std::_List_nod<class a2dSmrtPtr<class a2dLineSegment>, std::allocator<class a2dSmrtPtr<class a2dLineSegment> > >::_Node >;
307 template class A2DARTBASEDLLEXP std::allocator< std::_List_ptr<class a2dSmrtPtr<class a2dLineSegment>, std::allocator<class a2dSmrtPtr<class a2dLineSegment> > >::_Nodeptr >;
308 template class A2DARTBASEDLLEXP std::list<class a2dSmrtPtr<class a2dLineSegment> >::iterator;
309 template class A2DARTBASEDLLEXP std::list<class a2dSmrtPtr<class a2dLineSegment> >;
310 template class A2DARTBASEDLLEXP a2dlist< a2dSmrtPtr<a2dLineSegment> >;
311 template class A2DARTBASEDLLEXP a2dSmrtPtrList<a2dLineSegment>;
312 #endif
313 
314 #if 0
315 class a2dLineSegmentProperty;
316 typedef a2dPropertyIdTyped< a2dLineSegment, a2dLineSegmentProperty> a2dPropertyIdLineSegment;
317 
318 //! property to hold a pointer to a linesegment
319 ///*!
320 
321 a2dPolyHandle::PROPID_linesegment.SetPropertyObjectToObject(
322  handle, new a2dLineSegmentProperty( a2dPolyHandle::PROPID_linesegment, seg ) );
323 
324 a2dLineSegment* segment = a2dHandle::PROPID_linesegment.GetPropertyValuePtr( handle );
325 
326 \ingroup property
327 ///
328 class a2dLineSegmentProperty: public a2dNamedProperty
329 {
330 public:
331 
332  a2dLineSegmentProperty();
333 
334  a2dLineSegmentProperty( const a2dPropertyIdLineSegment& id, a2dLineSegment* segment );
335 
336  a2dLineSegmentProperty( const a2dLineSegmentProperty& other );
337 
338  virtual a2dNamedProperty* Clone( a2dObject::CloneOptions options ) const;
339 
340  virtual void Assign( const a2dNamedProperty& other );
341 
342  virtual ~a2dLineSegmentProperty();
343 
344  //! Construct a new property object from a string
345  //! If this is not appropriate, this may return NULL
346  static a2dLineSegmentProperty* CreatePropertyFromString( const a2dPropertyIdLineSegment& id, const wxString& value );
347 
348  a2dLineSegment* GetValuePtr() { return m_segment; }
349 
350 #if wxART2D_USE_CVGIO
351  virtual void DoSave( wxObject* parent, a2dIOHandlerXmlSerOut& out, a2dXmlSer_flag xmlparts , a2dObjectList* towrite );
352  virtual void DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts );
353 #endif //wxART2D_USE_CVGIO
354 
355  DECLARE_DYNAMIC_CLASS( a2dLineSegmentProperty )
356 
357 protected:
358 
359  a2dLineSegment* m_segment;
360 };
361 #endif
362 
363 //! Arc Segment in a2dVertexList
364 /*! Create an circular Arc segment.
365  From the previous segment to this segment position, create an arc
366  passing through a thrid point.
367  The Third point defines the Arc segment going clockwise or anticlockwise from begin to end point.
368 
369  \ingroup vpath
370 */
371 class A2DARTBASEDLLEXP a2dArcSegment : public a2dLineSegment
372 {
373 public:
374 
375  //! create arc segment
376  /*!
377  Begin point of arc is position/endpoint of previous segment
378  \param x1 x of arc endpoint
379  \param y1 y of arc endpoint
380  \param x2 x of arc midpoint
381  \param y2 y of arc midpoint
382  */
383  a2dArcSegment( double x1 = 0, double y1 = 0, double x2 = 0, double y2 = 0 );
384 
385  //! create arc segment
386  /*!
387  Begin point of arc is position/endpoint of previous segment
388  \param prev previous segment
389  \param xc x of arc center
390  \param yc y of arc center
391  \param angle angle of arc in degrees relative from the previous segment endpoint (negatif for clockwise)
392  */
393  a2dArcSegment( const a2dLineSegment& prev, double xc, double yc, double angle );
394 
395  //! create arc segment
396  /*!
397  Begin point of arc is position/endpoint of previous segment
398  \param prev previous segment
399  \param xc x of arc center
400  \param yc y of arc center
401  \param x1 x of arc endpoint
402  \param y1 y of arc endpoint
403  \param x2 x (xc,yc) ( x2,y2) define a line which the arc will cross
404  \param y2 y (xc,yc) ( x2,y2) define a line which the arc will cross
405 
406  \remark radius is defined by prev segment endpoint and (xc,yc), x1,y1 is adjusted to fit radius.
407  */
408  a2dArcSegment( const a2dLineSegment& prev, double xc, double yc, double x1, double y1, double x2, double y2 );
409 
410  //! copy constructor
411  a2dArcSegment( const a2dArcSegment& other );
412 
413  //! destructor
414  ~a2dArcSegment();
415 
416  //! create exact copy
417  virtual a2dLineSegment* Clone();
418 
419  //! Calculation of center for the Arc
420  /*! output :
421  \param prev the previous segment, to get start point of arc.
422  \param radius radius of the circle calculated
423  \param center_x x of the center calculated
424  \param center_y y of the center calculated
425  \param beginrad calculated starting angle in radians
426  \param midrad calculated middle angle in radians
427  \param endrad calculated end angle in radians
428  \param phit total calculated in radians (AntiClockwise positif, else negatif )
429 
430  \return true if the arc is indeed an Arc if a straight line return false.
431  */
432  bool CalcR( const a2dLineSegment& prev, double& radius, double& center_x, double& center_y, double& beginrad, double& midrad, double& endrad, double& phit ) const;
433 
434  //! calculate length
435  virtual double Length( const a2dLineSegment& prev );
436 
437  //! calculate new mid point bsed on prev segment radius and center.
438  /*!
439  \param prev the previous segment, to get start point of arc.
440  \param radius radius of the circle calculated
441  \param center_x x of the center calculated
442  \param center_y y of the center calculated
443  \param clockwise if true a clockwise arc segment is assumed for creating the mid point
444  */
445  void CalcMidPoint( const a2dLineSegment& prev, double center_x, double center_y, double radius, bool clockwise );
446 
447  //! get middle on arc segment between end and start
448  a2dPoint2D GetMidPoint() const { return a2dPoint2D( m_x2, m_y2 ); }
449 
450  //! set middle point of arc segment
451  /*!
452  \param prev the previous segment, to get start point of arc.
453  \param xm x of middle point
454  \param ym y of middle point
455  */
456  void SetMidPoint( const a2dLineSegment& prev, double xm, double ym );
457 
458  //! Get origin X of arc
459  double GetOx( const a2dLineSegment& prev ) const;
460 
461  //! Get origin Y of arc
462  double GetOy( const a2dLineSegment& prev ) const;
463 
464  //! Get origin of arc
465  a2dPoint2D GetOrigin( const a2dLineSegment& prev ) const;
466 
467  //! Get bounding box of arc
468  a2dBoundingBox GetBbox( const a2dLineSegment& prev, const a2dAffineMatrix& lworld = a2dIDENTITY_MATRIX ) const;
469 
470  //! x2 x of arc midpoint
471  double m_x2;
472  //! y2 y of arc midpoint
473  double m_y2;
474 };
475 
476 #include <vector>
477 #include <wx/listimpl.cpp>
478 
479 //! array of polygon vertexes a2dLineSegment
480 /*!
481  \ingroup canvasobject
482 */
483 
484 class A2DARTBASEDLLEXP a2dVertexList;
485 class A2DARTBASEDLLEXP a2dVpath;
486 
487 //! vertex array of line and arc segments.
488 /*!
489  Holds a wxArray of a2dLineSegment objects.
490  Drawing the sequence of segments, represents the form of the shape.
491  Shape depends on the type of segment and style of that segment.
492  There are two type, straight line segments and arc segments
493 */
494 class A2DARTBASEDLLEXP a2dVertexArray : public std::vector<a2dLineSegmentPtr>
495 {
496 public:
497 
498  //! constructor
499  a2dVertexArray();
500 
501  //! constructor
502  a2dVertexArray( const a2dVertexArray& other );
503 
504  a2dVertexArray( const a2dVertexList& other );
505 
506  //! destructor
507  ~a2dVertexArray();
508 
509  //! operator =
510  a2dVertexArray& operator=( const a2dVertexArray& other );
511 
512  a2dVertexArray& operator=( const a2dVertexList& other );
513 
514  //! get the previous segment as a polygon ( GetLast() is no previous )
515  a2dLineSegmentPtr GetPreviousAround( wxUint32 index ) const;
516 
517  //! get the next segment as a polygon ( GetFirst() is no next )
518  a2dLineSegmentPtr GetNextAround( wxUint32 index ) const;
519 
520  inline a2dLineSegmentPtr Item( wxUint32 index ) { return this->operator[]( index ); }
521 
522  inline a2dLineSegmentPtr Item( wxUint32 index ) const { return this->operator[]( index ); }
523 
524  void RemoveAt( size_t index );
525 
526  void Insert( a2dLineSegment* segment, size_t index );
527 
528  //! calculate length of path
529  double Length() const;
530 
531  //! add point to end or begin
532  void AddPoint( const a2dPoint2D& point, bool atEnd = true );
533 
534  //! add point to end or begin
535  void AddPoint( double x, double y, bool atEnd = true );
536 
537  //! sets a point of a segment and adjusts arc it midpoints.
538  void SetPointAdjustArcs( unsigned int n, double x, double y, bool polygon );
539 
540  //! sets a point of a segment and adjusts arc it midpoints.
541  void SetPointAdjustArcs( a2dLineSegmentPtr seg, double x, double y, bool polygon );
542 
543  //! calculate the area of simple polygons (not selfintersecting)
544  //! coordinates may be negatif
545  double CalcArea() const;
546 
547  //! Convert complex segments to line segments.
548  void ConvertToLines( double aberation = 0 );
549 
550  //! transform all segments with given matrix
551  /*! \remark complex segments will be broken down to lines. */
552  void Transform( const a2dAffineMatrix& world );
553 
554  //! return true if there are a2dArcSegment segments.
555  bool HasArcs() const;
556 
557  //! return a boundingbox of a transformed vertexarray
558  a2dBoundingBox GetBbox( const a2dAffineMatrix& lworld = a2dIDENTITY_MATRIX );
559 
560  //! create a contour around polygon/polyline
561  a2dVertexArray* Contour( double distance, a2dPATH_END_TYPE pathtype );
562 
563  //!Spline conversion for polygon.
564  a2dVertexArray* ConvertSplinedPolygon( double Aber ) const;
565 
566  //!Spline conversion for polyline.
567  a2dVertexArray* ConvertSplinedPolyline( double Aber ) const;
568 
569  //! return converted vector Vpath, arc segments stay intact if arc is true
570  a2dVpath* ConvertToVpath( bool arc, bool closed = false );
571 
572  //! extensive hittesting on vertex list seen as polygon.
573  /*!
574  \param ptest point to test against polygon.
575  \param margin point with this margin around.
576  */
577  a2dHit HitTestPolygon( const a2dPoint2D& ptest, double margin );
578 
579  //! extensive hittesting on vertex list seen as polyline.
580  /*!
581  \param ptest point to test against polyline.
582  \param margin point with this margin around.
583  */
584  a2dHit HitTestPolyline( const a2dPoint2D& ptest, double margin );
585 
586  //! line segments ( not arcs ) with same point are removed
587  bool RemoveRedundant( bool polygon );
588 
589  //! line segments ( not arcs ) with same point are returned
590  a2dVertexList* GetRedundant( bool polygon, double smallest = 0 );
591 };
592 
593 //! vertex list of line and arc segments.
594 /*!
595  Holds a wxList of a2dLineSegment objects.
596  Drawing the sequence of segments, represents the form of the shape.
597  Shape depends on the type of segment and style of that segment.
598  There are two type, straight line segments and arc segments
599 */
600 class A2DARTBASEDLLEXP a2dVertexList : public a2dSmrtPtrList< a2dLineSegment >
601 {
602 public:
603  a2dVertexList();
604 
605  a2dVertexList( const a2dVertexList& other );
606 
607  a2dVertexList( const a2dVertexArray& other );
608 
609  ~a2dVertexList();
610 
611  a2dVertexList& operator=( const a2dVertexList& other );
612 
613  a2dVertexList& operator=( const a2dVertexArray& other );
614 
615  //! return true if there are a2dArcSegment segments.
616  bool HasArcs() const;
617 
618  //! get the previous segment as a polygon ( --end() is no previous )
619  a2dVertexList::iterator GetPreviousAround( a2dVertexList::iterator iter );
620 
621  //! get the next segment as a polygon ( begin() is no next )
622  a2dVertexList::iterator GetNextAround( a2dVertexList::iterator iter );
623 
624  //! get the previous segment as a polygon ( --end() is no previous )
625  a2dVertexList::const_iterator GetPreviousAround( a2dVertexList::const_iterator iter ) const;
626 
627  //! get the next segment as a polygon ( begin() is no next )
628  a2dVertexList::const_iterator GetNextAround( a2dVertexList::const_iterator iter ) const;
629 
630  //! make the segmenet where iter point to the beginning of the list and shift the rest
631  void MakeBegin( a2dVertexList::iterator iter );
632 
633  //! calculate length of path
634  double Length();
635 
636  //! Find the index of a specific object
637  int IndexOf( a2dLineSegment* object ) const;
638 
639  //! insert before segment with index given
640  void Insert( unsigned int index, a2dLineSegmentPtr segin );
641 
642  //! sets a point of a segment and adjusts arc it midpoints.
643  void SetPointAdjustArcs( unsigned int n, double x, double y, bool polygon );
644 
645  void SetPointAdjustArcs( a2dLineSegmentPtr segin, double x, double y, bool polygon );
646 
647  //! Convert complex segments to line segments.
648  void ConvertToLines( double aberation = 0 );
649 
650  //! variation on ConvertToLines, this function converts an arc into segments were
651  //! the number of segments is determined by dphi (maximum angle of a piece) and
652  //! minseg (the arc will contain a minimum of minseg segments).
653  //! e.g. if you specify dphi on 10 a circle will be converted into 36 segments,
654  //! however if you specify minseg as 40, it will be converted to 40 segments.
655  void ConvertToLines( double dphi, int minseg );
656 
657  //! calculate the area of simple polygons (not selfintersecting)
658  //! coordinates may be negatif
659  double CalcArea() const;
660 
661  //! determines the direction of the polygon, all polygons must be in a
662  //! clockwise order to avoid conflics with certain algortihms. When
663  //! the polygon is in a non-clockwise order the area of the polygon is in
664  //! a clockwise order.
665  //! returns true if the polygon is in clockwise order
666  bool DirectionIsClockWise();
667 
668  bool CheckForOneCircle( a2dPoint2D& middle, double& radius );
669 
670  //! The point on the polyline which form an arc meeting the constraints, will be replaced
671  //! by an Arc segment.
672  //! The Arc segment will be with the following 4 coordinates:
673  //! - start point
674  //! - end point
675  //! - mid point (a point half way on the arc between start and end)
676  //! - center point
677  //! In principle only 3 point are need to define a circle, but if start and end point are the same,
678  //! the center point will be needed to.
679  //!
680  //! \param iter start of first point
681  //! \param n ( number of point2 to replace with arc )
682  //! \param center_x center_x (center point of the ARC)
683  //! \param center_y center_y (center point of the ARC)
684  void InsertArc( a2dVertexList::iterator& iter, int n, double center_x, double center_y );
685 
686  //! De punten van de polygon worden getest of ze converteerd kunnen
687  //! worden naar ARC's.
688  //! Conversie vind plaats als; aberatie < aber
689  //! Rmin < radius < Rmax
690  void ConvertPolylineToArc( double aber, double Rmin, double Rmax );
691 
692  void ConvertPolygonToArc( double aber, double Rmin, double Rmax );
693 
694  //! a row of point (minimum 4 ) will be tested to see if its an arc.
695  /*!
696  3 options:
697  - aber > 0 arc should be within this margin to all points
698  - aber = 0 arc points should be exact on the arc. The largets distance of segments to arc
699  is not important.
700  - aber < 0 combines the first two options.
701 
702  Abberation means maximum distance along a segment towards the perfect arc.
703 
704  \param iter start testing here
705  \param aber see above
706  \param Rmin (minimum radius)
707  \param Rmax (maximum radius)
708  \param center_p_old (centerpunt van circelboog)
709 
710  \return number of points found to be an arc
711  */
712  int TestArc( a2dVertexList::iterator& iter, double aber, double Rmin, double Rmax , a2dPoint2D& center_p_old );
713 
714  //! return a boundingbox of a transformed vertexarray
715  a2dBoundingBox GetBbox( const a2dAffineMatrix& lworld = a2dIDENTITY_MATRIX );
716 
717  //! transform all segments with given matrix
718  /*! \remark complex segments will be broken down to lines. */
719  void Transform( const a2dAffineMatrix& world );
720 
721  //!Spline conversion for polygon.
722  a2dVertexList* ConvertSplinedPolygon( double Aber ) const;
723 
724  //!Spline conversion for polyline.
725  a2dVertexList* ConvertSplinedPolyline( double Aber ) const;
726 
727  void ConvertIntoSplinedPolygon( double Aber );
728 
729  void ConvertIntoSplinedPolyline( double Aber );
730 
731  //! create a contour around polygon/polyline
732  a2dVertexList* ConvertToContour( double distance, a2dPATH_END_TYPE pathtype, bool asPolygon = false );
733 
734  //! return converted vector Vpath, arc segments stay intact if arc is true
735  a2dVpath* ConvertToVpath( bool arc, bool closed = false );
736 
737  //! create a contour around polygon/polyline
738  void Contour( double distance, a2dPATH_END_TYPE pathtype, bool asPolygon = false );
739 
740  //! add point to end or begin
741  void AddPoint( const a2dPoint2D& point, bool atEnd = true );
742 
743  //! add point to end or begin
744  void AddPoint( double x, double y, bool atEnd = true );
745 
746  //! create an arc and add it to the graph
747  /*!
748  \param center of circle
749  \param begin point of arc
750  \param end point of arc
751  \param radius of arc
752  \param clock if true clockwise
753  \param aber aberation for generating the segments
754  \param addAtFront where to add this segment
755  */
756  void CreateArc( const a2dPoint2D& center, const a2dPoint2D& begin, const a2dPoint2D& end, double radius, bool clock, double aber, bool addAtFront );
757 
758  //! create an arc and add it to the graph
759  /*!
760  \param center of circle
761  \param incoming last segment starting this segment
762  \param end point of arc
763  \param radius of arc
764  \param aber aberation for generating the segments
765  \param addAtFront where to add this segment
766  */
767  void CreateArc( const a2dPoint2D& center, const a2dLine& incoming, const a2dPoint2D& end, double radius, double aber, bool addAtFront );
768 
769  //! create a contour segements at a distance, using two segment
770  /*!
771  The angle of the two connected segments in combination with the factor is used to decide
772  if the corner is rounded or straight.
773 
774  \param currentline
775  \param nextline
776  \param factor
777  \param addAtFront where to add this segment
778  */
779  void OffsetContour_rounded( const a2dLine& currentline, const a2dLine& nextline, double factor, bool addAtFront );
780 
781  //! line segments ( not arcs ) with same point are removed
782  bool RemoveRedundant( bool polygon );
783 
784  //! line segments ( not arcs ) with same point are returned
785  a2dVertexList* GetRedundant( bool polygon, double smallest = 0 );
786 
787  //! extensive hittesting on vertex list seen as polygon.
788  /*!
789  \param ptest point to test against polygon.
790  \param margin point with this margin around.
791  */
792  a2dHit HitTestPolygon( const a2dPoint2D& ptest, double margin );
793 
794  //! extensive hittesting on vertex list seen as polyline.
795  /*!
796  \param ptest point to test against polyline.
797  \param margin point with this margin around.
798  */
799  a2dHit HitTestPolyline( const a2dPoint2D& ptest, double margin );
800 
801 private:
802  //!how many references to this object do exist
803  int m_refcount;
804 
805  //! Call to have a new owner for this object
806  /*! This function should only be called by a2dSmrtPtr
807 
808  \remark owning mean that the object calling this member needs to call Release at some time,
809  in order to actually release/delete the object.
810 
811  \return The return value is the object itself, which is now owned on time extra.
812 
813  increment refcount by 1 ( use when adding a reference to this object)
814  */
815  a2dVertexList* SmrtPtrOwn() { m_refcount++; return this; }
816 
817  //!To release the object, it is not longer owned by the calling object.
818  /*! This function should only be called by a2dSmrtPtr
819  */
820  bool SmrtPtrRelease()
821  {
822  m_refcount--;
823  wxASSERT_MSG( m_refcount >= 0, wxT( "a2dLineSegment Own/Release not matched (extra Release calls)" ) );
824  if ( m_refcount <= 0 )
825  {
826  delete this;
827  return true;
828  }
829  return false;
830  }
831 
832 private:
833  friend class a2dSmrtPtrBase;
834 };
835 
837 
838 typedef a2dVertexList::iterator a2dVertexListIter;
839 
841 
842 //! how do we move to the point of the segment
843 /*!
844  \ingroup vpath
845 */
847 {
848  a2dPATHSEG_MOVETO, /*!< Move to point */
849  a2dPATHSEG_LINETO, /*!< Line to point */
850  a2dPATHSEG_LINETO_NOSTROKE, /*!< Line to point without stroke (if not closed as polygon, same as moveto) */
851  a2dPATHSEG_QBCURVETO, /*!< Quadratic Bezier Curve */
852  a2dPATHSEG_QBCURVETO_NOSTROKE, /*!< Quadratic Bezier Curve to point without stroke (if not closed as polygon, same as moveto) */
853  a2dPATHSEG_CBCURVETO, /*!< Cubic Bezier Curve */
854  a2dPATHSEG_CBCURVETO_NOSTROKE, /*!< Cubic Bezier Curve to point without stroke (if not closed as polygon, same as moveto) */
855  a2dPATHSEG_ARCTO, /*!< Arc */
856  a2dPATHSEG_ARCTO_NOSTROKE /*!< arc to point without stroke (if not closed as polygon, same as moveto) */
857 };
858 
859 //! end of a segment type
860 /*!
861  \ingroup vpath
862 */
864 {
865  a2dPATHSEG_END_OPEN, /*!< Open end */
866  a2dPATHSEG_END_CLOSED, /*!< Closed to last a2dPATHSEG_MOVETO segment */
867  a2dPATHSEG_END_CLOSED_NOSTROKE, /*!< Closed to last a2dPATHSEG_MOVETO segment with No Stroke*/
868 };
869 
870 //! Normal straight line segment in a2dVpath
871 /*! baseclass for segments in a a2dVpath
872 Every segment type in a a2dVpath has this class as Baseclass.
873 It has/maintains the end position of a segment.
874 But for the first point it is a2dVpathSegment to give the begin point too.
875 
876  \ingroup vpath
877 */
878 class A2DARTBASEDLLEXP a2dVpathSegment
879 {
880 public:
881 
882  //! constructor
883  /*!
884  \param x endpoint of line
885  \param y endpoint of line
886  \param type line type ( e.g line to, move to, no stroking )
887  \param close endpoint closes the shape.
888  */
889  a2dVpathSegment( double x, double y, a2dPATHSEG type = a2dPATHSEG_LINETO, a2dPATHSEG_END close = a2dPATHSEG_END_OPEN );
890 
891  //! constructor
892  a2dVpathSegment( const a2dVpathSegment& other );
893 
894  //! destructor
895  virtual ~a2dVpathSegment();
896 
897  //! create exact copy
898  virtual a2dVpathSegment* Clone();
899 
900  //! easy way to test type of segment
901  inline a2dPATHSEG GetType() const { return m_type; }
902 
903  //! used in processing
904  inline bool GetBin() const { return m_bin; }
905 
906  //! used in processing
907  inline void SetBin( bool bin ) { m_bin = bin; }
908 
909  //! is this segment the closing a part since the last move
910  inline a2dPATHSEG_END GetClose() const { return m_close; }
911 
912  //! set this segment is closing a part since the last move
913  inline void SetClose( a2dPATHSEG_END close ) { m_close = close; }
914 
915  //! calculate length
916  virtual double Length( a2dSmrtPtr<a2dVpathSegment> prev );
917 
918  //!x endpoint of line
919  double m_x1;
920 
921  //!y endpoint of line
922  double m_y1;
923 
924  //! Marker for walking over the segments
925  bool m_bin : 1;
926 
927  //! easy way to test type of segment
928  a2dPATHSEG m_type : 5;
929 
930  //! is the path closing here or not
931  a2dPATHSEG_END m_close : 3;
932 
933 private:
934  //!how many references to this object do exist
935  int m_refcount;
936 
937  //! Call to have a new owner for this object
938  /*! This function should only be called by a2dSmrtPtr
939 
940  \remark owning mean that the object calling this member needs to call Release at some time,
941  in order to actually release/delete the object.
942 
943  \return The return value is the object itself, which is now owned on time extra.
944 
945  increment refcount by 1 ( use when adding a reference to this object)
946  */
947  a2dVpathSegment* SmrtPtrOwn() { m_refcount++; return this; }
948 
949  //!To release the object, it is not longer owned by the calling object.
950  /*! This function should only be called by a2dSmrtPtr
951  */
952  bool SmrtPtrRelease()
953  {
954  m_refcount--;
955  wxASSERT_MSG( m_refcount >= 0, wxT( "a2dVpathSegment Own/Release not matched (extra Release calls)" ) );
956  if ( m_refcount <= 0 )
957  {
958  delete this;
959  return true;
960  }
961  return false;
962  }
963 
964 private:
965  friend class a2dSmrtPtrBase;
966 };
967 
968 //! smart pointer to path segment
970 
971 //! Quadratic Bezier curve
972 /*! Create a curved segment based on qaudratic Bezier spline
973  let P0 be end point of previous segment
974  let P1 be inbetween point of this segment (m_x2, m_y2)
975  let P2 be end point of this segment (m_x1, m_y1)
976 
977  Then the formula describing points on the curve are:
978 
979  For ( 0 <= t <= 1 )
980  Point(t) = (1-t)^2*P0 + 2*t*(1-t)*P1 + t^2*P2
981 
982  \ingroup vpath
983 */
984 class A2DARTBASEDLLEXP a2dVpathQBCurveSegment : public a2dVpathSegment
985 {
986 public:
987 
988  //! constructor
989  /*!
990  \param x1 endpoint of curve
991  \param y1 endpoint of curve
992  \param x2 first control point coming from previous segment in path
993  \param y2 first control point coming from previous segment in path
994  \param type draw or move towards point
995  \param close if true close this path with the last move command/segment
996  */
997  a2dVpathQBCurveSegment( double x1, double y1, double x2, double y2, a2dPATHSEG type = a2dPATHSEG_QBCURVETO, a2dPATHSEG_END close = a2dPATHSEG_END_OPEN );
998 
999  //! constructor
1000  /*!
1001  \param prev previous segment
1002  \param x1 endpoint of curve
1003  \param y1 endpoint of curve
1004  \param type draw or move towards point
1005  \param close if true close this path with the last move command/segment
1006  */
1007  a2dVpathQBCurveSegment( a2dVpathSegmentPtr prev, double x1, double y1, a2dPATHSEG type = a2dPATHSEG_QBCURVETO, a2dPATHSEG_END close = a2dPATHSEG_END_OPEN );
1008 
1009  //! copy constructor
1011 
1012  //! destructor
1014 
1015  //! create exact copy
1016  virtual a2dVpathSegment* Clone();
1017 
1018  //! calculate length
1019  virtual double Length( a2dVpathSegmentPtr prev );
1020 
1021  //! calculate position at t, used for length
1022  void PositionAt( a2dVpathSegmentPtr prev, double t, double& xt, double& yt );
1023 
1024  //! control point
1025  double m_x2;
1026  //! control point
1027  double m_y2;
1028 
1029 };
1030 
1031 //! Cubic Bezier curve
1032 /*! Create a curved segment based on Cubic Bezier spline
1033  let P0 be end point of previous segment
1034  let P1 be inbetween point of this segment (m_x2, m_y2)
1035  let P2 be second inbetween point of this segment (m_x3, m_y3)
1036  let P3 be end point of this segment (m_x1, m_y1)
1037 
1038  Then the formula describing points on the curve are:
1039 
1040  For ( 0 <= t <= 1 )
1041  Point(t) = (1-t)^3*P0 + 3*t*(1-t)^2*P1 + 3*t^2*(1-t)*P2 + t^3*P3
1042 
1043  \ingroup vpath
1044 */
1045 class A2DARTBASEDLLEXP a2dVpathCBCurveSegment : public a2dVpathSegment
1046 {
1047 public:
1048 
1049  //! constructor
1050  /*!
1051  \param x1 endpoint of curve
1052  \param y1 endpoint of curve
1053  \param x2 first control point coming from previous segment in path
1054  \param y2 first control point coming from previous segment in path
1055  \param x3 second control point coming from previous segment in path
1056  \param y3 second control point coming from previous segment in path
1057  \param type draw or move towards point
1058  \param close if true close this path with the last move command/segment
1059  */
1060  a2dVpathCBCurveSegment( double x1, double y1, double x2, double y2, double x3, double y3, a2dPATHSEG type = a2dPATHSEG_CBCURVETO, a2dPATHSEG_END close = a2dPATHSEG_END_OPEN );
1061 
1062  //! constructor
1063  /*!
1064  \param prev previous segment
1065  \param x1 endpoint of curve
1066  \param y1 endpoint of curve
1067  \param x3 second control point coming from previous segment in path
1068  \param y3 second control point coming from previous segment in path
1069  \param type draw or move towards point
1070  \param close if true close this path with the last move command/segment
1071 
1072  \remark x2 first control point is mirror of second control point of previous segment in path, if Cubic else last endpoint
1073  \remark y2 first control point is mirror of second control point of previous segment in path, if Cubic else last endpoint
1074  */
1075  a2dVpathCBCurveSegment( a2dVpathSegmentPtr prev, double x1, double y1, double x3, double y3, a2dPATHSEG type = a2dPATHSEG_CBCURVETO, a2dPATHSEG_END close = a2dPATHSEG_END_OPEN );
1076 
1077  //! copy constructor
1079 
1080  //! destructor
1082 
1083  //! create exact copy
1084  virtual a2dVpathSegment* Clone();
1085 
1086  //! calculate length
1087  virtual double Length( a2dVpathSegmentPtr prev );
1088 
1089  //! calculate position at t, used for length
1090  void PositionAt( a2dVpathSegmentPtr prev, double t, double& xt, double& yt );
1091 
1092  //! control point 1
1093  double m_x2;
1094  //! control point 1
1095  double m_y2;
1096 
1097  //! control point 2
1098  double m_x3;
1099  //! control point 2
1100  double m_y3;
1101 
1102 };
1103 
1104 //! Arc Segment
1105 /*! Create an circular Arc segment.
1106  From the previous segment to this segment position, create an arc
1107  passing through a thrid point.
1108  The Third point defines the Arc segment going clockwise or anticlockwise from begin to end point.
1109 
1110  \ingroup vpath
1111 */
1112 class A2DARTBASEDLLEXP a2dVpathArcSegment : public a2dVpathSegment
1113 {
1114 public:
1115 
1116  //! create arc segment
1117  /*!
1118  Begin point of arc is position/endpoint of previous segment
1119  \param x1 x of arc endpoint
1120  \param y1 y of arc endpoint
1121  \param x2 x of arc midpoint
1122  \param y2 y of arc midpoint
1123  \param type draw or move towards point
1124  \param close if true close this path with the last move command/segment
1125  */
1126  a2dVpathArcSegment( double x1, double y1, double x2, double y2, a2dPATHSEG type = a2dPATHSEG_ARCTO, a2dPATHSEG_END close = a2dPATHSEG_END_OPEN );
1127 
1128  //! create arc segment
1129  /*!
1130  Begin point of arc is position/endpoint of previous segment
1131 
1132  \param prev previous segment
1133  \param xc x of arc center
1134  \param yc y of arc center
1135  \param angle angle of arc in degrees relative from the previous segment endpoint (negatif for clockwise)
1136  \param type draw or move towards point
1137  \param close if true close this path with the last move command/segment
1138  */
1139  a2dVpathArcSegment( a2dVpathSegmentPtr prev, double xc, double yc, double angle, a2dPATHSEG type = a2dPATHSEG_ARCTO, a2dPATHSEG_END close = a2dPATHSEG_END_OPEN );
1140 
1141  //! create arc segment
1142  /*!
1143  Begin point of arc is position/endpoint of previous segment
1144  \param prev previous segment
1145  \param xc x of arc center
1146  \param yc y of arc center
1147  \param x1 x of arc endpoint
1148  \param y1 y of arc endpoint
1149  \param x2 x (xc,yc) ( x2,y2) define a line which the arc will cross
1150  \param y2 y (xc,yc) ( x2,y2) define a line which the arc will cross
1151  \param type draw or move towards point
1152  \param close if true close this path with the last move command/segment
1153 
1154  \remark radius is defined by prev segment endpoint and (xc,yc), x1,y1 is adjusted to fit radius.
1155  */
1156  a2dVpathArcSegment( a2dVpathSegmentPtr prev, double xc, double yc, double x1, double y1, double x2, double y2, a2dPATHSEG type = a2dPATHSEG_ARCTO, a2dPATHSEG_END close = a2dPATHSEG_END_OPEN );
1157 
1158  //! constructor
1159  a2dVpathArcSegment( const a2dVpathArcSegment& other );
1160 
1161  //! destructor
1162  ~a2dVpathArcSegment();
1163 
1164  //! create exact copy
1165  virtual a2dVpathSegment* Clone();
1166 
1167  //! Calculation of center for the Arc
1168  /*! output :
1169  \param prev the previous segment, to get start point of arc.
1170  \param radius radius of the circle calculated
1171  \param center_x x of the center calculated
1172  \param center_y y of the center calculated
1173  \param beginrad calculated starting angle in radians
1174  \param midrad calculated middle angle in radians
1175  \param endrad calculated end angle in radians
1176  \param phit total calculated in radians (AntiClockwise positif, else negatif )
1177 
1178  \return true if the arc is indeed an Arc if a straight line return false.
1179  */
1180  bool CalcR( a2dVpathSegmentPtr prev, double& radius, double& center_x, double& center_y, double& beginrad, double& midrad, double& endrad, double& phit );
1181 
1182  //! calculate length
1183  virtual double Length( a2dVpathSegmentPtr prev );
1184 
1185  //! second control point
1186  double m_x2;
1187  //! second control point
1188  double m_y2;
1189 };
1190 
1191 
1192 //!Vector Path
1193 /*!
1194  Holds a wxArray of a2dVpathSegment objects.
1195  Drawing the sequence of segments, represents the form of the shape.
1196  Shape depends on the type of segment and style of that segment.
1197 
1198  With Vpath very complex shapes can be generated, also disjoint.
1199  e.g. polygons with holes, donuts.
1200 
1201  a2dVpathSegment is the baseclass for several types of segments.
1202 
1203  \sa a2dVpathQBCurveSegment
1204  \sa a2dVpathCBCurveSegment
1205  \sa a2dVpathArcSegment
1206 
1207  \remark do use Shrink() after filling a a2dVpath, to reduce memory usage
1208 
1209  \ingroup vpath
1210 */
1211 class A2DARTBASEDLLEXP a2dVpath : public std::vector<a2dVpathSegmentPtr>
1212 {
1213 public:
1214 
1215  //constructor for a vector path array
1216  a2dVpath();
1217 
1218  //constructor for a vector path array, using as input a a2dVertexArray
1219  a2dVpath( a2dVertexArray& vertexArray, bool moveToFirst = true , bool closeLast = false );
1220 
1221  //constructor for a vector path array, using as input a a2dVertexList
1222  a2dVpath( a2dVertexList& vertexList, bool moveToFirst = true , bool closeLast = false );
1223 
1224  //! destructor
1225  ~a2dVpath();
1226 
1227  //! operator =
1228  a2dVpath& operator=( const a2dVpath& other );
1229 
1230  //! calculate length of path, assuming continues path.
1231  double Length();
1232 
1233  //! test if closed polygon ( a2dPATHSEG_MOVETO, a2dPATHSEG_LINETO, a2dPATHSEG_ARCTO )
1234  bool IsPolygon( bool allowArc = true );
1235 
1236  //! test if polyline ( a2dPATHSEG_MOVETO, a2dPATHSEG_LINETO, a2dPATHSEG_ARCTO )
1237  bool IsPolyline( bool allowArc = true );
1238 
1239  //! add a segment
1240  void Add( a2dVpathSegment* seg ) { push_back( seg ); }
1241 
1242  //! add a vertexArray to an existing path
1243  void Add( a2dVertexArray& vertexArray, bool moveToFirst = true , bool closeLast = false );
1244 
1245  //! add a vertexlist to an existing path
1246  void Add( a2dVertexList& vertexList, bool moveToFirst = true , bool closeLast = false );
1247 
1248  inline a2dVpathSegmentPtr Item( wxUint32 index ) { return this->operator[]( index ); }
1249 
1250  inline a2dVpathSegmentPtr Item( wxUint32 index ) const { return this->operator[]( index ); }
1251 
1252  void RemoveAt( size_t index );
1253 
1254  void Insert( a2dVpathSegment* segment, size_t index );
1255 
1256  //! add a MoveTo command to the path
1257  /*!
1258  \param x point to move to
1259  \param y point to move to
1260  */
1261  void MoveTo( double x, double y );
1262 
1263  //! add a LineTo command to the path
1264  /*!
1265  \param x endpoint of line
1266  \param y endpoint of line
1267  \param withStroke Do stroke or not this line segment
1268  */
1269  void LineTo( double x, double y, bool withStroke = true );
1270 
1271  //! add a quadratic bezier segment to the path
1272  /*!
1273  \param x1 endpoint of curve
1274  \param y1 endpoint of curve
1275  \param x2 first control point coming from previous segment in path
1276  \param y2 first control point coming from previous segment in path
1277  \param withStroke Do stroke or not this line segment
1278  */
1279  void QBCurveTo( double x1, double y1, double x2, double y2, bool withStroke = true );
1280 
1281  //! add a quadratic bezier segment to the path, using the previous segment.
1282  /*!
1283  \param x1 endpoint of curve
1284  \param y1 endpoint of curve
1285  \param withStroke Do stroke or not this line segment
1286  */
1287  void QBCurveTo( double x1, double y1, bool withStroke = true );
1288 
1289  //! add a quadratic bezier segment to the path
1290  /*!
1291  \param x1 endpoint of curve
1292  \param y1 endpoint of curve
1293  \param x2 first control point coming from previous segment in path
1294  \param y2 first control point coming from previous segment in path
1295  \param x3 second control point coming from previous segment in path
1296  \param y3 second control point coming from previous segment in path
1297  \param withStroke Do stroke or not this line segment
1298  */
1299  void CBCurveTo( double x1, double y1, double x2, double y2, double x3, double y3, bool withStroke = true );
1300 
1301  //! add a quadratic bezier segment to the path, using the previous segment.
1302  /*!
1303  \param x1 endpoint of curve
1304  \param y1 endpoint of curve
1305  \param x3 second control point coming from previous segment in path
1306  \param y3 second control point coming from previous segment in path
1307  \param withStroke Do stroke or not this line segment
1308 
1309  \remark x2 first control point is mirror of second control point of previous segment in path, if Cubic else last endpoint
1310  \remark y2 first control point is mirror of second control point of previous segment in path, if Cubic else last endpoint
1311  */
1312  void CBCurveTo( double x1, double y1, double x3, double y3, bool withStroke = true );
1313 
1314  //! add an arc segment to the path
1315  /*!
1316  Begin point of arc is position/endpoint of previous segment
1317  \param x1 x of arc endpoint
1318  \param y1 y of arc endpoint
1319  \param x2 x of arc midpoint
1320  \param y2 y of arc midpoint
1321  \param withStroke Do stroke or not this line segment
1322  */
1323  void ArcTo( double x1, double y1, double x2, double y2, bool withStroke = true );
1324 
1325  //! add an arc segment to the path, using the previous segment
1326  /*!
1327  Begin point of arc is position/endpoint of previous segment
1328 
1329  \param xc x of arc center
1330  \param yc y of arc center
1331  \param angle angle of arc in degrees relative from the previous segment endpoint (negatif for clockwise)
1332  \param withStroke Do stroke or not this line segment
1333  */
1334  void ArcTo( double xc, double yc, double angle, bool withStroke = true );
1335 
1336  //! add an arc segment to the path, using the previous segment
1337  /*!
1338  Begin point of arc is position/endpoint of previous segment
1339  \param xc x of arc center
1340  \param yc y of arc center
1341  \param x1 x of arc endpoint
1342  \param y1 y of arc endpoint
1343  \param x2 x (xc,yc) ( x2,y2) define a line which the arc will cross
1344  \param y2 y (xc,yc) ( x2,y2) define a line which the arc will cross
1345  \param withStroke Do stroke or not this line segment
1346 
1347  \remark radius is defined by prev segment endpoint and (xc,yc), x1,y1 is adjusted to fit radius.
1348  */
1349  void ArcTo( double xc, double yc, double x1, double y1, double x2, double y2, bool withStroke = true );
1350 
1351  //! Closing the path as a filled area
1352  /*!
1353  The part sinve the last move is close to that move vertex.
1354 
1355  \param withStroke Do stroke or not this line segment
1356  */
1357  void Close( bool withStroke = true );
1358 
1359  //! Convert complex segments to line segments.
1360  void ConvertToLines();
1361 
1362  //! Convert to a a2dVertexList, taking and assuming it has only closed contours in path.
1363  //! Replacing non line (and arc segments if arc is true) with line segments.
1364  void ConvertToPolygon( a2dListOfa2dVertexList& addTo, bool arc = true );
1365 
1366  //! create an offset contour at distance
1367  /*!
1368  From all path parts a version is created
1369  that surrounds the original part at the given distance.
1370  */
1371  void Contour( double distance, a2dPATH_END_TYPE pathtype );
1372 
1373  //! transform all segments with given matrix
1374  /*!
1375  \remark complex segments will be broken down to lines.
1376  */
1377  void Transform( const a2dAffineMatrix& world );
1378 
1379  //! return a boundingbox of a transformed a2dVpath
1380  a2dBoundingBox GetBbox( const a2dAffineMatrix& lworld = a2dIDENTITY_MATRIX );
1381 
1382 
1383 private:
1384 
1385  //! Create a path around this path, at a distance
1386  /*!
1387  This is used to create/draw paths with a thickness.
1388  The output is a polygon shape, which can be drawn filled as a polygon.
1389  */
1390  void SingleContour( a2dVpath& converted, unsigned int start, unsigned int segments, double distance, a2dPATH_END_TYPE pathtype );
1391 };
1392 
1393 //! Calculate the square distance between two points
1394 inline double ClclDistSqrPntPnt( const a2dPoint2D& a, const a2dPoint2D& b )
1395 {
1396  double dx = a.m_x - b.m_x;
1397  double dy = a.m_y - b.m_y;
1398 
1399  return dx * dx + dy * dy;
1400 }
1401 
1402 //! Calculate the square distance between a point and a line
1403 /*! This returns DBL_MAX if the point is beyond the edges */
1404 extern A2DARTBASEDLLEXP double ClclDistSqrPntLine( const a2dPoint2D& p, const a2dPoint2D& p1, const a2dPoint2D& p2 );
1405 
1406 //! Calculation of center for the Arc
1407 /*!
1408  \param begin_x x start point of arc.
1409  \param begin_y y start point of arc.
1410  \param middle_x x middle point of arc.
1411  \param middle_y y middle point of arc.
1412  \param end_x x end point of arc.
1413  \param end_y y end point of arc.
1414  \param radius radius of the circle calculated
1415  \param center_p the center calculated
1416 
1417  \return true if the arc is indeed an Arc if a straight line return false.
1418 */
1419 bool CalcR( double begin_x, double begin_y, double middle_x, double middle_y, double end_x, double end_y,
1420  double& radius, a2dPoint2D& center_p );
1421 
1422 //! Calculation of center for the Arc
1423 /*!
1424  \param begin_x x start point of arc.
1425  \param begin_y y start point of arc.
1426  \param middle_x x middle point of arc.
1427  \param middle_y y middle point of arc.
1428  \param end_x x end point of arc.
1429  \param end_y y end point of arc.
1430  \param radius radius of the circle calculated
1431  \param center_x x of the center calculated
1432  \param center_y y of the center calculated
1433  \param beginrad calculated starting angle in radians
1434  \param midrad calculated middle angle in radians
1435  \param endrad calculated end angle in radians
1436  \param phit total calculated in radians (AntiClockwise positif, else negatif )
1437 
1438  \return true if the arc is indeed an Arc if a straight line return false.
1439 */
1440 bool CalcR( double begin_x, double begin_y, double middle_x, double middle_y, double end_x, double end_y,
1441  double& radius, double& center_x, double& center_y, double& beginrad, double& midrad, double& endrad, double& phit );
1442 
1443 
1444 #endif
1445 
wxPoint2DDouble a2dPoint2D
this to define if coordinate numbers are integer or doubles
Definition: artglob.h:47
bool IsStrokeHit() const
true if this is a stroke hit (parent or child/member stroke)
Definition: polyver.h:109
a2dSmrtPtr< a2dVpathSegment > a2dVpathSegmentPtr
smart pointer to path segment
Definition: polyver.h:969
a2dPATH_END_TYPE
defines the way a polyline with a contour width is ended.
Definition: polyver.h:31
(In) Visible property that can be added to Docview Objects.
Definition: gen.h:1785
Hit
Basic hit type.
Definition: polyver.h:49
unsigned int m_index
For edge/vertex hits the index of the edge / vertex.
Definition: polyver.h:89
void SetSegType(a2dSegType type)
Set the type of the segment.
Definition: polyver.h:224
Quadratic Bezier curve.
Definition: polyver.h:984
a2dSegType GetSegType()
get the type of the segment
Definition: polyver.h:227
Simple Memory manager for some objects which often create and destroy to replace OS-system calls...
Definition: a2dmemmgr.h:20
double m_x2
control point
Definition: polyver.h:1025
fundamental classes used by all other modules.
Stroke1
How the point is on the stroke ( in stroke perpendicular direction )
Definition: polyver.h:69
a2dDocumentRenderStyle operator|(a2dDocumentRenderStyle a, a2dDocumentRenderStyle b)
OR-ing a2dDocumentRenderStyle is allowed.
Definition: canglob.h:50
Cubic Bezier curve.
Definition: polyver.h:1045
static a2dHit stock_nohit
Stock object for no hit.
Definition: polyver.h:135
static a2dHit stock_strokeinside
Stock object for an inner stroke hit on objects without vertices/edges (like circles) ...
Definition: polyver.h:141
double m_y2
control point
Definition: polyver.h:1027
bool IsHit() const
true if this is a hit
Definition: polyver.h:107
double m_y3
control point 2
Definition: polyver.h:1100
Arc Segment.
Definition: polyver.h:1112
double m_x3
control point 2
Definition: polyver.h:1098
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:819
double m_x2
x2 x of arc midpoint
Definition: polyver.h:471
double ClclDistSqrPntPnt(const a2dPoint2D &a, const a2dPoint2D &b)
Calculate the square distance between two points.
Definition: polyver.h:1394
bool IsChildHit() const
true if this is child hit
Definition: polyver.h:120
A trivial base class for a2dSmrtPtr. Non-template class, so that it can.
Definition: smrtptr.h:55
double ClclDistSqrPntLine(const a2dPoint2D &p, const a2dPoint2D &p1, const a2dPoint2D &p2)
Calculate the square distance between a point and a line.
Definition: polyver.cpp:103
bool IsDirectFillHit() const
true if this is a direct fill hit (not a member or child object fill hit )
Definition: polyver.h:118
float m_distance
For margin hits, the distance from the stroke center in fractions of the margin.
Definition: polyver.h:93
Arc Segment in a2dVertexList.
Definition: polyver.h:371
vertex array of line and arc segments.
Definition: polyver.h:494
this segmnet is part of a hole
Definition: polyver.h:152
a2dAffineMatrix a2dIDENTITY_MATRIX
global a2dAffineMatrix to set/pass the identity matrix.
Definition: afmatrix.cpp:51
double m_y2
control point 1
Definition: polyver.h:1095
a2dPATHSEG_END GetClose() const
is this segment the closing a part since the last move
Definition: polyver.h:910
not specific or part of outer contour
Definition: polyver.h:148
bool GetBin() const
used in processing
Definition: polyver.h:904
vertex list of line and arc segments.
Definition: polyver.h:600
bool IsDirectStrokeHit() const
true if this is a direct stroke hit (not a member or child object stroke hit )
Definition: polyver.h:116
a2dHit(Hit hit, Stroke1 stroke1, Stroke2 stroke2, unsigned int index, float distance)
Standard constructor.
Definition: polyver.h:98
a2dSmrtPtr< a2dLineSegment > a2dLineSegmentPtr
smart pointer to line segment
Definition: polyver.h:297
void SetBin(bool bin)
used in processing
Definition: polyver.h:907
void SetClose(a2dPATHSEG_END close)
set this segment is closing a part since the last move
Definition: polyver.h:913
a2dPATHSEG
how do we move to the point of the segment
Definition: polyver.h:846
bool IsEdgeHit() const
true if this is a stroke hit on an edge
Definition: polyver.h:128
std list compatible list
Definition: a2dlist.h:42
classes for initializing the artbase modules, and set paths to be used for fonts etc.
double m_y2
second control point
Definition: polyver.h:1188
bool IsVertexHit() const
true if hit on stroke at a vertex
Definition: polyver.h:125
bounding class for optimizing drawing speed.
Normal straight line segment in a2dVpath.
Definition: polyver.h:878
void * Allocate(size_t bytes)
function for allocating memory block by size bytes
Definition: a2dmemmgr.cpp:47
bool IsInsideHit() const
true if this is a fill hit or an inside stroke hit (parent or child/member)
Definition: polyver.h:113
Normal straight line segment in a2dVertexList and a2dVertexArray.
Definition: polyver.h:163
void Add(a2dVpathSegment *seg)
add a segment
Definition: polyver.h:1240
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:862
double m_x2
control point 1
Definition: polyver.h:1093
A 2x3 affine matrix class for 2D transformations.
Definition: afmatrix.h:53
double m_y2
y2 y of arc midpoint
Definition: polyver.h:473
a2dSegType
defines the type of a segment in a a2dLineSegment
Definition: polyver.h:145
bool IsMemberdHit() const
true if this is member object hit (e.g. line begin/end object)
Definition: polyver.h:122
double m_x
x endpoint of line
Definition: polyver.h:232
struct for how a single object on one layer was hit
Definition: polyver.h:38
double m_y
y endpoint of line
Definition: polyver.h:235
a2dPATHSEG GetType() const
easy way to test type of segment
Definition: polyver.h:901
Line calculations.
Definition: liner.h:36
static a2dHit stock_strokeoutside
Stock object for an outer stroke hit on objects without vertices/edges (like circles) ...
Definition: polyver.h:139
double m_y1
y endpoint of line
Definition: polyver.h:922
bool InArc(double angle, double start, double end, bool clockwise)
Definition: polyver.cpp:148
a2dPATHSEG_END
end of a segment type
Definition: polyver.h:863
The a2dBoundingBox class stores one a2dBoundingBox of a a2dCanvasObject.
Definition: bbox.h:39
static a2dHit stock_fill
Stock object for a fill hit.
Definition: polyver.h:137
affine matrix class
double m_x1
x endpoint of line
Definition: polyver.h:919
bool CalcR(double begin_x, double begin_y, double middle_x, double middle_y, double end_x, double end_y, double &radius, a2dPoint2D &center_p)
Calculation of center for the Arc.
Definition: polyver.cpp:4786
This template class is for property ids with a known data type.
Definition: id.h:477
Vector Path.
Definition: polyver.h:1211
links an outside contour with a hole
Definition: polyver.h:150
Stroke2
How the point is on the stroke ( in stroke parallel direction )
Definition: polyver.h:79
bool IsFillHit() const
true if this is a fill hit (parent or child/member fill)
Definition: polyver.h:111
a2dHit()
Default constructor.
Definition: polyver.h:96
list of a2dObject&#39;s
Definition: gen.h:3157
CloneOptions
options for cloning
Definition: gen.h:1200
double m_x2
second control point
Definition: polyver.h:1186
a2dPoint2D GetMidPoint() const
get middle on arc segment between end and start
Definition: polyver.h:448
basic 2 point line class for intersection and contouring routines.
polyver.h Source File -- Sun Oct 12 2014 17:04:23 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation