You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何逆向推导交错Tile Map中由像素位置求瓦片位置的算法

Reverse Staggered Tile Map: Pixel Position to Tile Position

Got it, let's break down how to reverse this staggered tile map coordinate conversion step by step. First, let's recap what the original algorithm does so we're clear on exactly what we need to undo:

Original algorithm (tile to pixel):

float diffX = 0; 
if ((int)tilePos.y % 2 == 1) diffX = tileSize.width / 2; 
return Vec2 ( tilePos.x * tileSize.width + diffX, (mapSize.height - tilePos.y - 1) * tileSize.height / 2); 

Key Observations from the Original Code

  • Y-axis: Tile Y positions are mapped from bottom-to-top (since mapSize.height - tilePos.y - 1 flips the vertical direction), and each tile takes up half its full height in pixel space.
  • X-axis: Odd-numbered tile rows (Y is odd) are offset right by half a tile width; even rows have no offset.

Step-by-Step Reverse Calculation

1. First Solve for tilePos.y

The Y calculation doesn't depend on X, so we start here. Rearrange the original Y formula:
Original: pixelY = (mapSize.height - tilePos.y - 1) * (tileSize.height / 2)

Rearranged to solve for tilePos.y:

tilePos.y = mapSize.height - 1 - (pixelY / (tileSize.height / 2))

We cast the result to an integer because tile positions are discrete—this effectively truncates (floors) the value, which correctly maps the pixel Y to its corresponding tile row.

2. Adjust Pixel X and Solve for tilePos.x

Since X depends on whether tilePos.y is odd/even, we first use the tilePos.y we just calculated to adjust the pixel X:

  • If tilePos.y is odd: Subtract half the tile width from the pixel X to undo the original offset.
  • If even: No adjustment needed.

Then reverse the original X formula (pixelX = tilePos.x * tileSize.width + diffX):

tilePos.x = adjustedPixelX / tileSize.width

Again, cast to an integer to get the discrete tile column.


Full Reverse Algorithm Code

Here's the code implementing this logic, matching the style of the original snippet:

Vec2 pixelToTilePos(Vec2 pixelPos, Vec2 tileSize, Vec2 mapSize) {
    // Calculate tile Y first (since X depends on Y's parity)
    float halfTileHeight = tileSize.height / 2.0f;
    int tileY = mapSize.height - 1 - static_cast<int>(pixelPos.y / halfTileHeight);
    
    // Adjust pixel X based on tile Y's parity
    float adjustedPixelX = pixelPos.x;
    if (tileY % 2 == 1) {
        adjustedPixelX -= tileSize.width / 2.0f;
    }
    
    // Calculate tile X
    int tileX = static_cast<int>(adjustedPixelX / tileSize.width);
    
    // Optional: Clamp values to valid map bounds to avoid out-of-bounds tiles
    tileX = std::max(0, std::min(tileX, static_cast<int>(mapSize.width) - 1));
    tileY = std::max(0, std::min(tileY, static_cast<int>(mapSize.height) - 1));
    
    return Vec2(tileX, tileY);
}

Notes

  • Integer Truncation: Using static_cast<int> works here because we're dealing with positive coordinates (assuming your pixel origin is top-left or bottom-left as standard). If you have negative coordinates, use std::floor() instead to ensure correct truncation.
  • Bounds Clamping: The optional clamp step ensures you don't get tile positions outside the map's dimensions—this is a good safety measure, but you can omit it if you're confident input pixels are always within the map.

内容的提问来源于stack exchange,提问作者Eugene Lim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:59:34