• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeedu API Reference
  • KDE Home
  • Contact Us
 

kig

  • sources
  • kde-4.12
  • kdeedu
  • kig
  • objects
polygon_imp.cc
Go to the documentation of this file.
1 // Copyright (C) 2004 Pino Toscano <toscano.pino@tiscali.it>
2 
3 // This program is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU General Public License
5 // as published by the Free Software Foundation; either version 2
6 // of the License, or (at your option) any later version.
7 
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU General Public License for more details.
12 
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 // 02110-1301, USA.
17 
18 //
19 // note (mp): there are now two boolean flags:
20 // minside: tells if we want a "filled polygon"
21 // mopen: in case of boundary, if we want an open polygonal curve
22 //
23 // a much more clean solution would be to have an AbstractPolygon class
24 // from which to inherit "Polygon", "ClosedPolygonal" and "OpenPolygonal"
25 // we should think of the possibility of doing this...
26 //
27 #include "polygon_imp.h"
28 
29 #include <math.h>
30 
31 #include "bogus_imp.h"
32 #include "line_imp.h"
33 #include "point_imp.h"
34 #include "bezier_imp.h"
35 
36 #include "../misc/common.h"
37 #include "../misc/coordinate.h"
38 #include "../misc/kigpainter.h"
39 #include "../misc/kigtransform.h"
40 
41 #include "../kig/kig_document.h"
42 #include "../kig/kig_view.h"
43 
44 #include <klocale.h>
45 
46 #include <cmath>
47 
48 AbstractPolygonImp::AbstractPolygonImp( const uint npoints, const std::vector<Coordinate>& points,
49  const Coordinate& centerofmass )
50  : mnpoints( npoints ), mpoints( points ), mcenterofmass( centerofmass )
51 {
52 }
53 
54 AbstractPolygonImp::AbstractPolygonImp( const std::vector<Coordinate>& points )
55 {
56  uint npoints = points.size();
57  Coordinate centerofmassn = Coordinate( 0, 0 );
58 
59  for ( uint i = 0; i < npoints; ++i )
60  {
61  centerofmassn += points[i];
62  }
63  mpoints = points;
64  mcenterofmass = centerofmassn/npoints;
65  mnpoints = npoints;
66 }
67 
68 AbstractPolygonImp::~AbstractPolygonImp()
69 {
70 }
71 
72 Coordinate AbstractPolygonImp::attachPoint() const
73 {
74  return mcenterofmass;
75 }
76 
77 std::vector<Coordinate> AbstractPolygonImp::ptransform( const Transformation& t ) const
78 {
79 /*mp:
80  * any projective transformation makes sense for a polygon,
81  * since segments transform into segments (but see below...)
82  * of course regular polygons will no longer be
83  * regular if t is not homothetic.
84  * for projective transformations the polygon could transform to
85  * an unbounded nonconnected polygon; this happens if some side
86  * of the polygon crosses the critical line that maps to infinity
87  * this can be easily checked using the getProjectiveIndicator
88  * function
89  */
90  std::vector<Coordinate> np;
91 // if ( ! t.isHomothetic() )
92 // return new InvalidImp();
93 
94  if ( ! t.isAffine() ) /* in this case we need a more extensive test */
95  {
96  double maxp = -1.0;
97  double minp = 1.0;
98  for ( uint i = 0; i < mpoints.size(); ++i )
99  {
100  double p = t.getProjectiveIndicator( mpoints[i] );
101  if ( p > maxp ) maxp = p;
102  if ( p < minp ) minp = p;
103  }
104  if ( maxp > 0 && minp < 0 ) return np;
105  }
106  for ( uint i = 0; i < mpoints.size(); ++i )
107  {
108  Coordinate nc = t.apply( mpoints[i] );
109  if ( !nc.valid() )
110  return np;
111  np.push_back( nc );
112  }
113  return np;
114 }
115 
116 ObjectImp* FilledPolygonImp::transform( const Transformation& t ) const
117 {
118  std::vector<Coordinate> np = ptransform( t );
119  if ( np.size() != mnpoints ) return new InvalidImp;
120  return new FilledPolygonImp( np );
121 }
122 
123 ObjectImp* ClosedPolygonalImp::transform( const Transformation& t ) const
124 {
125  std::vector<Coordinate> np = ptransform( t );
126  if ( np.size() != mnpoints ) return new InvalidImp;
127  return new ClosedPolygonalImp( np );
128 }
129 
130 ObjectImp* OpenPolygonalImp::transform( const Transformation& t ) const
131 {
132  std::vector<Coordinate> np = ptransform( t );
133  if ( np.size() != mnpoints ) return new InvalidImp;
134  return new OpenPolygonalImp( np );
135 }
136 
137 bool AbstractPolygonImp::isInPolygon( const Coordinate& p ) const
138 {
139  // (algorithm sent to me by domi)
140  // We intersect with the horizontal ray from point to the right and
141  // count the number of intersections. That, along with some
142  // minor optimalisations of the intersection test..
143  bool inside_flag = false;
144  double cx = p.x;
145  double cy = p.y;
146 
147  Coordinate prevpoint = mpoints.back();
148  bool prevpointbelow = mpoints.back().y >= cy;
149  for ( uint i = 0; i < mpoints.size(); ++i )
150  {
151  Coordinate point = mpoints[i];
152  bool pointbelow = point.y >= cy;
153  if ( prevpointbelow != pointbelow )
154  {
155  // possibility of intersection: points on different side from
156  // the X axis
157  //bool rightofpt = point.x >= cx;
158  // mp: we need to be a little bit more conservative here, in
159  // order to treat properly the case when the point is on the
160  // boundary
161  //if ( rightofpt == ( prevpoint.x >= cx ) )
162  if ( ( point.x - cx )*(prevpoint.x - cx ) > 0 )
163  {
164  // points on same side of Y axis -> easy to test intersection
165  // intersection iff one point to the right of c
166  if ( point.x >= cx )
167  inside_flag = !inside_flag;
168  }
169  else
170  {
171  // points on different sides of Y axis -> we need to calculate
172  // the intersection.
173  // mp: we want to check if the point is on the boundary, and
174  // return false in such case
175  double num = ( point.y - cy )*( prevpoint.x - point.x );
176  double den = prevpoint.y - point.y;
177  if ( num == den*( point.x - cx ) ) return false;
178  if ( num/den <= point.x - cx )
179  inside_flag = !inside_flag;
180  }
181  }
182  prevpoint = point;
183  prevpointbelow = pointbelow;
184  }
185  return inside_flag;
186 }
187 
188 bool AbstractPolygonImp::isOnCPolygonBorder( const Coordinate& p, double dist, const KigDocument& doc ) const
189 {
190  uint reduceddim = mpoints.size() - 1;
191 
192  if ( isOnSegment( p, mpoints[reduceddim], mpoints[0], dist ) )
193  return true;
194 
195  return isOnOPolygonBorder( p, dist, doc );
196 }
197 
198 bool AbstractPolygonImp::isOnOPolygonBorder( const Coordinate& p, double dist, const KigDocument& ) const
199 {
200  bool ret = false;
201  uint reduceddim = mpoints.size() - 1;
202  for ( uint i = 0; i < reduceddim; ++i )
203  {
204  ret |= isOnSegment( p, mpoints[i], mpoints[i+1], dist );
205  }
206 
207  return ret;
208 }
209 
210 bool AbstractPolygonImp::inRect( const Rect& r, int width, const KigWidget& w ) const
211 {
212  bool ret = false;
213  uint reduceddim = mpoints.size() - 1;
214  for ( uint i = 0; !ret && i < reduceddim; ++i )
215  {
216  SegmentImp s( mpoints[i], mpoints[i+1] );
217  ret = lineInRect( r, mpoints[i], mpoints[i+1], width, &s, w );
218  }
219  if ( !ret )
220  {
221  SegmentImp s( mpoints[reduceddim], mpoints[0] );
222  ret = lineInRect( r, mpoints[reduceddim], mpoints[0], width, &s, w );
223  }
224 
225  return ret;
226 }
227 
228 bool AbstractPolygonImp::valid() const
229 {
230  return true;
231 }
232 
233 int AbstractPolygonImp::numberOfProperties() const
234 {
235  return Parent::numberOfProperties();
236 }
237 
238 int FilledPolygonImp::numberOfProperties() const
239 {
240  return Parent::numberOfProperties() + 7;
241 }
242 
243 int ClosedPolygonalImp::numberOfProperties() const
244 {
245  return Parent::numberOfProperties() + 7;
246 }
247 
248 int OpenPolygonalImp::numberOfProperties() const
249 {
250  return Parent::numberOfProperties() + 5;
251 }
252 
253 const QByteArrayList AbstractPolygonImp::propertiesInternalNames() const
254 {
255  return Parent::propertiesInternalNames();
256 }
257 
258 const QByteArrayList FilledPolygonImp::propertiesInternalNames() const
259 {
260  QByteArrayList l = Parent::propertiesInternalNames();
261  l += "polygon-number-of-sides";
262  l += "polygon-perimeter";
263  l += "polygon-surface";
264  l += "closed-polygonal";
265  l += "polygonal";
266  l += "polygon-center-of-mass";
267  l += "polygon-winding-number";
268  assert( l.size() == FilledPolygonImp::numberOfProperties() );
269  return l;
270 }
271 
272 const QByteArrayList ClosedPolygonalImp::propertiesInternalNames() const
273 {
274  QByteArrayList l = Parent::propertiesInternalNames();
275  l += "number-of-sides";
276  l += "polygon-perimeter";
277  l += "polygon-surface";
278  l += "polygon";
279  l += "polygonal";
280  l += "polygon-center-of-mass";
281  l += "polygon-winding-number";
282  assert( l.size() == ClosedPolygonalImp::numberOfProperties() );
283  return l;
284 }
285 
286 const QByteArrayList OpenPolygonalImp::propertiesInternalNames() const
287 {
288  QByteArrayList l = Parent::propertiesInternalNames();
289  l += "number-of-sides";
290  l += "length";
291  l += "bezier-curve";
292  l += "polygon";
293  l += "closed-polygonal";
294  assert( l.size() == OpenPolygonalImp::numberOfProperties() );
295  return l;
296 }
297 
298 const QByteArrayList AbstractPolygonImp::properties() const
299 {
300  return Parent::properties();
301 }
302 
303 const QByteArrayList FilledPolygonImp::properties() const
304 {
305  QByteArrayList l = Parent::properties();
306  l += I18N_NOOP( "Number of sides" );
307  l += I18N_NOOP( "Perimeter" );
308  l += I18N_NOOP( "Surface" );
309  l += I18N_NOOP( "Boundary Polygonal" );
310  l += I18N_NOOP( "Open Boundary Polygonal" );
311  l += I18N_NOOP( "Center of Mass of the Vertices" );
312  l += I18N_NOOP( "Winding Number" );
313  assert( l.size() == FilledPolygonImp::numberOfProperties() );
314  return l;
315 }
316 
317 const QByteArrayList ClosedPolygonalImp::properties() const
318 {
319  QByteArrayList l = Parent::properties();
320  l += I18N_NOOP( "Number of sides" );
321  l += I18N_NOOP( "Perimeter" );
322  l += I18N_NOOP( "Surface" );
323  l += I18N_NOOP( "Inside Polygon" );
324  l += I18N_NOOP( "Open Polygonal Curve" );
325  l += I18N_NOOP( "Center of Mass of the Vertices" );
326  l += I18N_NOOP( "Winding Number" );
327  assert( l.size() == ClosedPolygonalImp::numberOfProperties() );
328  return l;
329 }
330 
331 const QByteArrayList OpenPolygonalImp::properties() const
332 {
333  QByteArrayList l = Parent::properties();
334  l += I18N_NOOP( "Number of sides" );
335  l += I18N_NOOP( "Length" );
336  l += I18N_NOOP( "Bézier Curve" );
337  l += I18N_NOOP( "Associated Polygon" );
338  l += I18N_NOOP( "Closed Polygonal Curve" );
339  assert( l.size() == OpenPolygonalImp::numberOfProperties() );
340  return l;
341 }
342 
343 const ObjectImpType* AbstractPolygonImp::impRequirementForProperty( int which ) const
344 {
345  if ( which < Parent::numberOfProperties() )
346  return Parent::impRequirementForProperty( which );
347  else return AbstractPolygonImp::stype();
348 }
349 
350 const ObjectImpType* FilledPolygonImp::impRequirementForProperty( int which ) const
351 {
352  if ( which < Parent::numberOfProperties() )
353  return Parent::impRequirementForProperty( which );
354  else return FilledPolygonImp::stype();
355 }
356 
357 const ObjectImpType* ClosedPolygonalImp::impRequirementForProperty( int which ) const
358 {
359  if ( which < Parent::numberOfProperties() )
360  return Parent::impRequirementForProperty( which );
361  else return ClosedPolygonalImp::stype();
362 }
363 
364 const ObjectImpType* OpenPolygonalImp::impRequirementForProperty( int which ) const
365 {
366  if ( which < Parent::numberOfProperties() )
367  return Parent::impRequirementForProperty( which );
368  else return OpenPolygonalImp::stype();
369 }
370 
371 const char* AbstractPolygonImp::iconForProperty( int which ) const
372 {
373  assert( which < AbstractPolygonImp::numberOfProperties() );
374  if ( which < Parent::numberOfProperties() )
375  return Parent::iconForProperty( which );
376  else assert( false );
377  return "";
378 }
379 
380 const char* FilledPolygonImp::iconForProperty( int which ) const
381 {
382  assert( which < FilledPolygonImp::numberOfProperties() );
383  if ( which < Parent::numberOfProperties() )
384  return Parent::iconForProperty( which );
385  else if ( which == Parent::numberOfProperties() )
386  return "en"; // number of sides
387  else if ( which == Parent::numberOfProperties() + 1 )
388  return "circumference"; // perimeter
389  else if ( which == Parent::numberOfProperties() + 2 )
390  return "areaCircle"; // surface
391  else if ( which == Parent::numberOfProperties() + 3 )
392  return "kig_polygon"; // closed polygonal (minside = true) or polygon
393  else if ( which == Parent::numberOfProperties() + 4 )
394  return "openpolygon"; // open polygonal
395  else if ( which == Parent::numberOfProperties() + 5 )
396  return "point"; // center of mass
397  else if ( which == Parent::numberOfProperties() + 6 )
398  return "w"; // winding number
399  else assert( false );
400  return "";
401 }
402 
403 const char* ClosedPolygonalImp::iconForProperty( int which ) const
404 {
405  assert( which < ClosedPolygonalImp::numberOfProperties() );
406  if ( which < Parent::numberOfProperties() )
407  return Parent::iconForProperty( which );
408  else if ( which == Parent::numberOfProperties() )
409  return "en"; // number of sides
410  else if ( which == Parent::numberOfProperties() + 1 )
411  return "circumference"; // perimeter
412  else if ( which == Parent::numberOfProperties() + 2 )
413  return "areaCircle"; // surface
414  else if ( which == Parent::numberOfProperties() + 3 )
415  return "kig_polygon"; // closed polygonal (minside = true) or polygon
416  else if ( which == Parent::numberOfProperties() + 4 )
417  return "openpolygon"; // open polygonal
418  else if ( which == Parent::numberOfProperties() + 5 )
419  return "point"; // center of mass
420  else if ( which == Parent::numberOfProperties() + 6 )
421  return "w"; // winding number
422  else assert( false );
423  return "";
424 }
425 
426 const char* OpenPolygonalImp::iconForProperty( int which ) const
427 {
428  assert( which < OpenPolygonalImp::numberOfProperties() );
429  if ( which < Parent::numberOfProperties() )
430  return Parent::iconForProperty( which );
431  else if ( which == Parent::numberOfProperties() )
432  return "en"; // number of sides
433  else if ( which == Parent::numberOfProperties() + 1 )
434  return "circumference"; // perimeter
435  else if ( which == Parent::numberOfProperties() + 2 )
436  return "bezierN"; // Bezier curve
437  else if ( which == Parent::numberOfProperties() + 3 )
438  return "kig_polygon"; // closed polygonal (minside = true) or polygon
439  else if ( which == Parent::numberOfProperties() + 4 )
440  return "kig_polygon"; // closed polygonal
441  else assert( false );
442  return "";
443 }
444 
445 ObjectImp* AbstractPolygonImp::property( int which, const KigDocument& w ) const
446 {
447  assert( which < AbstractPolygonImp::numberOfProperties() );
448  if ( which < Parent::numberOfProperties() )
449  return Parent::property( which, w );
450  else assert( false );
451  return new InvalidImp;
452 }
453 
454 ObjectImp* FilledPolygonImp::property( int which, const KigDocument& w ) const
455 {
456  assert( which < FilledPolygonImp::numberOfProperties() );
457  if ( which < Parent::numberOfProperties() )
458  return Parent::property( which, w );
459  else if ( which == Parent::numberOfProperties() )
460  {
461  // number of sides
462  return new IntImp( mnpoints );
463  }
464  else if ( which == Parent::numberOfProperties() + 1)
465  {
466  // perimeter
467  return new DoubleImp( cperimeter () );
468  }
469  else if ( which == Parent::numberOfProperties() + 2)
470  {
471  int wn = windingNumber (); // not able to compute area for such polygons...
472  if ( wn < 0 ) wn = -wn;
473  if ( wn != 1 ) return new InvalidImp;
474  return new DoubleImp( fabs( area () ) );
475  }
476  else if ( which == Parent::numberOfProperties() + 3)
477  {
478  return new ClosedPolygonalImp( mpoints ); // polygon boundary
479  }
480  else if ( which == Parent::numberOfProperties() + 4)
481  {
482  return new OpenPolygonalImp( mpoints ); // open polygonal curve
483  }
484  else if ( which == Parent::numberOfProperties() + 5 )
485  {
486  return new PointImp( mcenterofmass );
487  }
488  else if ( which == Parent::numberOfProperties() + 6 )
489  {
490  // winding number
491  return new IntImp( windingNumber() );
492  }
493  else assert( false );
494  return new InvalidImp;
495 }
496 
497 ObjectImp* ClosedPolygonalImp::property( int which, const KigDocument& w ) const
498 {
499  assert( which < ClosedPolygonalImp::numberOfProperties() );
500  if ( which < Parent::numberOfProperties() )
501  return Parent::property( which, w );
502  else if ( which == Parent::numberOfProperties() )
503  {
504  // number of sides
505  return new IntImp( mnpoints );
506  }
507  else if ( which == Parent::numberOfProperties() + 1)
508  {
509  // perimeter
510  return new DoubleImp( cperimeter () );
511  }
512  else if ( which == Parent::numberOfProperties() + 2)
513  {
514  int wn = windingNumber (); // not able to compute area for such polygons...
515  if ( wn < 0 ) wn = -wn;
516  if ( wn != 1 ) return new InvalidImp;
517  return new DoubleImp( fabs( area () ) );
518  }
519  else if ( which == Parent::numberOfProperties() + 3)
520  {
521  return new FilledPolygonImp( mpoints ); // filled polygon
522  }
523  else if ( which == Parent::numberOfProperties() + 4)
524  {
525  return new OpenPolygonalImp( mpoints ); // open polygonal curve
526  }
527  else if ( which == Parent::numberOfProperties() + 5 )
528  {
529  return new PointImp( mcenterofmass );
530  }
531  else if ( which == Parent::numberOfProperties() + 6 )
532  {
533  // winding number
534  return new IntImp( windingNumber() );
535  }
536  else assert( false );
537  return new InvalidImp;
538 }
539 
540 ObjectImp* OpenPolygonalImp::property( int which, const KigDocument& w ) const
541 {
542  assert( which < OpenPolygonalImp::numberOfProperties() );
543  if ( which < Parent::numberOfProperties() )
544  return Parent::property( which, w );
545  else if ( which == Parent::numberOfProperties() )
546  {
547  // number of sides
548  return new IntImp( mnpoints - 1 );
549  }
550  else if ( which == Parent::numberOfProperties() + 1)
551  {
552  // perimeter
553  return new DoubleImp( operimeter () );
554  }
555  else if ( which == Parent::numberOfProperties() + 2)
556  {
557  return new BezierImp( mpoints ); // bezier curve
558  }
559  else if ( which == Parent::numberOfProperties() + 3)
560  {
561  return new FilledPolygonImp( mpoints ); // filled polygon
562  }
563  else if ( which == Parent::numberOfProperties() + 4)
564  {
565  return new ClosedPolygonalImp( mpoints ); // polygon boundary
566  }
567  else assert( false );
568  return new InvalidImp;
569 }
570 
571 const std::vector<Coordinate> AbstractPolygonImp::points() const
572 {
573  return mpoints;
574 }
575 
576 uint AbstractPolygonImp::npoints() const
577 {
578  return mnpoints;
579 }
580 
581 double AbstractPolygonImp::operimeter() const
582 {
583  double perimeter = 0.;
584  for ( uint i = 0; i < mpoints.size() - 1; ++i )
585  {
586  perimeter += ( mpoints[i+1] - mpoints[i] ).length();
587  }
588  return perimeter;
589 }
590 
591 double AbstractPolygonImp::cperimeter() const
592 {
593  return operimeter() + ( mpoints[0] - mpoints[mpoints.size()-1] ).length();
594 }
595 
596 /*
597  * returns the *signed* area, this has a result even if the
598  * polygon is selfintersecting. On the contrary, the "area"
599  * property returns an InvalidObject in such case.
600  */
601 
602 double AbstractPolygonImp::area() const
603 {
604  double surface2 = 0.0;
605  Coordinate prevpoint = mpoints.back();
606  for ( uint i = 0; i < mpoints.size(); ++i )
607  {
608  Coordinate point = mpoints[i];
609  surface2 += ( point.x - prevpoint.x ) * ( point.y + prevpoint.y );
610  prevpoint = point;
611  }
612  return -surface2/2; /* positive if counterclockwise */
613 }
614 
615 FilledPolygonImp* FilledPolygonImp::copy() const
616 {
617  return new FilledPolygonImp( mpoints );
618 }
619 
620 ClosedPolygonalImp* ClosedPolygonalImp::copy() const
621 {
622  return new ClosedPolygonalImp( mpoints );
623 }
624 
625 OpenPolygonalImp* OpenPolygonalImp::copy() const
626 {
627  return new OpenPolygonalImp( mpoints );
628 }
629 
630 void FilledPolygonImp::visit( ObjectImpVisitor* vtor ) const
631 {
632  vtor->visit( this );
633 }
634 
635 void ClosedPolygonalImp::visit( ObjectImpVisitor* vtor ) const
636 {
637  vtor->visit( this );
638 }
639 
640 void OpenPolygonalImp::visit( ObjectImpVisitor* vtor ) const
641 {
642  vtor->visit( this );
643 }
644 
645 bool AbstractPolygonImp::equals( const ObjectImp& rhs ) const
646 {
647  return rhs.inherits( AbstractPolygonImp::stype() ) &&
648  static_cast<const AbstractPolygonImp&>( rhs ).points() == mpoints;
649 }
650 
651 const ObjectImpType* AbstractPolygonImp::stype()
652 {
653  static const ObjectImpType t(
654  Parent::stype(), "abstractpolygon",
655  I18N_NOOP( "polygon" ),
656  I18N_NOOP( "Select this polygon" ), 0, 0, 0, 0, 0, 0, 0 );
657  return &t;
658 }
659 
660 const ObjectImpType* FilledPolygonImp::stype()
661 {
662  static const ObjectImpType t(
663  Parent::stype(), "polygon",
664  I18N_NOOP( "polygon" ),
665  I18N_NOOP( "Select this polygon" ),
666  I18N_NOOP( "Select polygon %1" ),
667  I18N_NOOP( "Remove a Polygon" ),
668  I18N_NOOP( "Add a Polygon" ),
669  I18N_NOOP( "Move a Polygon" ),
670  I18N_NOOP( "Attach to this polygon" ),
671  I18N_NOOP( "Show a Polygon" ),
672  I18N_NOOP( "Hide a Polygon" )
673  );
674 
675  return &t;
676 }
677 
678 const ObjectImpType* ClosedPolygonalImp::stype()
679 {
680  static const ObjectImpType t(
681  Parent::stype(), "closedpolygonal",
682  I18N_NOOP( "closed polygonal curve" ),
683  I18N_NOOP( "Select this closed polygonal curve" ),
684  I18N_NOOP( "Select closed polygonal curve %1" ),
685  I18N_NOOP( "Remove a closed polygonal curve" ),
686  I18N_NOOP( "Add a closed polygonal curve" ),
687  I18N_NOOP( "Move a closed polygonal curve" ),
688  I18N_NOOP( "Attach to this closed polygonal curve" ),
689  I18N_NOOP( "Show a closed polygonal curve" ),
690  I18N_NOOP( "Hide a closed polygonal curve" )
691  );
692 
693  return &t;
694 }
695 
696 const ObjectImpType* OpenPolygonalImp::stype()
697 {
698  static const ObjectImpType t(
699  Parent::stype(), "polygonal",
700  I18N_NOOP( "polygonal curve" ),
701  I18N_NOOP( "Select this polygonal curve" ),
702  I18N_NOOP( "Select polygonal curve %1" ),
703  I18N_NOOP( "Remove a polygonal curve" ),
704  I18N_NOOP( "Add a polygonal curve" ),
705  I18N_NOOP( "Move a polygonal curve" ),
706  I18N_NOOP( "Attach to this polygonal curve" ),
707  I18N_NOOP( "Show a polygonal curve" ),
708  I18N_NOOP( "Hide a polygonal curve" )
709  );
710 
711  return &t;
712 }
713 
714 const ObjectImpType* FilledPolygonImp::stype3()
715 {
716  static const ObjectImpType t3(
717  FilledPolygonImp::stype(), "triangle",
718  I18N_NOOP( "triangle" ),
719  I18N_NOOP( "Select this triangle" ),
720  I18N_NOOP( "Select triangle %1" ),
721  I18N_NOOP( "Remove a Triangle" ),
722  I18N_NOOP( "Add a Triangle" ),
723  I18N_NOOP( "Move a Triangle" ),
724  I18N_NOOP( "Attach to this triangle" ),
725  I18N_NOOP( "Show a Triangle" ),
726  I18N_NOOP( "Hide a Triangle" )
727  );
728 
729  return &t3;
730 }
731 
732 const ObjectImpType* FilledPolygonImp::stype4()
733 {
734  static const ObjectImpType t4(
735  FilledPolygonImp::stype(), "quadrilateral",
736  I18N_NOOP( "quadrilateral" ),
737  I18N_NOOP( "Select this quadrilateral" ),
738  I18N_NOOP( "Select quadrilateral %1" ),
739  I18N_NOOP( "Remove a Quadrilateral" ),
740  I18N_NOOP( "Add a Quadrilateral" ),
741  I18N_NOOP( "Move a Quadrilateral" ),
742  I18N_NOOP( "Attach to this quadrilateral" ),
743  I18N_NOOP( "Show a Quadrilateral" ),
744  I18N_NOOP( "Hide a Quadrilateral" )
745  );
746 
747  return &t4;
748 }
749 
750 const ObjectImpType* FilledPolygonImp::type() const
751 {
752  uint n = mnpoints;
753 
754  if ( n == 3 ) return FilledPolygonImp::stype3();
755  if ( n == 4 ) return FilledPolygonImp::stype4();
756  return FilledPolygonImp::stype();
757 }
758 
759 const ObjectImpType* ClosedPolygonalImp::type() const
760 {
761  return ClosedPolygonalImp::stype();
762 }
763 
764 const ObjectImpType* OpenPolygonalImp::type() const
765 {
766  return OpenPolygonalImp::stype();
767 }
768 
769 bool AbstractPolygonImp::isPropertyDefinedOnOrThroughThisImp( int which ) const
770 {
771  assert( which < AbstractPolygonImp::numberOfProperties() );
772  if ( which < Parent::numberOfProperties() )
773  return Parent::isPropertyDefinedOnOrThroughThisImp( which );
774  return false;
775 }
776 
777 bool FilledPolygonImp::isPropertyDefinedOnOrThroughThisImp( int which ) const
778 {
779  assert( which < FilledPolygonImp::numberOfProperties() );
780  if ( which < Parent::numberOfProperties() )
781  return Parent::isPropertyDefinedOnOrThroughThisImp( which );
782  return false;
783 }
784 
785 bool ClosedPolygonalImp::isPropertyDefinedOnOrThroughThisImp( int which ) const
786 {
787  assert( which < ClosedPolygonalImp::numberOfProperties() );
788  if ( which < Parent::numberOfProperties() )
789  return Parent::isPropertyDefinedOnOrThroughThisImp( which );
790  return false;
791 }
792 
793 bool OpenPolygonalImp::isPropertyDefinedOnOrThroughThisImp( int which ) const
794 {
795  assert( which < OpenPolygonalImp::numberOfProperties() );
796  if ( which < Parent::numberOfProperties() )
797  return Parent::isPropertyDefinedOnOrThroughThisImp( which );
798  return false;
799 }
800 
801 Rect AbstractPolygonImp::surroundingRect() const
802 {
803  Rect r( 0., 0., 0., 0. );
804  for ( uint i = 0; i < mpoints.size(); ++i )
805  {
806  r.setContains( mpoints[i] );
807  }
808  return r;
809 }
810 
811 int AbstractPolygonImp::windingNumber() const
812 {
813  /*
814  * this is defined as the sum of the external angles while at
815  * all vertices, then normalized by 2pi. The external angle
816  * is the angle we steer at each vertex while we walk along the
817  * boundary of the polygon.
818  * In the end we only need to count how many time we cross the (1,0)
819  * direction (positive x-axis) with a positive sign if we cross while
820  * steering left and a negative sign viceversa
821  */
822 
823  int winding = 0;
824  uint npoints = mpoints.size();
825  Coordinate prevside = mpoints[0] - mpoints[npoints-1];
826  for ( uint i = 0; i < npoints; ++i )
827  {
828  uint nexti = i + 1;
829  if ( nexti >= npoints ) nexti = 0;
830  Coordinate side = mpoints[nexti] - mpoints[i];
831  double vecprod = side.x*prevside.y - side.y*prevside.x;
832  int steeringdir = ( vecprod > 0 ) ? 1 : -1;
833  if ( vecprod == 0.0 || side.y*prevside.y > 0 )
834  {
835  prevside = side;
836  continue; // cannot cross the (1,0) direction
837  }
838  if ( side.y*steeringdir < 0 && prevside.y*steeringdir >= 0 )
839  winding -= steeringdir;
840  prevside = side;
841  }
842  return winding;
843 }
844 
845 bool AbstractPolygonImp::isTwisted() const
846 {
847  /*
848  * returns true if this is a "twisted" polygon, i.e.
849  * with selfintersecting sides
850  */
851 
852  std::vector<Coordinate>::const_iterator ia, ib, ic, id;
853  double abx, aby, cdx, cdy, acx, acy, adx, ady, cax, cay, cbx, cby;
854  bool pointbelow, prevpointbelow;
855 
856  if ( mpoints.size() <= 3 ) return false;
857  ia = mpoints.end() - 1;
858 
859  for ( ib = mpoints.begin(); ib + 1 != mpoints.end(); ++ib)
860  {
861  abx = ib->x - ia->x;
862  aby = ib->y - ia->y;
863  ic = ib + 1;
864  acx = ic->x - ia->x;
865  acy = ic->y - ia->y;
866  prevpointbelow = ( abx*acy <= aby*acx );
867 
868  for ( id = ib + 2; id != mpoints.end(); ++id)
869  {
870  if ( id == ia ) break;
871  adx = id->x - ia->x;
872  ady = id->y - ia->y;
873  pointbelow = ( abx*ady <= aby*adx );
874  if ( prevpointbelow != pointbelow )
875  {
876  /* il segmento cd interseca il supporto di ab */
877  cdx = id->x - ic->x;
878  cdy = id->y - ic->y;
879  cax = ia->x - ic->x;
880  cay = ia->y - ic->y;
881  cbx = ib->x - ic->x;
882  cby = ib->y - ic->y;
883  if ( ( cdx*cay <= cdy*cax ) != ( cdx*cby <= cdy*cbx ) ) return true;
884  }
885  prevpointbelow = pointbelow;
886  ic = id;
887  }
888  ia = ib;
889  }
890  return false;
891 }
892 
893 bool AbstractPolygonImp::isMonotoneSteering() const
894 {
895  /*
896  * returns true if while walking along the boundary,
897  * steering is always in the same direction
898  */
899 
900  uint npoints = mpoints.size();
901  Coordinate prevside = mpoints[0] - mpoints[npoints-1];
902  int prevsteeringdir = 0;
903  for ( uint i = 0; i < npoints; ++i )
904  {
905  uint nexti = i + 1;
906  if ( nexti >= npoints ) nexti = 0;
907  Coordinate side = mpoints[nexti] - mpoints[i];
908  double vecprod = side.x*prevside.y - side.y*prevside.x;
909  int steeringdir = ( vecprod > 0 ) ? 1 : -1;
910  if ( vecprod == 0.0 )
911  {
912  prevside = side;
913  continue; // going straight
914  }
915  if ( prevsteeringdir*steeringdir < 0 ) return false;
916  prevside = side;
917  prevsteeringdir = steeringdir;
918  }
919  return true;
920 }
921 
922 bool AbstractPolygonImp::isConvex() const
923 {
924  if ( ! isMonotoneSteering() ) return false;
925  int winding = windingNumber();
926  if ( winding < 0 ) winding = -winding;
927  assert ( winding > 0 );
928  return winding == 1;
929 }
930 
931 /*
932  * end of abstract type, start three real types
933  */
934 
935 FilledPolygonImp::FilledPolygonImp( const std::vector<Coordinate>& points )
936  : AbstractPolygonImp( points )
937 {
938 }
939 
940 void FilledPolygonImp::draw( KigPainter& p ) const
941 {
942  p.drawPolygon( mpoints );
943 }
944 
945 bool FilledPolygonImp::contains( const Coordinate& p, int,
946  const KigWidget& ) const
947 {
948  return isInPolygon( p );
949 }
950 
951 ClosedPolygonalImp::ClosedPolygonalImp( const std::vector<Coordinate>& points )
952  : AbstractPolygonImp( points )
953 {
954 }
955 
956 void ClosedPolygonalImp::draw( KigPainter& p ) const
957 {
958  for ( unsigned int i = 0; i < mnpoints - 1; i++ )
959  p.drawSegment( mpoints[i], mpoints[i+1] );
960  p.drawSegment( mpoints[mnpoints-1], mpoints[0] );
961 }
962 
963 bool ClosedPolygonalImp::contains( const Coordinate& p, int width,
964  const KigWidget& w ) const
965 {
966  return isOnCPolygonBorder( p, w.screenInfo().normalMiss( width ), w.document() );
967 }
968 
969 OpenPolygonalImp::OpenPolygonalImp( const std::vector<Coordinate>& points )
970  : AbstractPolygonImp( points )
971 {
972 }
973 
974 void OpenPolygonalImp::draw( KigPainter& p ) const
975 {
976  for ( unsigned int i = 0; i < mnpoints - 1; i++ )
977  p.drawSegment( mpoints[i], mpoints[i+1] );
978 }
979 
980 bool OpenPolygonalImp::contains( const Coordinate& p, int width,
981  const KigWidget& w ) const
982 {
983  return isOnOPolygonBorder( p, w.screenInfo().normalMiss( width ), w.document() );
984 }
985 
986 /*
987  *
988  */
989 
990 std::vector<Coordinate> computeConvexHull( const std::vector<Coordinate>& points )
991 {
992  /*
993  * compute the convex hull of the set of points, the resulting list
994  * is the vertices of the resulting polygon listed in a counter clockwise
995  * order. This algorithm is on order n^2, probably suboptimal, but
996  * we don't expect to have large values for n.
997  */
998 
999  if ( points.size() < 3 ) return points;
1000  std::vector<Coordinate> worklist = points;
1001  std::vector<Coordinate> result;
1002 
1003  double ymin = worklist[0].y;
1004  uint imin = 0;
1005  for ( uint i = 1; i < worklist.size(); ++i )
1006  {
1007  if ( worklist[i].y < ymin )
1008  {
1009  ymin = worklist[i].y;
1010  imin = i;
1011  }
1012  }
1013 
1014  // worklist[imin] is definitely on the convex hull, let's start from there
1015  result.push_back( worklist[imin] );
1016  Coordinate startpoint = worklist[imin];
1017  Coordinate apoint = worklist[imin];
1018  double aangle = 0.0;
1019 
1020  while ( ! worklist.empty() )
1021  {
1022  int besti = -1;
1023  double anglemin = 10000.0;
1024  for ( uint i = 0; i < worklist.size(); ++i )
1025  {
1026  if ( worklist[i] == apoint ) continue;
1027  Coordinate v = worklist[i] - apoint;
1028  double angle = std::atan2( v.y, v.x );
1029  while ( angle < aangle ) angle += 2*M_PI;
1030  if ( angle < anglemin )
1031  { // found a better point
1032  besti = i;
1033  anglemin = angle;
1034  }
1035  }
1036 
1037  if ( besti < 0 ) return result; // this happens, e.g. if all points coincide
1038  apoint = worklist[besti];
1039  aangle = anglemin;
1040  if ( apoint == startpoint )
1041  {
1042  return result;
1043  }
1044  result.push_back( apoint );
1045  worklist.erase( worklist.begin() + besti, worklist.begin() + besti + 1 );
1046  }
1047  assert( false );
1048  return result;
1049 }
ClosedPolygonalImp
An ObjectImp representing a closed polygonal.
Definition: polygon_imp.h:130
BezierImp
An ObjectImp representing polynomial Bézier Curve.
Definition: bezier_imp.h:31
AbstractPolygonImp::npoints
uint npoints() const
Returns the number of points of this polygon.
Definition: polygon_imp.cc:576
AbstractPolygonImp::ptransform
std::vector< Coordinate > ptransform(const Transformation &) const
Definition: polygon_imp.cc:77
ObjectImpType
Instances of this class represent a certain ObjectImp type.
Definition: object_imp.h:95
ObjectImp::inherits
bool inherits(const ObjectImpType *t) const
Returns true if this ObjectImp inherits the ObjectImp type represented by t.
Definition: object_imp.cc:279
FilledPolygonImp::draw
void draw(KigPainter &p) const
Definition: polygon_imp.cc:940
point_imp.h
FilledPolygonImp::iconForProperty
const char * iconForProperty(int which) const
Definition: polygon_imp.cc:380
FilledPolygonImp::FilledPolygonImp
FilledPolygonImp(const std::vector< Coordinate > &points)
Definition: polygon_imp.cc:935
FilledPolygonImp::isPropertyDefinedOnOrThroughThisImp
bool isPropertyDefinedOnOrThroughThisImp(int which) const
Definition: polygon_imp.cc:777
ScreenInfo::normalMiss
double normalMiss(int width) const
Definition: screeninfo.cc:88
AbstractPolygonImp::numberOfProperties
int numberOfProperties() const
Definition: polygon_imp.cc:233
OpenPolygonalImp
An ObjectImp representing an open polygonal.
Definition: polygon_imp.h:157
FilledPolygonImp::impRequirementForProperty
const ObjectImpType * impRequirementForProperty(int which) const
Definition: polygon_imp.cc:350
FilledPolygonImp::visit
void visit(ObjectImpVisitor *vtor) const
Definition: polygon_imp.cc:630
polygon_imp.h
ClosedPolygonalImp::type
const ObjectImpType * type() const
Returns the lowermost ObjectImpType that this object is an instantiation of.
Definition: polygon_imp.cc:759
FilledPolygonImp::copy
FilledPolygonImp * copy() const
Returns a copy of this ObjectImp.
Definition: polygon_imp.cc:615
ObjectImpVisitor::visit
void visit(const ObjectImp *imp)
Definition: object_imp.cc:81
OpenPolygonalImp::impRequirementForProperty
const ObjectImpType * impRequirementForProperty(int which) const
Definition: polygon_imp.cc:364
FilledPolygonImp::contains
bool contains(const Coordinate &p, int width, const KigWidget &) const
Definition: polygon_imp.cc:945
ObjectImp::impRequirementForProperty
virtual const ObjectImpType * impRequirementForProperty(int which) const
Definition: object_imp.cc:76
ClosedPolygonalImp::iconForProperty
const char * iconForProperty(int which) const
Definition: polygon_imp.cc:403
ObjectImp::property
virtual ObjectImp * property(int which, const KigDocument &d) const
Definition: object_imp.cc:70
Rect
This file is part of Kig, a KDE program for Interactive Geometry...
Definition: rect.h:34
FilledPolygonImp::type
const ObjectImpType * type() const
Returns the lowermost ObjectImpType that this object is an instantiation of.
Definition: polygon_imp.cc:750
AbstractPolygonImp::isInPolygon
bool isInPolygon(const Coordinate &p) const
Definition: polygon_imp.cc:137
Transformation::getProjectiveIndicator
double getProjectiveIndicator(const Coordinate &c) const
Definition: kigtransform.cpp:703
AbstractPolygonImp::iconForProperty
const char * iconForProperty(int which) const
Definition: polygon_imp.cc:371
ClosedPolygonalImp::stype
static const ObjectImpType * stype()
Definition: polygon_imp.cc:678
OpenPolygonalImp::type
const ObjectImpType * type() const
Returns the lowermost ObjectImpType that this object is an instantiation of.
Definition: polygon_imp.cc:764
ObjectImp::propertiesInternalNames
virtual const QByteArrayList propertiesInternalNames() const
Definition: object_imp.cc:63
ObjectImp::stype
static const ObjectImpType * stype()
The ObjectImpType representing the base ObjectImp class.
Definition: object_imp.cc:284
Transformation::isAffine
bool isAffine() const
Definition: kigtransform.cpp:686
AbstractPolygonImp::points
const std::vector< Coordinate > points() const
Returns the vector with polygon points.
Definition: polygon_imp.cc:571
AbstractPolygonImp::attachPoint
Coordinate attachPoint() const
Returns a reference point where to attach labels; when this returns an invalidCoord then the attachme...
Definition: polygon_imp.cc:72
AbstractPolygonImp::isMonotoneSteering
bool isMonotoneSteering() const
Definition: polygon_imp.cc:893
IntImp
This ObjectImp is a BogusImp containing only an int value.
Definition: bogus_imp.h:128
KigPainter::drawPolygon
void drawPolygon(const std::vector< QPoint > &pts, Qt::FillRule fillRule=Qt::OddEvenFill)
draw a polygon defined by the points in pts...
Definition: kigpainter.cpp:303
FilledPolygonImp::property
ObjectImp * property(int which, const KigDocument &w) const
Definition: polygon_imp.cc:454
AbstractPolygonImp::mcenterofmass
Coordinate mcenterofmass
Definition: polygon_imp.h:36
OpenPolygonalImp::visit
void visit(ObjectImpVisitor *vtor) const
Definition: polygon_imp.cc:640
Coordinate
The Coordinate class is the basic class representing a 2D location by its x and y components...
Definition: coordinate.h:33
AbstractPolygonImp::equals
bool equals(const ObjectImp &rhs) const
Returns true if this ObjectImp is equal to rhs.
Definition: polygon_imp.cc:645
ClosedPolygonalImp::propertiesInternalNames
const QByteArrayList propertiesInternalNames() const
Definition: polygon_imp.cc:272
FilledPolygonImp::properties
const QByteArrayList properties() const
Definition: polygon_imp.cc:303
AbstractPolygonImp::AbstractPolygonImp
AbstractPolygonImp(const std::vector< Coordinate > &points)
Definition: polygon_imp.cc:54
FilledPolygonImp::transform
ObjectImp * transform(const Transformation &) const
Return this ObjectImp, transformed by the transformation t.
Definition: polygon_imp.cc:116
OpenPolygonalImp::stype
static const ObjectImpType * stype()
Definition: polygon_imp.cc:696
ClosedPolygonalImp::impRequirementForProperty
const ObjectImpType * impRequirementForProperty(int which) const
Definition: polygon_imp.cc:357
KigWidget::screenInfo
const ScreenInfo & screenInfo() const
the part of the document we're currently showing i.e.
Definition: kig_view.cpp:272
ClosedPolygonalImp::draw
void draw(KigPainter &p) const
Definition: polygon_imp.cc:956
FilledPolygonImp::stype4
static const ObjectImpType * stype4()
Definition: polygon_imp.cc:732
isOnSegment
bool isOnSegment(const Coordinate &o, const Coordinate &a, const Coordinate &b, const double fault)
is o on the segment defined by point a and point b ? this calls isOnLine(), but also checks if o is "...
Definition: common.cpp:212
FilledPolygonImp::numberOfProperties
int numberOfProperties() const
Definition: polygon_imp.cc:238
OpenPolygonalImp::transform
ObjectImp * transform(const Transformation &) const
Return this ObjectImp, transformed by the transformation t.
Definition: polygon_imp.cc:130
AbstractPolygonImp::isConvex
bool isConvex() const
Definition: polygon_imp.cc:922
ObjectImp::iconForProperty
virtual const char * iconForProperty(int which) const
Definition: object_imp.cc:187
AbstractPolygonImp::~AbstractPolygonImp
~AbstractPolygonImp()
Definition: polygon_imp.cc:68
KigPainter
KigPainter is an extended QPainter.
Definition: kigpainter.h:51
AbstractPolygonImp::mpoints
std::vector< Coordinate > mpoints
Definition: polygon_imp.h:33
AbstractPolygonImp::windingNumber
int windingNumber() const
Definition: polygon_imp.cc:811
bogus_imp.h
PointImp
An ObjectImp representing a point.
Definition: point_imp.h:27
AbstractPolygonImp::stype
static const ObjectImpType * stype()
Returns the ObjectImpType representing the PolygonImp type.
Definition: polygon_imp.cc:651
OpenPolygonalImp::draw
void draw(KigPainter &p) const
Definition: polygon_imp.cc:974
AbstractPolygonImp::inRect
bool inRect(const Rect &r, int width, const KigWidget &) const
Definition: polygon_imp.cc:210
ClosedPolygonalImp::copy
ClosedPolygonalImp * copy() const
Returns a copy of this ObjectImp.
Definition: polygon_imp.cc:620
Transformation
Class representing a transformation.
Definition: kigtransform.h:37
OpenPolygonalImp::OpenPolygonalImp
OpenPolygonalImp(const std::vector< Coordinate > &points)
Definition: polygon_imp.cc:969
ClosedPolygonalImp::isPropertyDefinedOnOrThroughThisImp
bool isPropertyDefinedOnOrThroughThisImp(int which) const
Definition: polygon_imp.cc:785
AbstractPolygonImp::properties
const QByteArrayList properties() const
Definition: polygon_imp.cc:298
KigWidget
This class is the real widget showing the document.
Definition: kig_view.h:50
FilledPolygonImp::stype
static const ObjectImpType * stype()
Definition: polygon_imp.cc:660
KigWidget::document
const KigDocument & document() const
Definition: kig_view.cpp:460
ObjectImp::isPropertyDefinedOnOrThroughThisImp
virtual bool isPropertyDefinedOnOrThroughThisImp(int which) const
Definition: object_imp.cc:326
ClosedPolygonalImp::property
ObjectImp * property(int which, const KigDocument &w) const
Definition: polygon_imp.cc:497
Rect::setContains
void setContains(Coordinate p)
this makes sure p is in the rect, extending it if necessary...
Definition: rect.cc:240
OpenPolygonalImp::property
ObjectImp * property(int which, const KigDocument &w) const
Definition: polygon_imp.cc:540
AbstractPolygonImp::operimeter
double operimeter() const
Returns the perimeter of this polygon.
Definition: polygon_imp.cc:581
AbstractPolygonImp::mnpoints
uint mnpoints
Definition: polygon_imp.h:32
AbstractPolygonImp::isPropertyDefinedOnOrThroughThisImp
bool isPropertyDefinedOnOrThroughThisImp(int which) const
Definition: polygon_imp.cc:769
lineInRect
bool lineInRect(const Rect &r, const Coordinate &a, const Coordinate &b, const int width, const ObjectImp *imp, const KigWidget &w)
Is the line, segment, ray or vector inside r ? We need the imp to distinguish between rays...
Definition: common.cpp:401
computeConvexHull
std::vector< Coordinate > computeConvexHull(const std::vector< Coordinate > &points)
Definition: polygon_imp.cc:990
Transformation::apply
const Coordinate apply(const double x0, const double x1, const double x2) const
Apply this Tranformation.
Definition: kigtransform.cpp:611
OpenPolygonalImp::propertiesInternalNames
const QByteArrayList propertiesInternalNames() const
Definition: polygon_imp.cc:286
FilledPolygonImp::propertiesInternalNames
const QByteArrayList propertiesInternalNames() const
Definition: polygon_imp.cc:258
AbstractPolygonImp::property
ObjectImp * property(int which, const KigDocument &w) const
Definition: polygon_imp.cc:445
line_imp.h
ClosedPolygonalImp::contains
bool contains(const Coordinate &p, int width, const KigWidget &) const
Definition: polygon_imp.cc:963
ClosedPolygonalImp::ClosedPolygonalImp
ClosedPolygonalImp(const std::vector< Coordinate > &points)
Definition: polygon_imp.cc:951
AbstractPolygonImp::isTwisted
bool isTwisted() const
Definition: polygon_imp.cc:845
AbstractPolygonImp::valid
bool valid() const
Definition: polygon_imp.cc:228
DoubleImp
This ObjectImp is a BogusImp containing only a double value.
Definition: bogus_imp.h:89
KigDocument
KigDocument is the class holding the real data in a Kig document.
Definition: kig_document.h:36
ClosedPolygonalImp::transform
ObjectImp * transform(const Transformation &) const
Return this ObjectImp, transformed by the transformation t.
Definition: polygon_imp.cc:123
OpenPolygonalImp::isPropertyDefinedOnOrThroughThisImp
bool isPropertyDefinedOnOrThroughThisImp(int which) const
Definition: polygon_imp.cc:793
AbstractPolygonImp::isOnCPolygonBorder
bool isOnCPolygonBorder(const Coordinate &p, double dist, const KigDocument &doc) const
Definition: polygon_imp.cc:188
AbstractPolygonImp::propertiesInternalNames
const QByteArrayList propertiesInternalNames() const
Definition: polygon_imp.cc:253
OpenPolygonalImp::copy
OpenPolygonalImp * copy() const
Returns a copy of this ObjectImp.
Definition: polygon_imp.cc:625
Coordinate::x
double x
X Component.
Definition: coordinate.h:126
QByteArrayList
QList< QByteArray > QByteArrayList
Definition: objects/common.h:50
AbstractPolygonImp::surroundingRect
Rect surroundingRect() const
Definition: polygon_imp.cc:801
Coordinate::y
double y
Y Component.
Definition: coordinate.h:129
ObjectImp
The ObjectImp class represents the behaviour of an object after it is calculated. ...
Definition: object_imp.h:226
ClosedPolygonalImp::properties
const QByteArrayList properties() const
Definition: polygon_imp.cc:317
OpenPolygonalImp::properties
const QByteArrayList properties() const
Definition: polygon_imp.cc:331
AbstractPolygonImp
An ObjectImp representing a polygon.
Definition: polygon_imp.h:28
FilledPolygonImp
An ObjectImp representing a filled polygon.
Definition: polygon_imp.h:101
OpenPolygonalImp::contains
bool contains(const Coordinate &p, int width, const KigWidget &) const
Definition: polygon_imp.cc:980
ClosedPolygonalImp::visit
void visit(ObjectImpVisitor *vtor) const
Definition: polygon_imp.cc:635
OpenPolygonalImp::numberOfProperties
int numberOfProperties() const
Definition: polygon_imp.cc:248
FilledPolygonImp::stype3
static const ObjectImpType * stype3()
Definition: polygon_imp.cc:714
AbstractPolygonImp::cperimeter
double cperimeter() const
Definition: polygon_imp.cc:591
OpenPolygonalImp::iconForProperty
const char * iconForProperty(int which) const
Definition: polygon_imp.cc:426
ClosedPolygonalImp::numberOfProperties
int numberOfProperties() const
Definition: polygon_imp.cc:243
KigPainter::drawSegment
void drawSegment(const Coordinate &from, const Coordinate &to)
draw a segment...
Definition: kigpainter.cpp:94
AbstractPolygonImp::impRequirementForProperty
const ObjectImpType * impRequirementForProperty(int which) const
Definition: polygon_imp.cc:343
ObjectImp::numberOfProperties
virtual int numberOfProperties() const
Definition: object_imp.cc:58
uint
unsigned int uint
Definition: object_imp.h:87
Coordinate::valid
bool valid() const
Return whether this is a valid Coordinate.
Definition: coordinate.cpp:176
ObjectImpVisitor
Definition: object_imp.h:56
ObjectImp::properties
virtual const QByteArrayList properties() const
Definition: object_imp.cc:51
InvalidImp
This ObjectImp represents an invalid object.
Definition: bogus_imp.h:61
bezier_imp.h
AbstractPolygonImp::isOnOPolygonBorder
bool isOnOPolygonBorder(const Coordinate &p, double dist, const KigDocument &doc) const
Definition: polygon_imp.cc:198
AbstractPolygonImp::area
double area() const
Returns the area of this polygon.
Definition: polygon_imp.cc:602
SegmentImp
An ObjectImp representing a segment.
Definition: line_imp.h:81
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:35:39 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kig

Skip menu "kig"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdeedu API Reference

Skip menu "kdeedu API Reference"
  • Analitza
  •     lib
  • kalgebra
  • kalzium
  •   libscience
  • kanagram
  • kig
  •   lib
  • klettres
  • kstars
  • libkdeedu
  •   keduvocdocument
  • marble
  • parley
  • rocs
  •   App
  •   RocsCore
  •   VisualEditor
  •   stepcore

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal