about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorStar Rauchenberger <fefferburbia@gmail.com>2024-05-18 15:33:30 -0400
committerStar Rauchenberger <fefferburbia@gmail.com>2024-05-18 15:33:30 -0400
commita2b67cf27dbd41bcfa75835e36c605adfc040e40 (patch)
tree53cffc4d0163a5f6923e3851eb8281400cc028f6
parent4d8e36245e8ce43eef9b687a9108fd4c353f756f (diff)
downloadlingo-ap-tracker-a2b67cf27dbd41bcfa75835e36c605adfc040e40.tar.gz
lingo-ap-tracker-a2b67cf27dbd41bcfa75835e36c605adfc040e40.tar.bz2
lingo-ap-tracker-a2b67cf27dbd41bcfa75835e36c605adfc040e40.zip
Coordinate transformation functions
-rw-r--r--src/subway_map.cpp99
-rw-r--r--src/subway_map.h3
2 files changed, 50 insertions, 52 deletions
diff --git a/src/subway_map.cpp b/src/subway_map.cpp index 2e7b36f..5a4be4b 100644 --- a/src/subway_map.cpp +++ b/src/subway_map.cpp
@@ -143,23 +143,20 @@ void SubwayMap::OnPaint(wxPaintEvent &event) {
143 int item_width = col_width + 10 + 32; 143 int item_width = col_width + 10 + 32;
144 int full_width = item_width + 20; 144 int full_width = item_width + 20;
145 145
146 int popup_x = (subway_item.x + AREA_ACTUAL_SIZE / 2) * render_width_ / 146 wxPoint popup_pos =
147 map_image_.GetWidth() + 147 MapPosToRenderPos({subway_item.x + AREA_ACTUAL_SIZE / 2,
148 render_x_; 148 subway_item.y + AREA_ACTUAL_SIZE / 2});
149 int popup_y = (subway_item.y + AREA_ACTUAL_SIZE / 2) * render_width_ / 149
150 map_image_.GetWidth() + 150 if (popup_pos.x + full_width > GetSize().GetWidth()) {
151 render_y_; 151 popup_pos.x = GetSize().GetWidth() - full_width;
152
153 if (popup_x + full_width > GetSize().GetWidth()) {
154 popup_x = GetSize().GetWidth() - full_width;
155 } 152 }
156 if (popup_y + acc_height > GetSize().GetHeight()) { 153 if (popup_pos.y + acc_height > GetSize().GetHeight()) {
157 popup_y = GetSize().GetHeight() - acc_height; 154 popup_pos.y = GetSize().GetHeight() - acc_height;
158 } 155 }
159 156
160 dc.SetPen(*wxTRANSPARENT_PEN); 157 dc.SetPen(*wxTRANSPARENT_PEN);
161 dc.SetBrush(*wxBLACK_BRUSH); 158 dc.SetBrush(*wxBLACK_BRUSH);
162 dc.DrawRectangle({popup_x, popup_y}, {full_width, acc_height}); 159 dc.DrawRectangle(popup_pos, {full_width, acc_height});
163 160
164 dc.SetFont(GetFont()); 161 dc.SetFont(GetFont());
165 162
@@ -168,14 +165,15 @@ void SubwayMap::OnPaint(wxPaintEvent &event) {
168 for (const auto& [text, obtained] : report) { 165 for (const auto& [text, obtained] : report) {
169 wxBitmap *eye_ptr = obtained ? &unchecked_eye_ : &checked_eye_; 166 wxBitmap *eye_ptr = obtained ? &unchecked_eye_ : &checked_eye_;
170 167
171 dc.DrawBitmap(*eye_ptr, {popup_x + 10, popup_y + cur_height}); 168 dc.DrawBitmap(*eye_ptr, popup_pos + wxPoint{10, cur_height});
172 169
173 dc.SetTextForeground(obtained ? *wxWHITE : *wxRED); 170 dc.SetTextForeground(obtained ? *wxWHITE : *wxRED);
174 wxSize item_extent = dc.GetTextExtent(text); 171 wxSize item_extent = dc.GetTextExtent(text);
175 dc.DrawText( 172 dc.DrawText(
176 text, 173 text,
177 {popup_x + 10 + 32 + 10, 174 popup_pos +
178 popup_y + cur_height + (32 - dc.GetFontMetrics().height) / 2}); 175 wxPoint{10 + 32 + 10,
176 cur_height + (32 - dc.GetFontMetrics().height) / 2});
179 177
180 cur_height += 10 + 32; 178 cur_height += 10 + 32;
181 } 179 }
@@ -189,43 +187,34 @@ void SubwayMap::OnPaint(wxPaintEvent &event) {
189 const SubwayItem &item1 = GD_GetSubwayItem(item_id1); 187 const SubwayItem &item1 = GD_GetSubwayItem(item_id1);
190 const SubwayItem &item2 = GD_GetSubwayItem(item_id2); 188 const SubwayItem &item2 = GD_GetSubwayItem(item_id2);
191 189
192 int item1_x = (item1.x + AREA_ACTUAL_SIZE / 2) * render_width_ / 190 wxPoint item1_pos = MapPosToRenderPos(
193 map_image_.GetWidth() + 191 {item1.x + AREA_ACTUAL_SIZE / 2, item1.y + AREA_ACTUAL_SIZE / 2});
194 render_x_; 192 wxPoint item2_pos = MapPosToRenderPos(
195 int item1_y = (item1.y + AREA_ACTUAL_SIZE / 2) * render_width_ / 193 {item2.x + AREA_ACTUAL_SIZE / 2, item2.y + AREA_ACTUAL_SIZE / 2});
196 map_image_.GetWidth() + 194
197 render_y_; 195 int left = std::min(item1_pos.x, item2_pos.x);
198 196 int top = std::min(item1_pos.y, item2_pos.y);
199 int item2_x = (item2.x + AREA_ACTUAL_SIZE / 2) * render_width_ / 197 int right = std::max(item1_pos.x, item2_pos.x);
200 map_image_.GetWidth() + 198 int bottom = std::max(item1_pos.y, item2_pos.y);
201 render_x_;
202 int item2_y = (item2.y + AREA_ACTUAL_SIZE / 2) * render_width_ /
203 map_image_.GetWidth() +
204 render_y_;
205
206 int left = std::min(item1_x, item2_x);
207 int top = std::min(item1_y, item2_y);
208 int right = std::max(item1_x, item2_x);
209 int bottom = std::max(item1_y, item2_y);
210 199
211 int halfwidth = right - left; 200 int halfwidth = right - left;
212 int halfheight = bottom - top; 201 int halfheight = bottom - top;
213 202
214 if (halfwidth < 4 || halfheight < 4) { 203 if (halfwidth < 4 || halfheight < 4) {
215 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 4)); 204 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 4));
216 dc.DrawLine(item1_x, item1_y, item2_x, item2_y); 205 dc.DrawLine(item1_pos, item2_pos);
217 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxCYAN, 2)); 206 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxCYAN, 2));
218 dc.DrawLine(item1_x, item1_y, item2_x, item2_y); 207 dc.DrawLine(item1_pos, item2_pos);
219 } else { 208 } else {
220 int ellipse_x; 209 int ellipse_x;
221 int ellipse_y; 210 int ellipse_y;
222 double start; 211 double start;
223 double end; 212 double end;
224 213
225 if (item1_x > item2_x) { 214 if (item1_pos.x > item2_pos.x) {
226 ellipse_y = top; 215 ellipse_y = top;
227 216
228 if (item1_y > item2_y) { 217 if (item1_pos.y > item2_pos.y) {
229 ellipse_x = left - halfwidth; 218 ellipse_x = left - halfwidth;
230 219
231 start = 0; 220 start = 0;
@@ -239,7 +228,7 @@ void SubwayMap::OnPaint(wxPaintEvent &event) {
239 } else { 228 } else {
240 ellipse_y = top - halfheight; 229 ellipse_y = top - halfheight;
241 230
242 if (item1_y > item2_y) { 231 if (item1_pos.y > item2_pos.y) {
243 ellipse_x = left - halfwidth; 232 ellipse_x = left - halfwidth;
244 233
245 start = 270; 234 start = 270;
@@ -267,15 +256,10 @@ void SubwayMap::OnPaint(wxPaintEvent &event) {
267} 256}
268 257
269void SubwayMap::OnMouseMove(wxMouseEvent &event) { 258void SubwayMap::OnMouseMove(wxMouseEvent &event) {
270 int mouse_x = std::clamp( 259 wxPoint mouse_pos = RenderPosToMapPos(event.GetPosition());
271 (event.GetX() - render_x_) * map_image_.GetWidth() / render_width_, 260
272 0, map_image_.GetWidth() - 1);
273 int mouse_y = std::clamp(
274 (event.GetY() - render_y_) * map_image_.GetWidth() / render_width_,
275 0, map_image_.GetHeight() - 1);
276
277 std::vector<int> hovered = tree_->query( 261 std::vector<int> hovered = tree_->query(
278 {static_cast<float>(mouse_x), static_cast<float>(mouse_y), 2, 2}); 262 {static_cast<float>(mouse_pos.x), static_cast<float>(mouse_pos.y), 2, 2});
279 std::optional<int> new_hovered_item; 263 std::optional<int> new_hovered_item;
280 if (!hovered.empty()) { 264 if (!hovered.empty()) {
281 new_hovered_item = hovered[0]; 265 new_hovered_item = hovered[0];
@@ -369,10 +353,7 @@ void SubwayMap::Redraw() {
369 } 353 }
370 } 354 }
371 355
372 int real_area_x = 356 wxPoint real_area_pos = MapPosToRenderPos({subway_item.x, subway_item.y});
373 render_x_ + subway_item.x * render_width_ / image_size.GetWidth();
374 int real_area_y =
375 render_y_ + subway_item.y * render_width_ / image_size.GetWidth();
376 357
377 int real_area_size = 358 int real_area_size =
378 render_width_ * 359 render_width_ *
@@ -385,17 +366,31 @@ void SubwayMap::Redraw() {
385 if (draw_type == ItemDrawType::kBox) { 366 if (draw_type == ItemDrawType::kBox) {
386 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1)); 367 dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1));
387 dc.SetBrush(*brush_color); 368 dc.SetBrush(*brush_color);
388 dc.DrawRectangle({real_area_x, real_area_y}, 369 dc.DrawRectangle(real_area_pos,
389 {real_area_size, real_area_size}); 370 {real_area_size, real_area_size});
390 } else if (draw_type == ItemDrawType::kOwl) { 371 } else if (draw_type == ItemDrawType::kOwl) {
391 wxBitmap owl_bitmap = wxBitmap( 372 wxBitmap owl_bitmap = wxBitmap(
392 owl_image_.Scale(real_area_size, real_area_size, 373 owl_image_.Scale(real_area_size, real_area_size,
393 wxIMAGE_QUALITY_BILINEAR)); 374 wxIMAGE_QUALITY_BILINEAR));
394 dc.DrawBitmap(owl_bitmap, {real_area_x, real_area_y}); 375 dc.DrawBitmap(owl_bitmap, real_area_pos);
395 } 376 }
396 } 377 }
397} 378}
398 379
380
381wxPoint SubwayMap::MapPosToRenderPos(wxPoint pos) const {
382 return {pos.x * render_width_ / map_image_.GetSize().GetWidth() + render_x_,
383 pos.y * render_width_ / map_image_.GetSize().GetWidth() + render_y_};
384}
385
386wxPoint SubwayMap::RenderPosToMapPos(wxPoint pos) const {
387 return {
388 std::clamp((pos.x - render_x_) * map_image_.GetWidth() / render_width_, 0,
389 map_image_.GetWidth() - 1),
390 std::clamp((pos.y - render_y_) * map_image_.GetWidth() / render_width_, 0,
391 map_image_.GetHeight() - 1)};
392}
393
399quadtree::Box<float> SubwayMap::GetItemBox::operator()(const int& id) const { 394quadtree::Box<float> SubwayMap::GetItemBox::operator()(const int& id) const {
400 const SubwayItem &subway_item = GD_GetSubwayItem(id); 395 const SubwayItem &subway_item = GD_GetSubwayItem(id);
401 return {static_cast<float>(subway_item.x), static_cast<float>(subway_item.y), 396 return {static_cast<float>(subway_item.x), static_cast<float>(subway_item.y),
diff --git a/src/subway_map.h b/src/subway_map.h index 52d07b8..0d26d0b 100644 --- a/src/subway_map.h +++ b/src/subway_map.h
@@ -32,6 +32,9 @@ class SubwayMap : public wxPanel {
32 32
33 void Redraw(); 33 void Redraw();
34 34
35 wxPoint MapPosToRenderPos(wxPoint pos) const;
36 wxPoint RenderPosToMapPos(wxPoint pos) const;
37
35 wxImage map_image_; 38 wxImage map_image_;
36 wxImage owl_image_; 39 wxImage owl_image_;
37 wxBitmap unchecked_eye_; 40 wxBitmap unchecked_eye_;