OpenCPN Partial API docs
Loading...
Searching...
No Matches
dial.cpp
1/******************************************************************************
2 * $Id: dial.cpp, v1.0 2010/08/05 SethDart Exp $
3 *
4 * Project: OpenCPN
5 * Purpose: Dashboard Plugin
6 * Author: Jean-Eudes Onfray
7 * (Inspired by original work from Andreas Heiming)
8 *
9 ***************************************************************************
10 * Copyright (C) 2010 by David S. Register *
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 * This program is distributed in the hope that it will be useful, *
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20 * GNU General Public License for more details. *
21 * *
22 * You should have received a copy of the GNU General Public License *
23 * along with this program; if not, write to the *
24 * Free Software Foundation, Inc., *
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
26 ***************************************************************************
27 */
28
29#include <wx/wxprec.h>
30
31#ifndef WX_PRECOMP
32#include <wx/wx.h>
33#endif // precompiled headers
34
35#include "dial.h"
36
37#ifdef __BORLANDC__
38#pragma hdrstop
39#endif
40
41#include <cmath>
42#include "wx/tokenzr.h"
43
44#ifdef __OCPN__ANDROID__
45#include "qdebug.h"
46#endif
47
48double rad2deg(double angle) { return angle * 180.0 / M_PI; }
49double deg2rad(double angle) { return angle / 180.0 * M_PI; }
50
51DashboardInstrument_Dial::DashboardInstrument_Dial(
52 wxWindow* parent, wxWindowID id, wxString title,
53 InstrumentProperties* Properties, DASH_CAP cap_flag, int s_angle,
54 int r_angle, int s_value, int e_value)
55 : DashboardInstrument(parent, id, title, cap_flag, Properties) {
56 m_AngleStart = s_angle;
57 m_AngleRange = r_angle;
58 m_MainValueMin = s_value;
59 m_MainValueMax = e_value;
60 m_MainValueCap = cap_flag;
61
62 m_MainValue = s_value;
63 m_ExtraValue = 0;
64 m_MainValueFormat = _T("%d");
65 m_MainValueUnit = _T("");
66 m_MainValueOption = DIAL_POSITION_NONE;
67 m_ExtraValueFormat = _T("%d");
68 m_ExtraValueUnit = _T("");
69 m_ExtraValueOption = DIAL_POSITION_NONE;
70 m_MarkerOption = DIAL_MARKER_SIMPLE;
71 m_MarkerStep = 1;
72 m_LabelStep = 1;
73 m_MarkerOffset = 1;
74 m_LabelOption = DIAL_LABEL_HORIZONTAL;
75}
76
77wxSize DashboardInstrument_Dial::GetSize(int orient, wxSize hint) {
78 InitTitleSize();
79 InitTitleAndDataPosition(DefaultWidth);
80 int w;
81 if (orient == wxHORIZONTAL) {
82 w = wxMax(hint.y, GetFullHeight(DefaultWidth));
83 return wxSize(w - m_TitleHeight, w);
84 } else {
85 w = wxMax(hint.x, DefaultWidth);
86 return wxSize(w, GetFullHeight(w));
87 }
88}
89
90void DashboardInstrument_Dial::SetData(DASH_CAP st, double data,
91 wxString unit) {
92 if (st == m_MainValueCap) {
93 m_MainValue = data;
94 m_MainValueUnit = unit;
95 } else if (st == m_ExtraValueCap) {
96 m_ExtraValue = data;
97 m_ExtraValueUnit = unit;
98 }
99 Refresh();
100}
101
102void DashboardInstrument_Dial::Draw(wxGCDC* bdc) {
103 if (m_Properties) {
104 wxBrush b1(
105 GetColourSchemeBackgroundColour(m_Properties->m_DataBackgroundColour));
106 bdc->SetBackground(b1);
107 } else {
108 wxColour c1;
109 GetGlobalColor(_T("DASHB"), &c1);
110 wxBrush b1(c1);
111 bdc->SetBackground(b1);
112 }
113 bdc->Clear();
114
115 wxSize size = GetClientSize();
116 m_cx = size.x / 2;
117 int availableHeight = GetDataBottom(size.y) - m_DataTop;
118 InitTitleAndDataPosition(availableHeight);
119 availableHeight -= 6;
120 int width, height;
121 wxFont f;
122 if (m_Properties)
123 f = m_Properties->m_LabelFont.GetChosenFont();
124 else
125 f = g_pFontLabel->GetChosenFont();
126 bdc->GetTextExtent(_T("000"), &width, &height, 0, 0, &f);
127 m_cy = m_DataTop + 2;
128 m_cy += availableHeight / 2;
129 m_radius = availableHeight / 2;
130
131 DrawFrame(bdc);
132 DrawLabels(bdc);
133 DrawMarkers(bdc);
134 DrawBackground(bdc);
135 DrawData(bdc, m_MainValue, m_MainValueUnit, m_MainValueFormat,
136 m_MainValueOption);
137 DrawData(bdc, m_ExtraValue, m_ExtraValueUnit, m_ExtraValueFormat,
138 m_ExtraValueOption);
139 DrawForeground(bdc);
140}
141
142void DashboardInstrument_Dial::DrawFrame(wxGCDC* dc) {
143 wxSize size = GetClientSize();
144 wxColour cl;
145 if (m_Properties) {
146 cl = GetColourSchemeBackgroundColour(m_Properties->m_TitleBackgroundColour);
147 } else {
148 GetGlobalColor(_T("DASHL"), &cl);
149 }
150 dc->SetTextForeground(cl);
151 dc->SetBrush(*wxTRANSPARENT_BRUSH);
152
153 int penwidth = 1 + size.x / 100;
154 wxPen pen(cl, penwidth, wxPENSTYLE_SOLID);
155
156 if (m_MarkerOption == DIAL_MARKER_REDGREENBAR) {
157 pen.SetWidth(penwidth * 2);
158 GetGlobalColor(_T("DASHR"), &cl);
159 pen.SetColour(cl);
160 dc->SetPen(pen);
161 double angle1 = deg2rad(270); // 305-ANGLE_OFFSET
162 double angle2 = deg2rad(90); // 55-ANGLE_OFFSET
163 int radi = m_radius - 1 - penwidth;
164 wxCoord x1 = m_cx + ((radi)*cos(angle1));
165 wxCoord y1 = m_cy + ((radi)*sin(angle1));
166 wxCoord x2 = m_cx + ((radi)*cos(angle2));
167 wxCoord y2 = m_cy + ((radi)*sin(angle2));
168 dc->DrawArc(x1, y1, x2, y2, m_cx, m_cy);
169
170 GetGlobalColor(_T("DASHG"), &cl);
171 pen.SetColour(cl);
172 dc->SetPen(pen);
173 angle1 = deg2rad(89); // 305-ANGLE_OFFSET
174 angle2 = deg2rad(271); // 55-ANGLE_OFFSET
175 x1 = m_cx + ((radi)*cos(angle1));
176 y1 = m_cy + ((radi)*sin(angle1));
177 x2 = m_cx + ((radi)*cos(angle2));
178 y2 = m_cy + ((radi)*sin(angle2));
179 dc->DrawArc(x1, y1, x2, y2, m_cx, m_cy);
180
181 // Some platforms have trouble with transparent pen.
182 // so we simply draw arcs for the outer ring.
183 GetGlobalColor(_T("DASHF"), &cl);
184 pen.SetWidth(penwidth);
185 pen.SetColour(cl);
186 dc->SetPen(pen);
187 angle1 = deg2rad(0);
188 angle2 = deg2rad(180);
189 radi = m_radius - 1;
190
191 x1 = m_cx + ((radi)*cos(angle1));
192 y1 = m_cy + ((radi)*sin(angle1));
193 x2 = m_cx + ((radi)*cos(angle2));
194 y2 = m_cy + ((radi)*sin(angle2));
195 dc->DrawArc(x1, y1, x2, y2, m_cx, m_cy);
196 dc->DrawArc(x2, y2, x1, y1, m_cx, m_cy);
197
198 } else {
199 GetGlobalColor(_T("DASHF"), &cl);
200 pen.SetColour(cl);
201 dc->SetPen(pen);
202 dc->DrawCircle(m_cx, m_cy, m_radius);
203 }
204}
205
206void DashboardInstrument_Dial::DrawMarkers(wxGCDC* dc) {
207 if (m_MarkerOption == DIAL_MARKER_NONE) return;
208
209 wxColour cl;
210 GetGlobalColor(_T("DASHF"), &cl);
211 int penwidth = GetClientSize().x / 100;
212 wxPen pen(cl, penwidth, wxPENSTYLE_SOLID);
213 dc->SetPen(pen);
214
215 int diff_angle = m_AngleStart + m_AngleRange - ANGLE_OFFSET;
216 // angle between markers
217 double abm = m_AngleRange * m_MarkerStep / (m_MainValueMax - m_MainValueMin);
218 // don't draw last value, it's already done as first
219 if (m_AngleRange == 360) diff_angle -= abm;
220
221 int offset = 0;
222 for (double angle = m_AngleStart - ANGLE_OFFSET; angle <= diff_angle;
223 angle += abm) {
224 if (m_MarkerOption == DIAL_MARKER_REDGREEN) {
225 int a = int(angle + ANGLE_OFFSET) % 360;
226 if (a > 180)
227 GetGlobalColor(_T("DASHR"), &cl);
228 else if ((a > 0) && (a < 180))
229 GetGlobalColor(_T("DASHG"), &cl);
230 else
231 GetGlobalColor(_T("DASHF"), &cl);
232
233 pen.SetColour(cl);
234 dc->SetPen(pen);
235 }
236
237 double size = 0.92;
238 if (offset % m_MarkerOffset) {
239 size = 0.96;
240 }
241 offset++;
242
243 dc->DrawLine(m_cx + ((m_radius - 1) * size * cos(deg2rad(angle))),
244 m_cy + ((m_radius - 1) * size * sin(deg2rad(angle))),
245 m_cx + ((m_radius - 1) * cos(deg2rad(angle))),
246 m_cy + ((m_radius - 1) * sin(deg2rad(angle))));
247 }
248 // We must reset pen color so following drawings are fine
249 if (m_MarkerOption == DIAL_MARKER_REDGREEN) {
250 GetGlobalColor(_T("DASHF"), &cl);
251 pen.SetStyle(wxPENSTYLE_SOLID);
252 pen.SetColour(cl);
253 dc->SetPen(pen);
254 }
255}
256
257void DashboardInstrument_Dial::DrawLabels(wxGCDC* dc) {
258 if (m_LabelOption == DIAL_LABEL_NONE) return;
259
260 wxPoint TextPoint;
261 wxPen pen;
262 wxColor cl;
263 GetGlobalColor(_T("DASHF"), &cl);
264
265 if (m_Properties) {
266 dc->SetFont(m_Properties->m_SmallFont.GetChosenFont());
267 dc->SetTextForeground(
268 GetColourSchemeFont(m_Properties->m_SmallFont.GetColour()));
269 } else {
270 dc->SetFont(g_pFontSmall->GetChosenFont());
271 dc->SetTextForeground(GetColourSchemeFont(g_pFontSmall->GetColour()));
272 }
273 int diff_angle = m_AngleStart + m_AngleRange - ANGLE_OFFSET;
274 // angle between markers
275 double abm = m_AngleRange * m_LabelStep / (m_MainValueMax - m_MainValueMin);
276 // don't draw last value, it's already done as first
277 if (m_AngleRange == 360) diff_angle -= abm;
278
279 int offset = 0;
280 int value = m_MainValueMin;
281 int width, height;
282 wxFont f;
283 for (double angle = m_AngleStart - ANGLE_OFFSET; angle <= diff_angle;
284 angle += abm) {
285 wxString label =
286 (m_LabelArray.GetCount() ? m_LabelArray.Item(offset)
287 : wxString::Format(_T("%d"), value));
288 if (m_Properties)
289 f = m_Properties->m_SmallFont.GetChosenFont();
290 else
291 f = g_pFontSmall->GetChosenFont();
292 dc->GetTextExtent(label, &width, &height, 0, 0, &f);
293 double halfW = width / 2;
294 if (m_LabelOption == DIAL_LABEL_HORIZONTAL) {
295 double halfH = height / 2;
296 // double delta = sqrt(width*width+height*height);
297 double delta = sqrt(halfW * halfW + halfH * halfH);
298 TextPoint.x =
299 m_cx + ((m_radius * 0.90) - delta) * cos(deg2rad(angle)) - halfW;
300 TextPoint.y =
301 m_cy + ((m_radius * 0.90) - delta) * sin(deg2rad(angle)) - halfH;
302 dc->DrawText(label, TextPoint);
303
304 } else if (m_LabelOption == DIAL_LABEL_ROTATED) {
305 // The coordinates of dc->DrawRotatedText refer to the top-left corner
306 // of the rectangle bounding the string. So we must calculate the
307 // right coordinates depending of the angle.
308 // Move left from the Marker so that the position is in the Middle of Text
309 long double tmpangle = angle - rad2deg(asin(halfW / (0.90 * m_radius)));
310 TextPoint.x = m_cx + m_radius * 0.90 * cos(deg2rad(tmpangle));
311 TextPoint.y = m_cy + m_radius * 0.90 * sin(deg2rad(tmpangle));
312 dc->DrawRotatedText(label, TextPoint, -90 - angle);
313 }
314 offset++;
315 value += m_LabelStep;
316 }
317}
318
319void DashboardInstrument_Dial::DrawBackground(wxGCDC* dc) {
320 // Nothing to do here right now, will be overwritten
321 // by child classes if required
322}
323
324void DashboardInstrument_Dial::DrawData(wxGCDC* dc, double value, wxString unit,
325 wxString format,
326 DialPositionOption position) {
327 if (position == DIAL_POSITION_NONE) return;
328
329 if (m_Properties) {
330 dc->SetFont(m_Properties->m_LabelFont.GetChosenFont());
331 dc->SetTextForeground(
332 GetColourSchemeFont(m_Properties->m_LabelFont.GetColour()));
333 } else {
334 dc->SetFont(g_pFontLabel->GetChosenFont());
335 dc->SetTextForeground(GetColourSchemeFont(g_pFontLabel->GetColour()));
336 }
337 wxColour cl;
338 // GetGlobalColor(_T("DASHF"), &cl);
339 wxSize size = GetClientSize();
340
341 wxString text;
342 if (!std::isnan(value)) {
343 if (unit == _T("\u00B0"))
344 text = wxString::Format(format, value) + DEGREE_SIGN;
345 else if (unit == _T("\u00B0L")) // No special display for now, might be
346 // XX�< (as in text-only instrument)
347 text = wxString::Format(format, value) + DEGREE_SIGN;
348 else if (unit ==
349 _T("\u00B0R")) // No special display for now, might be >XX�
350 text = wxString::Format(format, value) + DEGREE_SIGN;
351 else if (unit == _T("\u00B0T"))
352 text = wxString::Format(format, value) + DEGREE_SIGN + _T("T");
353 else if (unit == _T("\u00B0M"))
354 text = wxString::Format(format, value) + DEGREE_SIGN + _T("M");
355 else if (unit == _T("N")) // Knots
356 text = wxString::Format(format, value) + _T(" Kts");
357 else
358 text = wxString::Format(format, value) + _T(" ") + unit;
359 } else
360 text = _T("---");
361
362 int width, height;
363 wxFont f;
364 if (m_Properties)
365 f = m_Properties->m_LabelFont.GetChosenFont();
366 else
367 f = g_pFontLabel->GetChosenFont();
368 dc->GetMultiLineTextExtent(text, &width, &height, NULL, &f);
369
370 wxRect TextPoint;
371 TextPoint.width = width;
372 TextPoint.height = height;
373 switch (position) {
374 case DIAL_POSITION_NONE:
375 // This case was already handled before, it's here just
376 // to avoid compiler warning.
377 return;
378 case DIAL_POSITION_INSIDE: {
379 TextPoint.x = m_cx - (width / 2) - 1;
380 TextPoint.y = ((size.y - m_InstrumentSpacing) * .75) - height;
381 if ((g_TitleAlignment & wxALIGN_BOTTOM) != 0)
382 TextPoint.y -= m_TitleHeight;
383 if (m_Properties)
384 cl = GetColourSchemeBackgroundColour(
385 m_Properties->m_TitleBackgroundColour);
386 else
387 GetGlobalColor(_T("DASHL"), &cl);
388 int penwidth = size.x / 100;
389 wxPen* pen =
390 wxThePenList->FindOrCreatePen(cl, penwidth, wxPENSTYLE_SOLID);
391 dc->SetPen(*pen);
392 if (m_Properties)
393 cl = GetColourSchemeBackgroundColour(
394 m_Properties->m_DataBackgroundColour);
395 else
396 GetGlobalColor(_T("DASHB"), &cl);
397 dc->SetBrush(cl);
398 // There might be a background drawn below
399 // so we must clear it first.
400 dc->DrawRoundedRectangle(TextPoint.x - 2, TextPoint.y - 2, width + 4,
401 height + 4, 3);
402 break;
403 }
404 case DIAL_POSITION_TOPLEFT:
405 TextPoint.x = 0;
406 TextPoint.y = m_DataTop;
407 break;
408 case DIAL_POSITION_TOPRIGHT:
409 TextPoint.x = size.x - width - 1;
410 TextPoint.y = m_DataTop;
411 break;
412 case DIAL_POSITION_BOTTOMLEFT:
413 TextPoint.x = 0;
414 TextPoint.y = GetDataBottom(size.y) - height;
415 break;
416 case DIAL_POSITION_BOTTOMRIGHT:
417 TextPoint.x = size.x - width - 1;
418 TextPoint.y = GetDataBottom(size.y) - height;
419 break;
420 case DIAL_POSITION_BOTTOMMIDDLE:
421 if (!std::isnan(value)) {
422 TextPoint.x = m_cx - (width / 2) - 1;
423 TextPoint.y = GetDataBottom(size.y) - height;
424 // There might be a background drawn below
425 // so we must clear it first.
426 dc->DrawRoundedRectangle(TextPoint.x - 2, TextPoint.y - 2, width + 4,
427 height + 4, 3);
428 }
429 break;
430 }
431
432 // wxColour c2;
433 // GetGlobalColor(_T("DASHB"), &c2);
434 wxColour c3;
435 GetGlobalColor(_T("DASHF"), &c3);
436
437 wxStringTokenizer tkz(text, _T("\n"));
438 wxString token;
439
440 token = tkz.GetNextToken();
441 while (token.Length()) {
442 if (m_Properties)
443 f = m_Properties->m_LabelFont.GetChosenFont();
444 else
445 f = g_pFontLabel->GetChosenFont();
446 dc->GetTextExtent(token, &width, &height, NULL, NULL, &f);
447 dc->DrawText(token, TextPoint.x, TextPoint.y);
448 TextPoint.y += height;
449 token = tkz.GetNextToken();
450 }
451}
452
453void DashboardInstrument_Dial::DrawForeground(wxGCDC* dc) {
454 // The default foreground is the arrow used in most dials
455 wxColour cl;
456 GetGlobalColor(_T("DASH2"), &cl);
457 wxPen pen1;
458 pen1.SetStyle(wxPENSTYLE_SOLID);
459 pen1.SetColour(cl);
460 pen1.SetWidth(2);
461 dc->SetPen(pen1);
462 GetGlobalColor(_T("DASH1"), &cl);
463 wxBrush brush1;
464 brush1.SetStyle(wxBRUSHSTYLE_SOLID);
465 brush1.SetColour(cl);
466 dc->SetBrush(brush1);
467 dc->DrawCircle(m_cx, m_cy, m_radius / 8);
468
469 dc->SetPen(*wxTRANSPARENT_PEN);
470 if (m_Properties)
471 cl = GetColourSchemeFont(m_Properties->m_Arrow_First_Colour);
472 else
473 GetGlobalColor(_T("DASHN"), &cl);
474 wxBrush brush;
475 brush.SetStyle(wxBRUSHSTYLE_SOLID);
476 brush.SetColour(cl);
477 dc->SetBrush(brush);
478
479 /* this is fix for a +/-180� round instrument, when m_MainValue is supplied as
480 * <0..180><L | R> for example TWA & AWA */
481 double data;
482 if (m_MainValueUnit == _T("\u00B0L"))
483 data = 360 - m_MainValue;
484 else
485 data = m_MainValue;
486
487 // The arrow should stay inside fixed limits
488 double val;
489 if (data < m_MainValueMin)
490 val = m_MainValueMin;
491 else if (data > m_MainValueMax)
492 val = m_MainValueMax;
493 else
494 val = data;
495
496 double value = deg2rad((val - m_MainValueMin) * m_AngleRange /
497 (m_MainValueMax - m_MainValueMin)) +
498 deg2rad(m_AngleStart - ANGLE_OFFSET);
499
500 wxPoint points[4];
501 points[0].x = m_cx + (m_radius * 0.95 * cos(value - .010));
502 points[0].y = m_cy + (m_radius * 0.95 * sin(value - .010));
503 points[1].x = m_cx + (m_radius * 0.95 * cos(value + .015));
504 points[1].y = m_cy + (m_radius * 0.95 * sin(value + .015));
505 points[2].x = m_cx + (m_radius * 0.22 * cos(value + 2.8));
506 points[2].y = m_cy + (m_radius * 0.22 * sin(value + 2.8));
507 points[3].x = m_cx + (m_radius * 0.22 * cos(value - 2.8));
508 points[3].y = m_cy + (m_radius * 0.22 * sin(value - 2.8));
509 dc->DrawPolygon(4, points, 0, 0);
510}
511
512/* Shared functions */
513void DrawCompassRose(wxGCDC* dc, int cx, int cy, int radius, int startangle,
514 bool showlabels, InstrumentProperties* Properties) {
515 wxPoint pt, points[3];
516 wxString Value;
517 int width, height;
518 wxString CompassArray[] = {_("N"), _("NE"), _("E"), _("SE"), _("S"),
519 _("SW"), _("W"), _("NW"), _("N")};
520 if (Properties)
521 dc->SetFont((Properties->m_SmallFont.GetChosenFont()));
522 else
523 dc->SetFont((g_pFontSmall->GetChosenFont()));
524
525 wxColour cl;
526 wxPen* pen;
527 GetGlobalColor(_T("DASH2"), &cl);
528 pen = wxThePenList->FindOrCreatePen(cl, 1, wxPENSTYLE_SOLID);
529 wxBrush* b2 = wxTheBrushList->FindOrCreateBrush(cl);
530
531 GetGlobalColor(_T("DASH1"), &cl);
532 wxBrush* b1 = wxTheBrushList->FindOrCreateBrush(cl);
533
534 dc->SetPen(*pen);
535 dc->SetTextForeground(cl);
536 dc->SetBrush(*b2);
537
538 int offset = 0;
539 wxFont f;
540 for (double tmpangle = startangle - ANGLE_OFFSET;
541 tmpangle < startangle + 360 - ANGLE_OFFSET; tmpangle += 90) {
542 if (showlabels) {
543 Value = CompassArray[offset];
544 if (Properties) {
545 f = Properties->m_SmallFont.GetChosenFont();
546 dc->GetTextExtent(Value, &width, &height, 0, 0, &f);
547 } else {
548 f = g_pFontSmall->GetChosenFont();
549 dc->GetTextExtent(Value, &width, &height, 0, 0, &f);
550 }
551 double x = width / 2;
552 long double anglefortext = tmpangle - rad2deg(asin((x / radius)));
553 pt.x = cx + radius * cos(deg2rad(anglefortext));
554 pt.y = cy + radius * sin(deg2rad(anglefortext));
555 dc->DrawRotatedText(Value, pt.x, pt.y, -90 - tmpangle);
556 Value = CompassArray[offset + 1];
557 if (Properties) {
558 f = Properties->m_SmallFont.GetChosenFont();
559 dc->GetTextExtent(Value, &width, &height, 0, 0, &f);
560 } else {
561 f = g_pFontSmall->GetChosenFont();
562 dc->GetTextExtent(Value, &width, &height, 0, 0, &f);
563 }
564 x = width / 2;
565 anglefortext = tmpangle - rad2deg(asin((x / radius))) + 45;
566 pt.x = cx + radius * cos(deg2rad(anglefortext));
567 pt.y = cy + radius * sin(deg2rad(anglefortext));
568 dc->DrawRotatedText(Value, pt.x, pt.y, -135 - tmpangle);
569 }
570 points[0].x = cx;
571 points[0].y = cy;
572 points[1].x = cx + radius * 0.15 * cos(deg2rad(tmpangle));
573 points[1].y = cy + radius * 0.15 * sin(deg2rad(tmpangle));
574 points[2].x = cx + radius * 0.6 * cos(deg2rad(tmpangle + 45));
575 points[2].y = cy + radius * 0.6 * sin(deg2rad(tmpangle + 45));
576 dc->DrawPolygon(3, points, 0, 0);
577 points[1].x = cx + radius * 0.15 * cos(deg2rad(tmpangle + 90));
578 points[1].y = cy + radius * 0.15 * sin(deg2rad(tmpangle + 90));
579 dc->SetBrush(*b1);
580 dc->DrawPolygon(3, points, 0, 0);
581 points[2].x = cx + radius * 0.8 * cos(deg2rad(tmpangle));
582 points[2].y = cy + radius * 0.8 * sin(deg2rad(tmpangle));
583 points[1].x = cx + radius * 0.15 * cos(deg2rad(tmpangle + 45));
584 points[1].y = cy + radius * 0.15 * sin(deg2rad(tmpangle + 45));
585 dc->DrawPolygon(3, points, 0, 0);
586 points[2].x = cx + radius * 0.8 * cos(deg2rad(tmpangle + 90));
587 points[2].y = cy + radius * 0.8 * sin(deg2rad(tmpangle + 90));
588 dc->SetBrush(*b2);
589 dc->DrawPolygon(3, points, 0, 0);
590 offset += 2;
591 }
592}
593
594void DrawBoat(wxGCDC* dc, int cx, int cy, int radius) {
595 // Now draw the boat
596 wxColour cl;
597 GetGlobalColor(_T("DASH2"), &cl);
598 wxPen* pen = wxThePenList->FindOrCreatePen(cl, 1, wxPENSTYLE_SOLID);
599 dc->SetPen(*pen);
600 GetGlobalColor(_T("DASH1"), &cl);
601 dc->SetBrush(cl);
602 wxPoint points[7];
603
604 /*
605 * 0
606 * /\
607 * / \
608 * / \
609 * 6 / \ 1
610 * | |
611 * | X |
612 * 5 | | 2
613 * \ /
614 * \__ _/
615 * 4 3
616 */
617 points[0].x = cx;
618 points[0].y = cy - radius * .60; // a little bit longer than compass rose
619 points[1].x = cx + radius * .15;
620 points[1].y = cy - radius * .08;
621 points[2].x = cx + radius * .15;
622 points[2].y = cy + radius * .12;
623 points[3].x = cx + radius * .10;
624 points[3].y = cy + radius * .40;
625 points[4].x = cx - radius * .10;
626 points[4].y = cy + radius * .40;
627 points[5].x = cx - radius * .15;
628 points[5].y = cy + radius * .12;
629 points[6].x = cx - radius * .15;
630 points[6].y = cy - radius * .08;
631
632 dc->DrawPolygon(7, points, 0, 0);
633}