-
Notifications
You must be signed in to change notification settings - Fork 0
/
visualization.cpp
182 lines (161 loc) · 4.43 KB
/
visualization.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include "wx/wx.h"
#include "wx/utils.h"
#include "wx/sizer.h"
#include "visualization.hpp"
#include "graham_scan.hpp"
/********************* APP ***********************/
IMPLEMENT_APP(App)
bool
App::OnInit()
{
wxBoxSizer * szr = new wxBoxSizer(wxVERTICAL);
this->frame = new wxFrame((wxFrame *)NULL, -1, wxT(APP_NAME), wxPoint(50,50), wxSize(800,600));
this->drawPane = new BasicDrawingPane((wxFrame *) this->frame);
szr->Add(this->drawPane, 1, wxEXPAND);
this->frame->SetSizer(szr);
this->frame->SetAutoLayout(true);
this->frame->Show();
return true;
}
/**************************************************/
/************* BasicDrawingPane Methods ***********/
BasicDrawingPane::BasicDrawingPane(wxFrame * parent) :
wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSIMPLE_BORDER)
{
g = new GrahamScan;
}
/*
* void mouseDown(e)
*
* The mouseDown event will capture LEFT clicks of the mouse
* when the mouse is over the pane. This point is added to the
* set of points maintained by the graham scan.
*
* return
* None
*/
void
BasicDrawingPane::mouseDown(wxMouseEvent & e)
{
/* get the point that the mouse clicked */
const wxPoint& pt = wxGetMousePosition();
/*
* get the x, y position of the mouse click relative to this
* window.
*/
int xPos = pt.x - this->GetScreenPosition().x;
int yPos = pt.y - this->GetScreenPosition().y;
g->addPoint(xPos, yPos);
/* repaint the canvas */
paintNow();
}
/*
* void keyPressed(e)
*
* The keyPressed event will capture key presses designated by the macros
* in visualization.hpp. Currectly if the user hits the `r' key, then the
* pane will be reset. If the user hits the `h' key then the hull will be
* calculated for the set of points maintained by g. Otherwise, nothing
* occurs.
*
* return
* None
*/
void
BasicDrawingPane::keyPressed(wxKeyEvent & e)
{
const wxChar c = e.GetUnicodeKey();
switch (c) {
case RESET_KEY:
/* pts and hull will be empty so clear re-render */
{
g->clear();
wxClientDC dc(this);
dc.Clear();
}
break;
case RUN_KEY:
g->findHull();
/* hull points will not be empty so re-render */
break;
default:
/* all other key presses are not handled */
return;
}
/* repaint the canvas since state has changed */
paintNow();
}
/*
* void paintEvent(e)
*
* This event is fired whenever, painting happens on the pane.
* There is no need to explicitly handle this event, other than rendering
* the current context. This is called whenever something needs to be
* rendered.
*
* return
* None
*/
void
BasicDrawingPane::paintEvent(wxPaintEvent & e)
{
wxPaintDC dc(this);
render (dc);
}
/*
* void paintNow()
*
* This method is not an event; rather, it is called whenever the state
* needs to be updated. For example, if the user clicks a key we force a
* re-render of the screen.
*
* return
* None
*/
void
BasicDrawingPane::paintNow()
{
wxClientDC dc(this);
render (dc);
}
/*
* void render(dc)
*
* This method will render the points in the scan and the hull
* if there are any points in the hull set.
*
* return
* None
*/
void
BasicDrawingPane::render(wxDC& dc)
{
std::vector<Point> & pts = g->getPoints();
int N = pts.size();
/* grey filling */
dc.SetBrush(*wxLIGHT_GREY_BRUSH);
/* blue outline for the pen */
dc.SetPen( wxPen(BLUE, POINT_OUTLINE_THICKNESS) );
/* draw the points if there are any */
for (int i = 0; i < N; ++i) {
Point p = pts[i];
dc.DrawCircle( wxPoint(p.x, p.y), POINT_RADIUS );
}
/* there will only be hull points if user hit key for finding them */
std::vector<Point>& hull = g->getHull();
N = hull.size();
/* red line for connecting hull points */
dc.SetPen( wxPen(RED, HULL_OUTLINE_THICKNESS) );
/* draw lines connecting the hull */
for (int i = 0; i < N-1; ++i) {
Point p1 = hull[i];
Point p2 = hull[i+1];
dc.DrawLine(p1.x, p1.y, p2.x, p2.y);
}
if (!hull.empty()) { /* connect the last two points */
Point first = hull[0];
Point last = hull[N-1];
dc.DrawLine(first.x, first.y, last.x, last.y);
}
}
/**************************************************/