Согласно приложенному рисунку мы связали 4 области с заданной геометрией. Приведено количество клеток в горизонтальном и вертикальном направлении. Ширина и высота ячейки также определены. Так что почти все известно, чтобы вычислить, где, в какой части и какой ячейке мы находимся для данной координаты.
Чтобы упростить жизнь, мы определяем 4 части (которые равны) в структуре. Затем мы можем определить поля и общие позиции каждой ячейки.
По сути, нам нужно сделать много вычислений. Сначала проверьте, в какой части мы находимся, затем проверьте, в какой ячейке мы находимся, а затем вычислите общее число ячеек, зависящее от локальных результатов.
Пожалуйста, см. Ниже одно из многих возможных решений:
#include <iostream>
#include <vector>
#include <utility>
constexpr double CellWidth = 35.0;
constexpr double CellHeight = 32.0;
constexpr double OffsetLeft = 22.0;
constexpr double OffsetTop = 20.0;
constexpr double SpaceHorizontal = 60.0;
constexpr double SpaceVertical = 50.0;
constexpr unsigned int TileNumberOfRows = 17U;
constexpr unsigned int TileNumberOfColumns = 10U;
constexpr unsigned int NumberOfTilesHorizontal = 2;
constexpr unsigned int NumberOfTilesVertical = 2;
struct Tile {
Tile(unsigned int tn);
std::pair<bool, unsigned int> getCellNumber(const double x, const double y) const;
unsigned int tileNumber{};
double posLeft{};
double posTop{};
double posRight{};
double posBottom{};
};
// tielnumer starting with 0. From left to right, then next row
Tile::Tile(unsigned int tn) : tileNumber(tn) {
// Calculate the index of the tile
unsigned int tileIndexX = tileNumber % NumberOfTilesHorizontal;
unsigned int tileIndexY = tileNumber / NumberOfTilesVertical;
// Calculate X position of tile
posLeft =
// Left margin to paper
OffsetLeft // - (CellWidth / 2.0) // Unclear if this is the full offset or if we need to substract half the width
// Depending on the number of tiles
+ tileIndexX * (
// Tile Width
TileNumberOfColumns * CellWidth +
// Horizontal distance to next tile
SpaceHorizontal - (CellWidth / 2.0)
);
// Calculate Y position of tile
posTop =
// Top Margin to paper
OffsetTop // - (CellHight / 2.0) // Unclear if this is the full offset or if we need to substract half the height
// Depending on the number of tiles
+ tileIndexY * (
// Tile height
TileNumberOfRows * CellHeight +
// Vetical distance to next tile
SpaceVertical - (CellHeight / 2.0));
// Right position of tile
posRight = posLeft + TileNumberOfColumns * CellWidth;
// Bottom position of tile
posBottom = posTop + TileNumberOfRows * CellHeight;
}
// Check, if in pos is in tile and at what position
std::pair<bool, unsigned int> Tile::getCellNumber(const double x, const double y) const {
unsigned int cellNumber{ 0 };
// Is the position in range of this tile?
const bool inTile{ (x >= posLeft) && (x <= posRight) && (y > posTop) && (y < posBottom) };
// If so
if (inTile) {
// Calculate row in local tile
unsigned int col = static_cast<unsigned int>((x - posLeft) / CellWidth +
((tileNumber % NumberOfTilesHorizontal) * TileNumberOfColumns));
// Calculate col in local tile
unsigned int row = static_cast<unsigned int>((y - posTop) / CellHeight +
((tileNumber / NumberOfTilesVertical) * TileNumberOfRows));
// And now calculate the overall cell Number
cellNumber = row * TileNumberOfColumns* NumberOfTilesHorizontal + col;
}
return std::make_pair(inTile, cellNumber);
}
int main(void) {
const std::vector<Tile> tiles{ Tile(0),Tile(1),Tile(2),Tile(3) };
// Test values
const double x{ 740 };
const double y{ 1100 };
// Check cell number
for (const Tile& tile : tiles) {
if (const auto [isInTile, cellNumber] = tile.getCellNumber(x, y); isInTile) {
std::cout << "\nTilenumber: " << cellNumber << "\n";
}
}
return 0;
}