dRonin  adbada4
dRonin GCS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
waypointcurve.cpp
Go to the documentation of this file.
1 
12 /*
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, see <http://www.gnu.org/licenses/>
25 */
26 #include "waypointcurve.h"
27 #include <math.h>
28 #include "homeitem.h"
29 
30 namespace mapcontrol
31 {
32 
42 WayPointCurve::WayPointCurve(WayPointItem *start, WayPointItem *dest, double radius, bool clockwise, MapGraphicItem *map,QColor color) :
43  QGraphicsEllipseItem(map), m_start(start), m_dest(dest), m_radius(radius),
44  m_clockwise(clockwise), my_map(map),myColor(color)
45 {
46  connect(start, SIGNAL(relativePositionChanged(QPointF, MapPointItem*)), this, SLOT(refreshLocations()));
47  connect(dest, SIGNAL(relativePositionChanged(QPointF, MapPointItem*)), this, SLOT(refreshLocations()));
48  connect(start,SIGNAL(aboutToBeDeleted(MapPointItem*)),this,SLOT(waypointdeleted()));
49  connect(dest,SIGNAL(aboutToBeDeleted(MapPointItem*)),this,SLOT(waypointdeleted()));
50  refreshLocations();
51  connect(map,SIGNAL(childSetOpacity(qreal)),this,SLOT(setOpacitySlot(qreal)));
52 
53 }
54 
56 int WayPointCurve::type() const
57 {
58  // Enable the use of qgraphicsitem_cast with this item.
59  return Type;
60 }
61 
66 void WayPointCurve::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
67 {
68  Q_UNUSED(option);
69  Q_UNUSED(widget);
70 
71  QPen myPen = pen();
72  myPen.setColor(myColor);
73  painter->setPen(myPen);
74  painter->setBrush(myColor);
75 
76  qreal arrowSize = 10;
77  QBrush brush=painter->brush();
78 
79  QPointF arrowP1 = midpoint + QPointF(sin(midpoint_angle + M_PI / 3) * arrowSize,
80  cos(midpoint_angle + M_PI / 3) * arrowSize);
81  QPointF arrowP2 = midpoint + QPointF(sin(midpoint_angle + M_PI - M_PI / 3) * arrowSize,
82  cos(midpoint_angle + M_PI - M_PI / 3) * arrowSize);
83 
84  arrowHead.clear();
85  arrowHead << midpoint << arrowP1 << arrowP2;
86  painter->drawPolygon(arrowHead);
87  painter->setBrush(brush);
88  painter->drawArc(this->rect(), this->startAngle(), this->spanAngle());
89 }
90 
96 {
97  double m_n, m_e, p_n, p_e, d, center_x, center_y, midpoint_x, midpoint_y;
98 
99  // Center between start and end
100  m_n = (m_start->pos().x() + m_dest->pos().x()) / 2;
101  m_e = (m_start->pos().y() + m_dest->pos().y()) / 2;
102 
103  // Normal vector the line between start and end.
104  if (!m_clockwise) {
105  p_n = -(m_dest->pos().y() - m_start->pos().y());
106  p_e = (m_dest->pos().x() - m_start->pos().x());
107  } else {
108  p_n = (m_dest->pos().y() - m_start->pos().y());
109  p_e = -(m_dest->pos().x() - m_start->pos().x());
110  }
111 
112  double radius_sign = (m_radius > 0) ? 1 : -1;
113  double pixels2meters = my_map->Projection()->GetGroundResolution(my_map->ZoomTotal(), m_start->Coord().Lat());
114  double radius = fabs(m_radius / pixels2meters);
115 
116  // Work out how far to go along the perpendicular bisector
117  d = sqrt(radius * radius / (p_n * p_n + p_e * p_e) - 0.25f);
118 
119  if ((fabs(p_n) < 1e-3 && fabs(p_e) < 1e-3) || ((d == d) == false)) {
120  // Segment has no length, put valid values there to prevent crash
121  // check for nan in the d term too
122  center_x = m_n;
123  center_y = m_e;
124  midpoint_x = m_n;
125  midpoint_y = m_e;
126  } else {
127  center_x = m_n + p_n * d * radius_sign;
128  center_y = m_e + p_e * d * radius_sign;
129 
130  d = sqrt(radius * radius / (p_n * p_n + p_e * p_e));
131  midpoint_x = center_x - p_n * d;
132  midpoint_y = center_y - p_e * d;
133  }
134 
135  // Store the center and midpoint
136  center.setX(center_x);
137  center.setY(center_y);
138  midpoint.setX(midpoint_x);
139  midpoint.setY(midpoint_y);
140 
141  // Compute the midpoint along the arc for the arrow
142  midpoint_angle = -atan2(m_dest->pos().y() - m_start->pos().y(), m_dest->pos().x() - m_start->pos().x());
143 
144  double startAngle = atan2(-(m_start->pos().y() - center_y), m_start->pos().x() - center_x);
145  double endAngle = atan2(-(m_dest->pos().y() - center_y), m_dest->pos().x() - center_x);
146  double span = endAngle - startAngle;
147  if (!m_clockwise) {
148  if (span > 0)
149  span = span - 2 * M_PI;
150  } else {
151  if (span < 0)
152  span = span + 2 * M_PI;
153  }
154  setRect(center_x - radius, center_y - radius, 2 * radius, 2 * radius);
155  setStartAngle(startAngle * 180.0 / M_PI * 16.0);
156  setSpanAngle(span * 180.0 / M_PI * 16.0);
157  update();
158 }
159 
161 {
162  this->deleteLater();
163 }
164 
165 void WayPointCurve::setOpacitySlot(qreal opacity)
166 {
167  setOpacity(opacity);
168 }
169 
170 }
void refreshLocations()
Called if the waypoints move to redraw the curve.
void waypointdeleted()
Called if the start or end point is destroyed.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
WayPointCurve::paint Draw the path arc.
A graphicsItem representing a Home Location.
void setOpacitySlot(qreal opacity)
virtual double GetGroundResolution(const int &zoom, const double &latitude)
PureProjection::GetGroundResolution Returns the conversion from pixels to meters. ...
e
Definition: OPPlots.m:99
A graphicsItem representing a curve connecting 2 waypoints.