From a2b67cf27dbd41bcfa75835e36c605adfc040e40 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sat, 18 May 2024 15:33:30 -0400 Subject: Coordinate transformation functions --- src/subway_map.cpp | 99 ++++++++++++++++++++++++++---------------------------- src/subway_map.h | 3 ++ 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) { int item_width = col_width + 10 + 32; int full_width = item_width + 20; - int popup_x = (subway_item.x + AREA_ACTUAL_SIZE / 2) * render_width_ / - map_image_.GetWidth() + - render_x_; - int popup_y = (subway_item.y + AREA_ACTUAL_SIZE / 2) * render_width_ / - map_image_.GetWidth() + - render_y_; - - if (popup_x + full_width > GetSize().GetWidth()) { - popup_x = GetSize().GetWidth() - full_width; + wxPoint popup_pos = + MapPosToRenderPos({subway_item.x + AREA_ACTUAL_SIZE / 2, + subway_item.y + AREA_ACTUAL_SIZE / 2}); + + if (popup_pos.x + full_width > GetSize().GetWidth()) { + popup_pos.x = GetSize().GetWidth() - full_width; } - if (popup_y + acc_height > GetSize().GetHeight()) { - popup_y = GetSize().GetHeight() - acc_height; + if (popup_pos.y + acc_height > GetSize().GetHeight()) { + popup_pos.y = GetSize().GetHeight() - acc_height; } dc.SetPen(*wxTRANSPARENT_PEN); dc.SetBrush(*wxBLACK_BRUSH); - dc.DrawRectangle({popup_x, popup_y}, {full_width, acc_height}); + dc.DrawRectangle(popup_pos, {full_width, acc_height}); dc.SetFont(GetFont()); @@ -168,14 +165,15 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { for (const auto& [text, obtained] : report) { wxBitmap *eye_ptr = obtained ? &unchecked_eye_ : &checked_eye_; - dc.DrawBitmap(*eye_ptr, {popup_x + 10, popup_y + cur_height}); + dc.DrawBitmap(*eye_ptr, popup_pos + wxPoint{10, cur_height}); dc.SetTextForeground(obtained ? *wxWHITE : *wxRED); wxSize item_extent = dc.GetTextExtent(text); dc.DrawText( text, - {popup_x + 10 + 32 + 10, - popup_y + cur_height + (32 - dc.GetFontMetrics().height) / 2}); + popup_pos + + wxPoint{10 + 32 + 10, + cur_height + (32 - dc.GetFontMetrics().height) / 2}); cur_height += 10 + 32; } @@ -189,43 +187,34 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { const SubwayItem &item1 = GD_GetSubwayItem(item_id1); const SubwayItem &item2 = GD_GetSubwayItem(item_id2); - int item1_x = (item1.x + AREA_ACTUAL_SIZE / 2) * render_width_ / - map_image_.GetWidth() + - render_x_; - int item1_y = (item1.y + AREA_ACTUAL_SIZE / 2) * render_width_ / - map_image_.GetWidth() + - render_y_; - - int item2_x = (item2.x + AREA_ACTUAL_SIZE / 2) * render_width_ / - map_image_.GetWidth() + - render_x_; - int item2_y = (item2.y + AREA_ACTUAL_SIZE / 2) * render_width_ / - map_image_.GetWidth() + - render_y_; - - int left = std::min(item1_x, item2_x); - int top = std::min(item1_y, item2_y); - int right = std::max(item1_x, item2_x); - int bottom = std::max(item1_y, item2_y); + wxPoint item1_pos = MapPosToRenderPos( + {item1.x + AREA_ACTUAL_SIZE / 2, item1.y + AREA_ACTUAL_SIZE / 2}); + wxPoint item2_pos = MapPosToRenderPos( + {item2.x + AREA_ACTUAL_SIZE / 2, item2.y + AREA_ACTUAL_SIZE / 2}); + + int left = std::min(item1_pos.x, item2_pos.x); + int top = std::min(item1_pos.y, item2_pos.y); + int right = std::max(item1_pos.x, item2_pos.x); + int bottom = std::max(item1_pos.y, item2_pos.y); int halfwidth = right - left; int halfheight = bottom - top; if (halfwidth < 4 || halfheight < 4) { dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 4)); - dc.DrawLine(item1_x, item1_y, item2_x, item2_y); + dc.DrawLine(item1_pos, item2_pos); dc.SetPen(*wxThePenList->FindOrCreatePen(*wxCYAN, 2)); - dc.DrawLine(item1_x, item1_y, item2_x, item2_y); + dc.DrawLine(item1_pos, item2_pos); } else { int ellipse_x; int ellipse_y; double start; double end; - if (item1_x > item2_x) { + if (item1_pos.x > item2_pos.x) { ellipse_y = top; - if (item1_y > item2_y) { + if (item1_pos.y > item2_pos.y) { ellipse_x = left - halfwidth; start = 0; @@ -239,7 +228,7 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { } else { ellipse_y = top - halfheight; - if (item1_y > item2_y) { + if (item1_pos.y > item2_pos.y) { ellipse_x = left - halfwidth; start = 270; @@ -267,15 +256,10 @@ void SubwayMap::OnPaint(wxPaintEvent &event) { } void SubwayMap::OnMouseMove(wxMouseEvent &event) { - int mouse_x = std::clamp( - (event.GetX() - render_x_) * map_image_.GetWidth() / render_width_, - 0, map_image_.GetWidth() - 1); - int mouse_y = std::clamp( - (event.GetY() - render_y_) * map_image_.GetWidth() / render_width_, - 0, map_image_.GetHeight() - 1); - + wxPoint mouse_pos = RenderPosToMapPos(event.GetPosition()); + std::vector hovered = tree_->query( - {static_cast(mouse_x), static_cast(mouse_y), 2, 2}); + {static_cast(mouse_pos.x), static_cast(mouse_pos.y), 2, 2}); std::optional new_hovered_item; if (!hovered.empty()) { new_hovered_item = hovered[0]; @@ -369,10 +353,7 @@ void SubwayMap::Redraw() { } } - int real_area_x = - render_x_ + subway_item.x * render_width_ / image_size.GetWidth(); - int real_area_y = - render_y_ + subway_item.y * render_width_ / image_size.GetWidth(); + wxPoint real_area_pos = MapPosToRenderPos({subway_item.x, subway_item.y}); int real_area_size = render_width_ * @@ -385,17 +366,31 @@ void SubwayMap::Redraw() { if (draw_type == ItemDrawType::kBox) { dc.SetPen(*wxThePenList->FindOrCreatePen(*wxBLACK, 1)); dc.SetBrush(*brush_color); - dc.DrawRectangle({real_area_x, real_area_y}, + dc.DrawRectangle(real_area_pos, {real_area_size, real_area_size}); } else if (draw_type == ItemDrawType::kOwl) { wxBitmap owl_bitmap = wxBitmap( owl_image_.Scale(real_area_size, real_area_size, wxIMAGE_QUALITY_BILINEAR)); - dc.DrawBitmap(owl_bitmap, {real_area_x, real_area_y}); + dc.DrawBitmap(owl_bitmap, real_area_pos); } } } + +wxPoint SubwayMap::MapPosToRenderPos(wxPoint pos) const { + return {pos.x * render_width_ / map_image_.GetSize().GetWidth() + render_x_, + pos.y * render_width_ / map_image_.GetSize().GetWidth() + render_y_}; +} + +wxPoint SubwayMap::RenderPosToMapPos(wxPoint pos) const { + return { + std::clamp((pos.x - render_x_) * map_image_.GetWidth() / render_width_, 0, + map_image_.GetWidth() - 1), + std::clamp((pos.y - render_y_) * map_image_.GetWidth() / render_width_, 0, + map_image_.GetHeight() - 1)}; +} + quadtree::Box SubwayMap::GetItemBox::operator()(const int& id) const { const SubwayItem &subway_item = GD_GetSubwayItem(id); return {static_cast(subway_item.x), static_cast(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 { void Redraw(); + wxPoint MapPosToRenderPos(wxPoint pos) const; + wxPoint RenderPosToMapPos(wxPoint pos) const; + wxImage map_image_; wxImage owl_image_; wxBitmap unchecked_eye_; -- cgit 1.4.1