• 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
  • misc
coordinate_system.cpp
Go to the documentation of this file.
1 
21 #include "coordinate_system.h"
22 
23 #include "../kig/kig_document.h"
24 #include "../kig/kig_view.h"
25 
26 #include "common.h"
27 #include "coordinate.h"
28 #include "goniometry.h"
29 #include "kigpainter.h"
30 
31 #include <qpainter.h>
32 #include <qregexp.h>
33 
34 #include <kdebug.h>
35 #include <kglobal.h>
36 #include <klocale.h>
37 #include <knumvalidator.h>
38 
39 #include <string>
40 #include <math.h>
41 
42 static QString withoutSpaces( const QString& str )
43 {
44  QString newstr;
45  int s = str.size();
46  for ( int i = 0; i < s; ++i )
47  if ( !str.at( i ).isSpace() )
48  newstr.append( str.at( i ) );
49  return newstr;
50 }
51 
52 
53 class CoordinateValidator
54  : public QValidator
55 {
56  bool mpolar;
57  KDoubleValidator mdv;
58  mutable QRegExp mre;
59 public:
60  static const char reEuclidean[];
61  static const char rePolar[];
62 
63  CoordinateValidator( bool polar );
64  ~CoordinateValidator();
65  State validate ( QString & input, int & pos ) const;
66  void fixup ( QString & input ) const;
67 };
68 
69 const char CoordinateValidator::reEuclidean[] = "\\s*\\(?\\s*([0-9.,+-]+)\\s*;\\s*([0-9.,+-]+)\\s*\\)?\\s*";
70 const char CoordinateValidator::rePolar[] = "\\s*\\(?\\s*([0-9.,+-]+)\\s*;\\s*([0-9.,+-]+) ?°?\\s*\\)?\\s*";
71 
72 CoordinateValidator::CoordinateValidator( bool polar )
73  : QValidator( 0L ), mpolar( polar ), mdv( 0L ),
74  mre( QString::fromUtf8( polar ? rePolar : reEuclidean ) )
75 {
76 }
77 
78 CoordinateValidator::~CoordinateValidator()
79 {
80 }
81 
82 QValidator::State CoordinateValidator::validate( QString & input, int & pos ) const
83 {
84  QString tinput = withoutSpaces( input );
85  if ( tinput.isEmpty() )
86  return Invalid;
87  if ( tinput.at( tinput.length() - 1 ) == ')' ) tinput.truncate( tinput.length() - 1 );
88  if ( mpolar )
89  {
90  // strip the eventual '°'
91  if ( !tinput.isEmpty() && tinput.at( tinput.length() - 1 ).unicode() == 176 )
92  tinput.truncate( tinput.length() - 1 );
93  };
94  if ( tinput[0] == '(' ) tinput = tinput.mid( 1 );
95  int scp = tinput.indexOf( ';' );
96  if ( scp == -1 ) return mdv.validate( tinput, pos ) == Invalid ? Invalid : Intermediate;
97  else
98  {
99  QString p1 = tinput.left( scp );
100  QString p2 = tinput.mid( scp + 1 );
101 
102  State ret = Acceptable;
103 
104  int boguspos = 0;
105  ret = kigMin( ret, mdv.validate( p1, boguspos ) );
106 
107  boguspos = 0;
108  ret = kigMin( ret, mdv.validate( p2, boguspos ) );
109 
110  return ret;
111  };
112 }
113 
114 void CoordinateValidator::fixup( QString & input ) const
115 {
116  int nsc = input.count( ';' );
117  if ( nsc > 1 )
118  {
119  // where is the second ';'
120  int i = input.indexOf( ';' );
121  i = input.indexOf( ';', i );
122  input = input.left( i );
123  };
124  // now the string has at most one semicolon left..
125  int sc = input.indexOf( ';' );
126  if ( sc == -1 )
127  {
128  sc = input.length();
129  KLocale* l = KGlobal::locale();
130  if ( mpolar )
131  input.append( QString::fromLatin1( ";" ) + l->positiveSign() +
132  QString::fromLatin1( "0" ) );
133  else
134  input.append( QString::fromLatin1( ";" ) + l->positiveSign() +
135  QString::fromLatin1( "0" ) + l->decimalSymbol() +
136  QString::fromLatin1( "0" ) );
137  };
138  mre.exactMatch( input );
139  QString ds1 = mre.cap( 1 );
140  mdv.fixup( ds1 );
141  QString ds2 = mre.cap( 2 );
142  mdv.fixup( ds2 );
143  input = ds1 + QString::fromLatin1( "; " ) + ds2;
144 }
145 
146 EuclideanCoords::EuclideanCoords()
147 {
148 }
149 
150 QString EuclideanCoords::fromScreen( const Coordinate& p, const KigDocument& d ) const
151 {
152  // i used to use the widget size here, but that's no good idea,
153  // since an object isn't asked to recalc every time the widget size
154  // changes.. might be a good idea to do that, but well, maybe some
155  // other time :)
156  int l = d.getCoordinatePrecision();
157  QString xs = KGlobal::locale()->formatNumber( p.x, l );
158  QString ys = KGlobal::locale()->formatNumber( p.y, l );
159  return QString::fromLatin1( "( %1; %2 )" ).arg( xs ).arg( ys );
160 }
161 
162 Coordinate EuclideanCoords::toScreen(const QString& s, bool& ok) const
163 {
164  QRegExp r( QString::fromUtf8( CoordinateValidator::reEuclidean ) );
165  ok = ( r.indexIn(s) == 0 );
166  if (ok)
167  {
168  QString xs = r.cap(1);
169  QString ys = r.cap(2);
170  KLocale* l = KGlobal::locale();
171  double x = l->readNumber( xs, &ok );
172  if ( ! ok ) x = xs.toDouble( &ok );
173  if ( ! ok ) return Coordinate();
174  double y = l->readNumber( ys, &ok );
175  if ( ! ok ) y = ys.toDouble( &ok );
176  if ( ! ok ) return Coordinate();
177  return Coordinate( x, y );
178  }
179  return Coordinate();
180 }
181 
189 static double nicenum( double x, bool round )
190 {
191  int exp = (int) log10( x );
192  double f = x/pow( 10., exp );
193  double nf;
194  if ( round )
195  {
196  if ( f < 1.5 ) nf = 1.;
197  else if ( f < 3. ) nf = 2.;
198  else if ( f < 7. ) nf = 5.;
199  else nf = 10.;
200  }
201  else
202  {
203  if ( f <= 1. ) nf = 1.;
204  else if ( f <= 2. ) nf = 2.;
205  else if ( f <= 5. ) nf = 5.;
206  else nf = 10.;
207  };
208  return nf * pow( 10., exp );
209 }
210 
211 void EuclideanCoords::drawGrid( KigPainter& p, bool showgrid, bool showaxes ) const
212 {
213  p.setWholeWinOverlay();
214 
215  // this instruction in not necessary, but there is a little
216  // optimization when there are no grid and no axes.
217  if ( !( showgrid || showaxes ) )
218  return;
219 
220  // this function is inspired upon ( public domain ) code from the
221  // first Graphics Gems book. Credits to Paul S. Heckbert, who wrote
222  // the "Nice number for graph labels" gem.
223 
224  const double hmax = ceil( p.window().right() );
225  const double hmin = floor( p.window().left() );
226  const double vmax = ceil( p.window().top() );
227  const double vmin = floor( p.window().bottom() );
228 
229  // the number of intervals we would like to have:
230  // we try to have one of them per 40 pixels or so..
231  const int ntick = static_cast<int>(
232  kigMax( hmax - hmin, vmax - vmin ) / p.pixelWidth() / 40. ) + 1;
233 
234  double hrange = nicenum( hmax - hmin, false );
235  double vrange = nicenum( vmax - vmin, false );
236  const double newrange = kigMin( hrange, vrange );
237  hrange = newrange;
238  vrange = newrange;
239 
240  const double hd = nicenum( hrange / ( ntick - 1 ), true );
241  const double vd = nicenum( vrange / ( ntick - 1 ), true );
242 
243  const double hgraphmin = ceil( hmin / hd) * hd;
244  const double hgraphmax = floor( hmax / hd ) * hd;
245  const double vgraphmin = ceil( vmin / vd ) * vd;
246  const double vgraphmax = floor( vmax / vd ) * vd;
247 
248  const int hnfrac = kigMax( (int) - floor( log10( hd ) ), 0 );
249  const int vnfrac = kigMax( (int) - floor( log10( vd ) ), 0 );
250 
251  /****** the grid lines ******/
252  if ( showgrid )
253  {
254  p.setPen( QPen( Qt::lightGray, 0, Qt::DotLine ) );
255  // vertical lines...
256  for ( double i = hgraphmin; i <= hgraphmax + hd/2; i += hd )
257  p.drawSegment( Coordinate( i, vgraphmin ),
258  Coordinate( i, vgraphmax ) );
259  // horizontal lines...
260  for ( double i = vgraphmin; i <= vgraphmax + vd/2; i += vd )
261  p.drawSegment( Coordinate( hgraphmin, i ),
262  Coordinate( hgraphmax, i ) );
263  }
264 
265  /****** the axes ******/
266  if ( showaxes )
267  {
268  p.setPen( QPen( Qt::gray, 1, Qt::SolidLine ) );
269  // x axis
270  p.drawSegment( Coordinate( hmin, 0 ), Coordinate( hmax, 0 ) );
271  // y axis
272  p.drawSegment( Coordinate( 0, vmin ), Coordinate( 0, vmax ) );
273 
274  /****** the numbers ******/
275 
276  // x axis
277  for( double i = hgraphmin; i <= hgraphmax + hd / 2; i += hd )
278  {
279  // we skip 0 since that would look stupid... (the axes going
280  // through the 0 etc. )
281  if( fabs( i ) < 1e-8 ) continue;
282 
283  p.drawText(
284  Rect( Coordinate( i, 0 ), hd, -2*vd ).normalized(),
285  KGlobal::locale()->formatNumber( i, hnfrac ),
286  Qt::AlignLeft | Qt::AlignTop
287  );
288  };
289  // y axis...
290  for ( double i = vgraphmin; i <= vgraphmax + vd/2; i += vd )
291  {
292  if( fabs( i ) < 1e-8 ) continue;
293  p.drawText ( Rect( Coordinate( 0, i ), 2*hd, vd ).normalized(),
294  KGlobal::locale()->formatNumber( i, vnfrac ),
295  Qt::AlignBottom | Qt::AlignLeft
296  );
297  };
298  // arrows on the ends of the axes...
299  p.setPen( QPen( Qt::gray, 1, Qt::SolidLine ) );
300  p.setBrush( QBrush( Qt::gray ) );
301  std::vector<Coordinate> a;
302 
303  // the arrow on the right end of the X axis...
304  a.reserve( 3 );
305  double u = p.pixelWidth();
306  a.push_back( Coordinate( hmax - 6 * u, -3 * u) );
307  a.push_back( Coordinate( hmax, 0 ) );
308  a.push_back( Coordinate( hmax - 6 * u, 3 * u ) );
309  p.drawArea( a );
310 // p.drawPolygon( a, true );
311 
312  // the arrow on the top end of the Y axis...
313  a.clear();
314  a.reserve( 3 );
315  a.push_back( Coordinate( 3 * u, vmax - 6 * u ) );
316  a.push_back( Coordinate( 0, vmax ) );
317  a.push_back( Coordinate( -3 * u, vmax - 6 * u ) );
318  p.drawArea( a );
319 // p.drawPolygon( a, true );
320  }; // if( showaxes )
321 }
322 
323 QString EuclideanCoords::coordinateFormatNotice() const
324 {
325  return i18n( "Enter coordinates in the following format: \"x;y\",\n"
326  "where x is the x coordinate, and y is the y coordinate." );
327 }
328 
329 QString EuclideanCoords::coordinateFormatNoticeMarkup() const
330 {
331  return i18n( "Enter coordinates in the following format: <b>\"x;y\"</b>,<br />"
332  "where x is the x coordinate, and y is the y coordinate." );
333 }
334 
335 EuclideanCoords::~EuclideanCoords()
336 {
337 }
338 
339 CoordinateSystem::~CoordinateSystem()
340 {
341 }
342 
343 CoordinateSystem::CoordinateSystem()
344 {
345 }
346 
347 PolarCoords::PolarCoords()
348 {
349 }
350 
351 PolarCoords::~PolarCoords()
352 {
353 }
354 
355 QString PolarCoords::fromScreen( const Coordinate& pt, const KigDocument& d ) const
356 {
357  int l = d.getCoordinatePrecision();
358 
359  double r = pt.length();
360  double theta = Goniometry::convert( atan2( pt.y, pt.x ), Goniometry::Rad, Goniometry::Deg );
361 
362  QString rs = KGlobal::locale()->formatNumber( r, l );
363  QString ts = KGlobal::locale()->formatNumber( theta, 0 );
364 
365  return QString::fromLatin1("( %1; %2 )").arg( rs ).arg( ts );
366 }
367 
368 QString PolarCoords::coordinateFormatNotice() const
369 {
370  // \xCE\xB8 is utf8 for the greek theta sign..
371  return i18n( "Enter coordinates in the following format: \"r; \xCE\xB8°\",\n"
372  "where r and \xCE\xB8 are the polar coordinates." );
373 }
374 
375 QString PolarCoords::coordinateFormatNoticeMarkup() const
376 {
377  // \xCE\xB8 is utf8 for the greek theta sign..
378  return i18n( "Enter coordinates in the following format: <b>\"r; \xCE\xB8°\"</b>,<br />"
379  "where r and \xCE\xB8 are the polar coordinates." );
380 }
381 
382 Coordinate PolarCoords::toScreen(const QString& s, bool& ok) const
383 {
384  QRegExp regexp( QString::fromUtf8( CoordinateValidator::rePolar ) );
385  ok = ( regexp.indexIn( s ) == 0 );
386  if (ok)
387  {
388  QString rs = regexp.cap( 1 );
389  double r = KGlobal::locale()->readNumber( rs, &ok );
390  if ( ! ok ) r = rs.toDouble( &ok );
391  if ( ! ok ) return Coordinate();
392  QString ts = regexp.cap( 2 );
393  double theta = KGlobal::locale()->readNumber( ts, &ok );
394  if ( ! ok ) theta = ts.toDouble( &ok );
395  if ( ! ok ) return Coordinate();
396  theta *= M_PI;
397  theta /= 180;
398  return Coordinate( cos( theta ) * r, sin( theta ) * r );
399  }
400  else return Coordinate();
401 }
402 
403 void PolarCoords::drawGrid( KigPainter& p, bool showgrid, bool showaxes ) const
404 {
405  p.setWholeWinOverlay();
406 
407  // this instruction in not necessary, but there is a little
408  // optimization when there are no grid and no axes.
409  if ( !( showgrid || showaxes ) )
410  return;
411 
412  // we multiply by sqrt( 2 ) cause we don't want to miss circles in
413  // the corners, that intersect with the axes outside of the
414  // screen..
415 
416  const double hmax = M_SQRT2*p.window().right();
417  const double hmin = M_SQRT2*p.window().left();
418  const double vmax = M_SQRT2*p.window().top();
419  const double vmin = M_SQRT2*p.window().bottom();
420 
421  // the intervals:
422  // we try to have one of them per 40 pixels or so..
423  const int ntick = static_cast<int>(
424  kigMax( hmax - hmin, vmax - vmin ) / p.pixelWidth() / 40 ) + 1;
425 
426  const double hrange = nicenum( hmax - hmin, false );
427  const double vrange = nicenum( vmax - vmin, false );
428 
429  const double hd = nicenum( hrange / ( ntick - 1 ), true );
430  const double vd = nicenum( vrange / ( ntick - 1 ), true );
431 
432  const double hgraphmin = floor( hmin / hd) * hd;
433  const double hgraphmax = ceil( hmax / hd ) * hd;
434  const double vgraphmin = floor( vmin / vd ) * vd;
435  const double vgraphmax = ceil( vmax / vd ) * vd;
436 
437  const int hnfrac = kigMax( (int) - floor( log10( hd ) ), 0 );
438  const int vnfrac = kigMax( (int) - floor( log10( vd ) ), 0 );
439  const int nfrac = kigMax( hnfrac, vnfrac );
440 
441  /****** the grid lines ******/
442  if ( showgrid )
443  {
444  double d = kigMin( hd, vd );
445  double begin = kigMin( kigAbs( hgraphmin ), kigAbs( vgraphmin ) );
446  if ( kigSgn( hgraphmin ) != kigSgn( hgraphmax ) && kigSgn( vgraphmin ) != kigSgn( vgraphmax ) )
447  begin = d;
448  double end = kigMax( hgraphmax, vgraphmax );
449 
450  // we also want the circles that don't fit entirely in the
451  // screen..
452  Coordinate c( 0, 0 );
453  p.setPen( QPen( Qt::lightGray, 0, Qt::DotLine ) );
454  for ( double i = begin; i <= end + d / 2; i += d )
455  drawGridLine( p, c, fabs( i ) );
456  }
457 
458  /****** the axes ******/
459  if ( showaxes )
460  {
461  p.setPen( QPen( Qt::gray, 1, Qt::SolidLine ) );
462  // x axis
463  p.drawSegment( Coordinate( hmin, 0 ), Coordinate( hmax, 0 ) );
464  // y axis
465  p.drawSegment( Coordinate( 0, vmin ), Coordinate( 0, vmax ) );
466 
467  /****** the numbers ******/
468 
469  // x axis
470  for( double i = hgraphmin; i <= hgraphmax + hd / 2; i += hd )
471  {
472  // we skip 0 since that would look stupid... (the axes going
473  // through the 0 etc. )
474  if( fabs( i ) < 1e-8 ) continue;
475 
476  QString is = KGlobal::locale()->formatNumber( fabs( i ), nfrac );
477  p.drawText(
478  Rect( Coordinate( i, 0 ), hd, -2*vd ).normalized(),
479  is, Qt::AlignLeft | Qt::AlignTop );
480  };
481  // y axis...
482  for ( double i = vgraphmin; i <= vgraphmax + vd / 2; i += vd )
483  {
484  if( fabs( i ) < 1e-8 ) continue;
485 
486  QString is = KGlobal::locale()->formatNumber( fabs( i ), nfrac );
487 
488  p.drawText ( Rect( Coordinate( 0, i ), hd, vd ).normalized(),
489  is, Qt::AlignBottom | Qt::AlignLeft
490  );
491  };
492  // arrows on the ends of the axes...
493  p.setPen( QPen( Qt::gray, 1, Qt::SolidLine ) );
494  p.setBrush( QBrush( Qt::gray ) );
495  std::vector<Coordinate> a;
496 
497  // the arrow on the right end of the X axis...
498  a.reserve( 3 );
499  double u = p.pixelWidth();
500  a.push_back( Coordinate( hmax - 6 * u, -3 * u) );
501  a.push_back( Coordinate( hmax, 0 ) );
502  a.push_back( Coordinate( hmax - 6 * u, 3 * u ) );
503 // p.drawPolygon( a, true );
504  p.drawArea( a );
505 
506  // the arrow on the top end of the Y axis...
507  a.clear();
508  a.reserve( 3 );
509  a.push_back( Coordinate( 3 * u, vmax - 6 * u ) );
510  a.push_back( Coordinate( 0, vmax ) );
511  a.push_back( Coordinate( -3 * u, vmax - 6 * u ) );
512 // p.drawPolygon( a, true );
513  p.drawArea( a );
514  }; // if( showaxes )
515 }
516 
517 QValidator* EuclideanCoords::coordinateValidator() const
518 {
519  return new CoordinateValidator( false );
520 }
521 
522 QValidator* PolarCoords::coordinateValidator() const
523 {
524  return new CoordinateValidator( true );
525 }
526 
527 QStringList CoordinateSystemFactory::names()
528 {
529  QStringList ret;
530  ret << i18n( "&Euclidean" )
531  << i18n( "&Polar" );
532  return ret;
533 }
534 
535 CoordinateSystem* CoordinateSystemFactory::build( int which )
536 {
537  if ( which == Euclidean )
538  return new EuclideanCoords;
539  else if ( which == Polar )
540  return new PolarCoords;
541  else return 0;
542 }
543 
544 static const char euclideanTypeString[] = "Euclidean";
545 static const char polarTypeString[] = "Polar";
546 
547 CoordinateSystem* CoordinateSystemFactory::build( const char* type )
548 {
549  if ( std::string( euclideanTypeString ) == type )
550  return new EuclideanCoords;
551  if ( std::string( polarTypeString ) == type )
552  return new PolarCoords;
553  else return 0;
554 }
555 
556 const char* EuclideanCoords::type() const
557 {
558  return euclideanTypeString;
559 }
560 
561 const char* PolarCoords::type() const
562 {
563  return polarTypeString;
564 }
565 
566 int EuclideanCoords::id() const
567 {
568  return CoordinateSystemFactory::Euclidean;
569 }
570 
571 int PolarCoords::id() const
572 {
573  return CoordinateSystemFactory::Polar;
574 }
575 
576 QString CoordinateSystemFactory::setCoordinateSystemStatement( int id )
577 {
578  switch( id )
579  {
580  case Euclidean:
581  return i18n( "Set Euclidean Coordinate System" );
582  case Polar:
583  return i18n( "Set Polar Coordinate System" );
584  default:
585  assert( false );
586  return QString();
587  }
588 }
589 
590 Coordinate EuclideanCoords::snapToGrid( const Coordinate& c,
591  const KigWidget& w ) const
592 {
593  Rect rect = w.showingRect();
594  // we recalc the interval stuff since there is no way to cache it..
595 
596  // this function is again inspired upon ( public domain ) code from
597  // the first Graphics Gems book. Credits to Paul S. Heckbert, who
598  // wrote the "Nice number for graph labels" gem.
599 
600  const double hmax = rect.right();
601  const double hmin = rect.left();
602  const double vmax = rect.top();
603  const double vmin = rect.bottom();
604 
605  // the number of intervals we would like to have:
606  // we try to have one of them per 40 pixels or so..
607  const int ntick = static_cast<int>(
608  kigMax( hmax - hmin, vmax - vmin ) / w.pixelWidth() / 40. ) + 1;
609 
610  const double hrange = nicenum( hmax - hmin, false );
611  const double vrange = nicenum( vmax - vmin, false );
612 
613  const double hd = nicenum( hrange / ( ntick - 1 ), true );
614  const double vd = nicenum( vrange / ( ntick - 1 ), true );
615 
616  const double hgraphmin = ceil( hmin / hd) * hd;
617  const double vgraphmin = ceil( vmin / vd ) * vd;
618 
619  const double nx = qRound( ( c.x - hgraphmin ) / hd ) * hd + hgraphmin;
620  const double ny = qRound( ( c.y - vgraphmin ) / vd ) * vd + vgraphmin;
621  return Coordinate( nx, ny );
622 }
623 
624 Coordinate PolarCoords::snapToGrid( const Coordinate& c,
625  const KigWidget& w ) const
626 {
627  // we reuse the drawGrid code to find
628 
629  // we multiply by sqrt( 2 ) cause we don't want to miss circles in
630  // the corners, that intersect with the axes outside of the
631  // screen..
632 
633  Rect r = w.showingRect();
634 
635  const double hmax = M_SQRT2 * r.right();
636  const double hmin = M_SQRT2 * r.left();
637  const double vmax = M_SQRT2 * r.top();
638  const double vmin = M_SQRT2 * r.bottom();
639 
640  // the intervals:
641  // we try to have one of them per 40 pixels or so..
642  const int ntick = static_cast<int>(
643  kigMax( hmax - hmin, vmax - vmin ) / w.pixelWidth() / 40 ) + 1;
644 
645  const double hrange = nicenum( hmax - hmin, false );
646  const double vrange = nicenum( vmax - vmin, false );
647 
648  const double hd = nicenum( hrange / ( ntick - 1 ), true );
649  const double vd = nicenum( vrange / ( ntick - 1 ), true );
650 
651  double d = kigMin( hd, vd );
652 
653  double dist = c.length();
654  double ndist = qRound( dist / d ) * d;
655  return c.normalize( ndist );
656 }
657 
658 void PolarCoords::drawGridLine( KigPainter& p, const Coordinate& c,
659  double r ) const
660 {
661 #ifdef KIG_TESSELLATE_POLAR_GRID_CIRCLE
662  Rect rect = p.window();
663 
664  struct iterdata_t
665  {
666  int xd;
667  int yd;
668  Coordinate ( Rect::*point )() const;
669  Coordinate ( Rect::*oppositepoint )() const;
670  double horizAngle;
671  double vertAngle;
672  };
673 
674  static const iterdata_t iterdata[] =
675  {
676  { +1, +1, &Rect::topRight, &Rect::bottomLeft, 0, M_PI/2 },
677  { -1, +1, &Rect::topLeft, &Rect::bottomRight, M_PI, M_PI / 2 },
678  { -1, -1, &Rect::bottomLeft, &Rect::topRight, M_PI, 3*M_PI/2 },
679  { +1, -1, &Rect::bottomRight, &Rect::topLeft, 2*M_PI, 3*M_PI/2 }
680  };
681  for ( int i = 0; i < 4; ++i )
682  {
683  int xd = iterdata[i].xd;
684  int yd = iterdata[i].yd;
685  Coordinate point = ( rect.*iterdata[i].point )();
686  Coordinate opppoint = ( rect.*iterdata[i].oppositepoint )();
687  double horizangle = iterdata[i].horizAngle;
688  double vertangle = iterdata[i].vertAngle;
689 
690  if ( ( c.x - point.x )*xd > 0 || ( c.y - point.y )*yd > 0 )
691  continue;
692  if ( ( c.x - opppoint.x )*-xd > r || ( c.y - opppoint.y )*-yd > r )
693  continue;
694 
695  int posdir = xd*yd;
696  double hd = ( point.x - c.x )*xd;
697  assert( hd >= 0 );
698  if ( hd < r )
699  {
700  double anglediff = acos( hd/r );
701  horizangle += posdir * anglediff;
702  }
703 
704  hd = ( c.x - opppoint.x )*-xd;
705  if ( hd >= 0 )
706  {
707  double anglediff = asin( hd/r );
708  vertangle -= posdir * anglediff;
709  }
710 
711  double vd = ( point.y - c.y )*yd;
712  assert( vd >= 0 );
713  if ( vd < r )
714  {
715  double anglediff = acos( vd/r );
716  vertangle -= posdir * anglediff;
717  }
718 
719  vd = ( c.y - opppoint.y ) * -xd;
720  if ( vd >= 0 )
721  {
722  double anglediff = asin( hd/r );
723  horizangle += posdir * anglediff;
724  }
725 
726  p.drawArc( c, r, kigMin( horizangle, vertangle ), kigMax( horizangle, vertangle ) );
727  }
728 #else
729  p.drawCircle( c, r );
730 #endif
731 }
PolarCoords
Definition: coordinate_system.h:111
CoordinateSystemFactory::Polar
Definition: coordinate_system.h:42
KigPainter::pixelWidth
double pixelWidth()
Definition: kigpainter.cpp:489
CoordinateSystemFactory::build
static CoordinateSystem * build(int which)
Definition: coordinate_system.cpp:535
CoordinateSystem
a CoordinateSystem is what the user sees: it is kept by KigPart to show the user a grid...
Definition: coordinate_system.h:60
EuclideanCoords::coordinateValidator
QValidator * coordinateValidator() const
Definition: coordinate_system.cpp:517
KigPainter::setWholeWinOverlay
void setWholeWinOverlay()
this is called by some drawing functions that modify the 'entire' screen, i.e.
Definition: kigpainter.cpp:494
KigPainter::drawCircle
void drawCircle(const Coordinate &center, double radius)
draw a circle...
Definition: kigpainter.cpp:84
KigPainter::drawText
void drawText(const Rect &r, const QString &s, int textFlags=0)
draw text...
Definition: kigpainter.cpp:192
EuclideanCoords::coordinateFormatNotice
QString coordinateFormatNotice() const
This returns a notice to say in which format coordinates should be entered.
Definition: coordinate_system.cpp:323
PolarCoords::snapToGrid
Coordinate snapToGrid(const Coordinate &c, const KigWidget &w) const
Definition: coordinate_system.cpp:624
Goniometry::Deg
Definition: goniometry.h:31
EuclideanCoords::coordinateFormatNoticeMarkup
QString coordinateFormatNoticeMarkup() const
Like coordinateFormatNotice(), but with HTML tags useful to have a rich text...
Definition: coordinate_system.cpp:329
EuclideanCoords::~EuclideanCoords
~EuclideanCoords()
Definition: coordinate_system.cpp:335
Rect::bottomLeft
Coordinate bottomLeft() const
Definition: rect.cc:161
Rect::left
double left() const
Definition: rect.cc:186
CoordinateSystemFactory::Euclidean
Definition: coordinate_system.h:42
Rect
This file is part of Kig, a KDE program for Interactive Geometry...
Definition: rect.h:34
PolarCoords::fromScreen
QString fromScreen(const Coordinate &pt, const KigDocument &w) const
Definition: coordinate_system.cpp:355
kigpainter.h
coordinate_system.h
KigPainter::setBrush
void setBrush(const QBrush &b)
Definition: kigpainter.cpp:252
Rect::right
double right() const
Definition: rect.cc:190
kigAbs
T kigAbs(const T &a)
Definition: misc/common.h:267
CoordinateSystemFactory::setCoordinateSystemStatement
static QString setCoordinateSystemStatement(int id)
Definition: coordinate_system.cpp:576
CoordinateSystemFactory::names
static QStringList names()
Definition: coordinate_system.cpp:527
EuclideanCoords::fromScreen
QString fromScreen(const Coordinate &pt, const KigDocument &w) const
Definition: coordinate_system.cpp:150
CoordinateSystem::~CoordinateSystem
virtual ~CoordinateSystem()
Definition: coordinate_system.cpp:339
Coordinate
The Coordinate class is the basic class representing a 2D location by its x and y components...
Definition: coordinate.h:33
KigDocument::getCoordinatePrecision
int getCoordinatePrecision() const
Definition: kig_document.cc:221
Coordinate::length
double length() const
Length.
Definition: coordinate.cpp:144
goniometry.h
Coordinate::normalize
const Coordinate normalize(double length=1) const
Normalize.
Definition: coordinate.cpp:154
EuclideanCoords
Definition: coordinate_system.h:91
KigPainter
KigPainter is an extended QPainter.
Definition: kigpainter.h:51
EuclideanCoords::id
int id() const
Definition: coordinate_system.cpp:566
EuclideanCoords::type
const char * type() const
Definition: coordinate_system.cpp:556
Rect::topLeft
Coordinate topLeft() const
Definition: rect.cc:171
kigMax
T kigMax(const T &a, const T &b)
Definition: misc/common.h:261
withoutSpaces
static QString withoutSpaces(const QString &str)
This file is part of Kig, a KDE program for Interactive Geometry...
Definition: coordinate_system.cpp:42
KigPainter::window
Rect window()
what rect are we drawing on ?
Definition: kigpainter.cpp:349
Rect::bottom
double bottom() const
Definition: rect.cc:194
KigPainter::drawArc
void drawArc(const Coordinate &center, double radius, double startangle, double angle)
draw the arc ( a part of a circle ), of the circle with center center, radius radius, with size angle, starting at the angle startAngle.
Definition: kigpainter.cpp:957
euclideanTypeString
static const char euclideanTypeString[]
Definition: coordinate_system.cpp:544
KigWidget
This class is the real widget showing the document.
Definition: kig_view.h:50
Rect::top
double top() const
Definition: rect.cc:199
PolarCoords::coordinateValidator
QValidator * coordinateValidator() const
Definition: coordinate_system.cpp:522
EuclideanCoords::snapToGrid
Coordinate snapToGrid(const Coordinate &c, const KigWidget &w) const
Definition: coordinate_system.cpp:590
Goniometry::convert
static double convert(const double angle, const Goniometry::System from, const Goniometry::System to)
The most useful method of this class: convert the specified angle from the system from to the system ...
Definition: goniometry.cc:87
PolarCoords::~PolarCoords
~PolarCoords()
Definition: coordinate_system.cpp:351
PolarCoords::PolarCoords
PolarCoords()
Definition: coordinate_system.cpp:347
PolarCoords::coordinateFormatNoticeMarkup
QString coordinateFormatNoticeMarkup() const
Like coordinateFormatNotice(), but with HTML tags useful to have a rich text...
Definition: coordinate_system.cpp:375
kigMin
T kigMin(const T &a, const T &b)
Definition: misc/common.h:255
common.h
Rect::topRight
Coordinate topRight() const
Definition: rect.cc:176
Goniometry::Rad
Definition: goniometry.h:31
EuclideanCoords::EuclideanCoords
EuclideanCoords()
Definition: coordinate_system.cpp:146
PolarCoords::toScreen
Coordinate toScreen(const QString &pt, bool &ok) const
Definition: coordinate_system.cpp:382
PolarCoords::drawGrid
void drawGrid(KigPainter &p, bool showgrid=true, bool showaxes=true) const
Definition: coordinate_system.cpp:403
KigPainter::setPen
void setPen(const QPen &p)
Definition: kigpainter.cpp:244
KigDocument
KigDocument is the class holding the real data in a Kig document.
Definition: kig_document.h:36
kigSgn
int kigSgn(const T &a)
Definition: misc/common.h:273
EuclideanCoords::drawGrid
void drawGrid(KigPainter &p, bool showgrid=true, bool showaxes=true) const
Definition: coordinate_system.cpp:211
CoordinateSystem::CoordinateSystem
CoordinateSystem()
Definition: coordinate_system.cpp:343
Coordinate::x
double x
X Component.
Definition: coordinate.h:126
Coordinate::y
double y
Y Component.
Definition: coordinate.h:129
Rect::bottomRight
Coordinate bottomRight() const
Definition: rect.cc:166
coordinate.h
KigWidget::pixelWidth
double pixelWidth() const
Definition: kig_view.cpp:287
nicenum
static double nicenum(double x, bool round)
copied and adapted from a ( public domain ) function i found in the first Graphics Gems book...
Definition: coordinate_system.cpp:189
polarTypeString
static const char polarTypeString[]
Definition: coordinate_system.cpp:545
KigPainter::drawSegment
void drawSegment(const Coordinate &from, const Coordinate &to)
draw a segment...
Definition: kigpainter.cpp:94
EuclideanCoords::toScreen
Coordinate toScreen(const QString &pt, bool &ok) const
Definition: coordinate_system.cpp:162
KigPainter::drawArea
void drawArea(const std::vector< Coordinate > &pts, bool border=true)
draw an area defined by the points in pts filled with the set color...
Definition: kigpainter.cpp:327
PolarCoords::type
const char * type() const
Definition: coordinate_system.cpp:561
PolarCoords::coordinateFormatNotice
QString coordinateFormatNotice() const
This returns a notice to say in which format coordinates should be entered.
Definition: coordinate_system.cpp:368
KigWidget::showingRect
const Rect showingRect() const
Mapping between Internal Coordinate Systems there are two coordinate systems: 1 the widget's coordina...
Definition: kig_view.cpp:277
PolarCoords::id
int id() const
Definition: coordinate_system.cpp:571
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