我得到了一张图像,并在下面的图像中并排放置了几颗钻石

我在图像上知道的唯一坐标是顶角(绿色文本).
当我点击图像时,我得到了那个点的坐标,但是我无法得到我正在使用的那颗钻石.
例如,我点击红点,我怎么知道x:260,y:179 =顶级钻石?
蓝色属于左边?等等...
非常感谢您的帮助.
编辑:
我最终使用了Canvas,但我认为SVG可以用于我需要做的事情.
我看到两种可能的方法:直接检查一个点是否在钻石内并使用仿射变换.我将描述两者.
要确定某个点是否在钻石内,您必须检查其与钻石中点的偏差.你必须将X和Y偏差与钻石的X和Y范围成比例,你将得到两个因素.对于菱形内的所有点,这些因子的模数值之和小于或等于1.在代码中,这看起来像这样:
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");
Run Code Online (Sandbox Code Playgroud)
因此,您现在要做的就是确定每个钻石的中间点(大小在所有情况下都是相同的)并检查您测试的点是否位于它们内部.
工作示例:http://jsfiddle.net/z98hr/
使用仿射变换,您可以将顶部钻石的角坐标更改为(0,0),(1,0),(0,1)和(1,1).如果然后将相同的变换应用于您需要测试的点,则确定它所属的钻石变得微不足道.
首先,您需要一个平移向量来将(225,2)点移动到坐标原点.假设您有四个坐标确定您的顶部钻石(左右坐标,顶部和底部坐标):
var topDiamond = [[113, 2], [337, 227]];
Run Code Online (Sandbox Code Playgroud)
然后,将菱形顶点移动到零坐标的平移向量将是:
var translationVector = [-(topDiamond[0][0] + topDiamond[1][0]) / 2,
-topDiamond[0][1]];
Run Code Online (Sandbox Code Playgroud)
您可以将它应用于原始坐标,如下所示:
function add(vector1, vector2)
{
return [vector1[0] + vector2[0], vector1[1] + vector2[1]];
}
topDiamond = [add(topDiamond[0], translationVector),
add(topDiamond[1], translationVector)];
Run Code Online (Sandbox Code Playgroud)
然后你需要一个旋转矩阵:
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)]];
Run Code Online (Sandbox Code Playgroud)
在与该矩阵相乘之后,点(225,2)和(337,114.5)在X轴上对齐.但是你现在拥有的是一个空中飞人,你现在需要一个水平剪切变换来使钻石的另一侧在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]];
Run Code Online (Sandbox Code Playgroud)
与此矩阵相乘后,您现在有一个矩形.现在你只需要一个缩放矩阵来确保角的X和Y坐标的值为0和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]]];
Run Code Online (Sandbox Code Playgroud)
你有它,现在你可以将这些转换应用到任何一点:
alert(
multiply(scaleMatrix,
multiply(shearMatrix,
multiply(rotMatrix,
add(translationVector, [260, 179])
)
)
)
);
Run Code Online (Sandbox Code Playgroud)
这给你0.94,0.63- 两个值都在(0..1)范围内,意味着它是顶级钻石.随着[420,230]输入你1.88,0.14- X的(1..2)范围和Y 0..1范围是指正确的钻石.等等.
工作示例:http://jsfiddle.net/FzWHe/
在回顾展中,对于像钻石这样的简单几何图形来说,这可能太过分了.