veo dos enfoques posibles: comprobación directa si un punto está dentro de un diamante y utilizando transformaciones afines. Describiré ambos.
posición del punto de verificación directa
Para determinar si un punto está dentro de un diamante que usted tiene que comprobar su desviación desde el punto medio de un diamante. Tienes que poner las desviaciones X e Y en proporción con las extensiones X e Y del diamante, obtendrás dos factores. Para todos los puntos dentro del diamante, la suma de los valores del módulo para estos factores es menor o igual a 1.En el código de este se ve así:
var dx = Math.abs(coords[0] - middle[0]);
var dy = Math.abs(coords[1] - middle[1]);
if (dx/size[0] + dy/size[1] <= 1)
alert("Inside diamond");
else
alert("Outside diamond");
Así que todo lo que tiene que hacer ahora es determinar el punto medio de cada diamante (el tamaño es el mismo en todos los casos) y comprobar si el punto que se está probando se encuentra dentro de ellos .
Ejemplo de trabajo: http://jsfiddle.net/z98hr/
afín transformaciones
Usando affine transformations puede cambiar las coordenadas de las esquinas de su diamante en la parte superior (0,0), (1,0), (0,1) y (1,1). Si luego aplicas la misma transformación al punto que necesitas probar, determinar a qué diana pertenece se vuelve trivial.
Primero necesitará un vector de traducción para mover el punto (225,2) al origen de las coordenadas. Digamos que usted tiene cuatro coordenadas que determinan su diamante superior (izquierda y derecha de coordenadas, la parte superior y coordinar inferior):
var topDiamond = [[113, 2], [337, 227]];
Entonces el translation vector para mover el punto superior del diamante al cero de coordenadas serían:
var translationVector = [-(topDiamond[0][0] + topDiamond[1][0])/2,
-topDiamond[0][1]];
se puede aplicar a las coordenadas originales como esta:
function add(vector1, vector2)
{
return [vector1[0] + vector2[0], vector1[1] + vector2[1]];
}
topDiamond = [add(topDiamond[0], translationVector),
add(topDiamond[1], translationVector)];
entonces necesitará un rotation matrix:
var angle = -Math.atan2(topDiamond[1][1] - topDiamond[0][1],
topDiamond[1][0] - topDiamond[0][0]);
var rotMatrix = [[Math.cos(angle), -Math.sin(angle)],
[Math.sin(angle), Math.cos(angle)]];
Después de la multiplicación con esta matriz, los puntos (225,2) y (337,114.5) se alinean en el eje X. Pero lo que tenemos ahora es un trapecio, ahora tiene un horizontal shear transformation para llegar al otro lado del diamante alineados en el eje Y:
function multiply(matrix, vector)
{
return [matrix[0][0] * vector[0] + matrix[0][1] * vector[1],
matrix[1][0] * vector[0] + matrix[1][1] * vector[1]];
}
var point = [topDiamond[0][0], (topDiamond[0][1] + topDiamond[1][1])/2];
point = multiply(rotMatrix, point);
var shearMatrix = [[1, -point[0]/point[1]], [0, 1]];
Después de la multiplicación con esta matriz tiene un rectángulo ahora. Ahora sólo necesita un scaling matrix para asegurarse de que la coordenadas X e Y de las esquinas tienen el valor 0 y 1:
point = multiply(shearMatrix, point);
var point2 = [topDiamond[1][0], (topDiamond[0][1] + topDiamond[1][1])/2];
point2 = multiply(rotMatrix, point2);
point2 = multiply(shearMatrix, point2);
var scaleMatrix = [[1/point2[0], 0], [0, 1/point[1]]];
Y ahí lo tienes, ahora se puede aplicar estas transformaciones a cualquier punto:
alert(
multiply(scaleMatrix,
multiply(shearMatrix,
multiply(rotMatrix,
add(translationVector, [260, 179])
)
)
)
);
Esto le da 0.94,0.63
- ambos valores están en la gama (0..1)
, lo que significa que es el diamante superior. Con [420,230]
como entrada obtienes 1.88,0.14
- X en (1..2)
rango y Y en 0..1
rango significa diamante derecho. Y así.
Ejemplo de trabajo: http://jsfiddle.net/FzWHe/
En la retrospectiva, esto era probablemente demasiado trabajo para una simple figura geométrica como un diamante.
¿Y qué tiene que ver con Javascript y jQuery? Esto es solo matemática. – MaxArt
Lo siento, porque lo hago en jquery, pero cierto no me concierne. Edité – Shadowbob
Su imagen coloca el punto verde en el diamante inferior, pero las coordenadas corresponden al diamante correcto. Además, las coordenadas del punto azul lo colocan más cerca del borde del diamante inferior. –