Primero, aquí está el código. Seguirá una explicación:
/*
* tw, th contain the tile width and height.
*
* hitTest contains a single channel taken from a tile-shaped hit-test
* image. Data was extracted with getImageData()
*/
worldToTilePos = function(x, y) {
var eventilex = Math.floor(x%tw);
var eventiley = Math.floor(y%th);
if (hitTest[eventilex + eventiley * tw] !== 255) {
/* On even tile */
return {
x: Math.floor((x + tw) / tw) - 1,
y: 2 * (Math.floor((y + th) / th) - 1)
};
} else {
/* On odd tile */
return {
x: Math.floor((x + tw / 2) / tw) - 1,
y: 2 * (Math.floor((y + th / 2) / th)) - 1
};
}
};
Tenga en cuenta que este código no funcionará para el mapa que se muestra en su pregunta. Esto se debe a que los mosaicos impares se desplazan hacia la izquierda, mientras que el mosaico impar generalmente se desplaza hacia la derecha (como es el caso en el editor de mapas en mosaico ). Debería poder remediarlo fácilmente ajustando el valor x devuelto en el caso de mosaico impar.
Explicación
Esto puede parecer un método un poco más de fuerza bruta para lograr esta tarea, pero al menos tiene la ventaja de ser un píxel perfecto y un poco más flexible.
El truco consiste en ver el mapa no como una cuadrícula escalonada única, sino como dos cuadrículas superpuestas una encima de la otra. Existe la cuadrícula de filas impares y la cuadrícula de filas pares, pero en su lugar los llamamos rojo y verde para que podamos crear un diagrama bonito ...
Observe a la derecha de esa imagen que he marcado un punto con un punto morado. Este es el punto de ejemplo que intentaremos encontrar en nuestro espacio de mosaico original.
Lo que debe notarse sobre cualquier punto del mundo es que siempre se ubicará exactamente en dos regiones: una roja y una verde (a menos que esté en un borde, pero de todos modos es probable que se recorte dentro del límite de borde irregular). Encontremos esas regiones ...
Ahora para elegir cuál de las dos regiones es la correcta. Siempre habrá exactamente una respuesta.
Desde aquí podríamos hacer una aritmética más simple y calcular la distancia al cuadrado desde nuestro punto de muestra a cada punto central de las dos regiones. Cualquiera que sea el más cercano será nuestra respuesta.
Sin embargo, hay una forma alternativa. Para cada región de prueba, tomamos muestras de un mapa de bits que coincide con la forma exacta de nuestros mosaicos. Lo muestreamos en un punto traducido a coordenadas locales para ese mosaico único. Para nuestro ejemplo, se vería así:
A la izquierda, verificamos la región verde y obtenemos un hit (píxel negro). A la derecha probamos la región roja y obtenemos una falla (píxel blanco). La segunda prueba es, por supuesto, redundante, ya que siempre será exactamente una u otra, nunca ambas.
Luego llegamos a la conclusión de que tenemos un golpe en el mosaico impar en 1,1. Esta coordenada debería ser simple de mapear a las coordenadas del mosaico original usando una transformación diferente para las filas pares e impares.
Este método también le permite tener propiedades simples por píxel en los mapas de bits de prueba de píxeles. Por ejemplo, el blanco es un mosaico, el negro es un éxito, el azul es agua, el rojo es sólido.