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

kstars

  • sources
  • kde-4.12
  • kdeedu
  • kstars
  • kstars
  • skycomponents
linelistlabel.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  linelistlabel.cpp - K Desktop Planetarium
3  -------------------
4  begin : 2007-08-08
5  copyright : (C) 2007 James B. Bowlin
6  email : bowlin@mindspring.com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include <QString>
19 
20 #include "linelistlabel.h"
21 #include "Options.h"
22 #include "skyobjects/skypoint.h"
23 #include "skymap.h"
24 #include "skylabeler.h"
25 #include "linelist.h"
26 #include "projections/projector.h"
27 
28 LineListLabel::LineListLabel( const QString& text )
29  : m_text( text )
30 {
31  m_skyLabeler = SkyLabeler::Instance();
32 
33  // prevent a crash if drawGuideLabel() is called before reset()
34  for ( int i = 0; i < 4; i++ ) {
35  m_labList[i] = 0;
36  m_labIndex[i] = 0;
37  }
38 }
39 
40 void LineListLabel::reset()
41 {
42  // These are the indices of the farthest left point, farthest right point,
43  // etc. The are data members so the drawLabels() routine can use them.
44  // Zero indicates an index that was never set and is considered invalid
45  // inside of drawLabels().
46  for ( int i = 0; i < 4; i++ ) {
47  m_labList[i] = 0;
48  m_labIndex[i] = 0;
49  }
50 
51  // These are used to keep track of the element that is farthest left,
52  // farthest right, etc.
53  m_farLeft = 100000.0;
54  m_farRight = 0.0;
55  m_farTop = 100000.0;
56  m_farBot = 0.0;
57 
58  m_skyLabeler->getMargins( m_text, &m_marginLeft, &m_marginRight,
59  &m_marginTop, &m_marginBot );
60 }
61 
62 void LineListLabel::updateLabelCandidates( qreal x, qreal y, LineList* lineList, int i )
63 {
64  if ( i < 1 ) return;
65 
66  if ( x < m_marginLeft || x > m_marginRight ||
67  y < m_marginTop || y > m_marginBot ) return;
68 
69  if ( x < m_farLeft ) {
70  m_labIndex[LeftCandidate] = i;
71  m_labList[LeftCandidate] = lineList;
72  m_farLeft = x;
73  }
74  if ( x > m_farRight ) {
75  m_labIndex[RightCandidate] = i;
76  m_labList[RightCandidate] = lineList;
77  m_farRight = x;
78  }
79  if ( y > m_farBot ) {
80  m_labIndex[BotCandidate] = i;
81  m_labList[BotCandidate] = lineList;
82  m_farBot = x;
83  }
84  if ( y < m_farTop ) {
85  m_labIndex[TopCandidate] = i;
86  m_labList[TopCandidate] = lineList;
87  m_farTop = x;
88  }
89 }
90 
91 
92 void LineListLabel::draw()
93 {
94  const Projector *proj = SkyMap::Instance()->projector();
95 
96  double comfyAngle = 40.0; // the first valid candidate with an angle
97  // smaller than this gets displayed. If you set
98  // this to > 90. then the first valid candidate
99  // will be displayed, regardless of angle.
100 
101  // We store info about the four candidate points in arrays to make several
102  // of the steps easier, particularly choosing the valid candidate with the
103  // smallest angle from the horizontal.
104 
105  int idx[4]; // index of candidate
106  LineList* list[4]; // LineList of candidate
107  double a[4] = { 360.0, 360.0, 360.0, 360.0 }; // angle, default to large value
108  QPointF o[4]; // candidate point
109  bool okay[4] = { true, true, true, true }; // flag candidate false if it
110  // overlaps a previous label.
111 
112  // We no longer adjust the order but if we were to it would be here
113  static int Order[4] =
114  { LeftCandidate, BotCandidate, TopCandidate, LeftCandidate };
115 
116  for ( int j = 0; j < 4; j++ ) {
117  idx[j] = m_labIndex[ Order[ j ] ];
118  list[j] = m_labList[ Order[ j ] ];
119  }
120 
121  // Make sure start with a valid candidate
122  int first = 0;
123  for ( ; first < 4; first++ ) {
124  if ( idx[first] ) break;
125  }
126 
127  // return if there are no valid candidates
128  if ( first >= 4 ) return;
129 
130 
131  // Try the points in order and print the label if we can draw it at
132  // a comfortable angle for viewing;
133  for ( int j = first; j < 4; j++ ) {
134  o[j] = angleAt( proj, list[j], idx[j], &a[j] );
135 
136  if ( ! idx[j] || ! proj->checkVisibility( list[j]->at( idx[j] ) ) ) {
137  okay[j] = false;
138  continue;
139  }
140 
141  if ( fabs( a[j] ) > comfyAngle )
142  continue;
143 
144  if ( m_skyLabeler->drawGuideLabel( o[j], m_text, a[j] ) )
145  return;
146 
147  okay[j] = false;
148  }
149 
150  //--- No angle was comfy so pick the one with the smallest angle ---
151 
152  // Index of the index/angle/point that gets displayed
153  int best = first;
154 
155  // find first valid candidate that does not overlap existing labels
156  for ( ; best < 4; best++ ) {
157  if ( idx[best] && okay[best] ) break;
158  }
159 
160  // return if all candiates either overlap or are invalid
161  if ( best >= 4 ) return;
162 
163  // find the valid non-overlap candidate with the smallest angle
164  for ( int j = best + 1; j < 4; j++ ) {
165  if ( idx[j] && okay[j] && fabs(a[j]) < fabs(a[best]) ) best = j;
166  }
167 
168  m_skyLabeler->drawGuideLabel( o[best], m_text, a[best] );
169 }
170 
171 
172 QPointF LineListLabel::angleAt( const Projector *proj, LineList* list, int i, double *angle )
173 {
174  SkyPoint* pThis = list->at( i );
175  SkyPoint* pLast = list->at( i - 1 );
176 
177  QPointF oThis = proj->toScreen( pThis );
178  QPointF oLast = proj->toScreen( pLast );
179 
180  double sx = double( oThis.x() - oLast.x() );
181  double sy = double( oThis.y() - oLast.y() );
182 
183  *angle = atan2( sy, sx ) * 180.0 / dms::PI;
184 
185  // FIXME: use clamp in KSUtils
186  // Never draw the label upside down
187  if ( *angle < -90.0 ) *angle += 180.0;
188  if ( *angle > 90.0 ) *angle -= 180.0;
189 
190  return oThis;
191 }
192 
193 
LineList::at
SkyPoint * at(int i)
Definition: linelist.h:54
LineListLabel::TopCandidate
Definition: linelistlabel.h:42
LineList
Definition: linelist.h:35
SkyLabeler::getMargins
void getMargins(const QString &text, float *left, float *right, float *top, float *bot)
sets four margins for help in keeping labels entirely on the screen.
Definition: skylabeler.cpp:195
Projector::checkVisibility
bool checkVisibility(SkyPoint *p) const
Determine if the skypoint p is likely to be visible in the display window.
Definition: projector.cpp:181
SkyLabeler::Instance
static SkyLabeler * Instance()
Definition: skylabeler.cpp:49
SkyPoint
The sky coordinates of a point in the sky.
Definition: skypoint.h:50
Projector
This class serves as an interface to handle projections.
Definition: projector.h:49
Projector::toScreen
QPointF toScreen(const SkyPoint *o, bool oRefract=true, bool *onVisibleHemisphere=0) const
This is exactly the same as toScreenVec but it returns a QPointF.
Definition: projector.cpp:93
linelist.h
linelistlabel.h
LineListLabel::BotCandidate
Definition: linelistlabel.h:42
skymap.h
LineListLabel::LineListLabel
LineListLabel(const QString &text)
Definition: linelistlabel.cpp:28
skypoint.h
SkyLabeler::drawGuideLabel
bool drawGuideLabel(QPointF &o, const QString &text, double angle)
Tries to draw the text at the position and angle specified.
Definition: skylabeler.cpp:104
Options.h
LineListLabel::reset
void reset()
Definition: linelistlabel.cpp:40
PI
#define PI
Definition: satellite.cpp:43
projector.h
LineListLabel::draw
void draw()
Definition: linelistlabel.cpp:92
SkyMap::Instance
static SkyMap * Instance()
Definition: skymap.cpp:141
skylabeler.h
SkyMap::projector
const Projector * projector() const
Get the current projector.
Definition: skymap.h:264
LineListLabel::RightCandidate
Definition: linelistlabel.h:42
LineListLabel::LeftCandidate
Definition: linelistlabel.h:42
LineListLabel::updateLabelCandidates
void updateLabelCandidates(qreal x, qreal y, LineList *lineList, int i)
Definition: linelistlabel.cpp:62
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:36:20 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kstars

Skip menu "kstars"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

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