Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/426.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 查找离单击点最近的元素_Javascript_Jquery_Algorithm_Math_Nearest Neighbor - Fatal编程技术网

Javascript 查找离单击点最近的元素

Javascript 查找离单击点最近的元素,javascript,jquery,algorithm,math,nearest-neighbor,Javascript,Jquery,Algorithm,Math,Nearest Neighbor,这里需要帮助。我是一个UI设计师,不擅长做实验性的web表单设计,我需要知道哪个输入元素最接近网页上的点击点。我知道如何用点做最近邻,但输入元素是矩形而不是点,所以我被卡住了 我正在使用jQuery。我只需要帮我做这个小算法。一旦我做完实验,我会告诉你们我在做什么 更新 我在想它是如何工作的。请看这个图表: 每个矩形有8个点(或者更确切地说是4个点和4条线),它们是有意义的。只有x值对水平点(红点)有效,只有y值对垂直点(绿点)有效。x和y对角都很重要 橙色十字是我的用例中鼠标点击的测量点。浅

这里需要帮助。我是一个UI设计师,不擅长做实验性的web表单设计,我需要知道哪个输入元素最接近网页上的点击点。我知道如何用点做最近邻,但输入元素是矩形而不是点,所以我被卡住了

我正在使用jQuery。我只需要帮我做这个小算法。一旦我做完实验,我会告诉你们我在做什么

更新

我在想它是如何工作的。请看这个图表:

每个矩形有8个点(或者更确切地说是4个点和4条线),它们是有意义的。只有x值对水平点(红点)有效,只有y值对垂直点(绿点)有效。x和y对角都很重要

橙色十字是我的用例中鼠标点击的测量点。浅紫色线是橙色十字和可能最近点之间的距离

所以…对于任何给定的橙色十字,在每个矩形的8个点中循环,以找到每个矩形最接近橙色十字的最近边或角。值最小的矩形是最近的矩形


我可以将其概念化和可视化,但不能将其转化为代码。救命啊

您可以查找所有矩形中最近的角点。这在大多数情况下都有效,而且快速且易于实现。只要矩形在规则网格上对齐,此方法将为您提供最接近的矩形。

我的方法不是使用数字,而是使用逻辑

我假设你想得到这样的结果,“如果x是最近的元素,那么当我点击其他地方时,做些什么,然后对x做些什么”

如果要处理的每个元素都位于简单的
容器中,该容器比要处理的元素大,但不超过它所包含的对象和它的下一个最近对象之间的一半,则可以执行此操作。实际上是一个网格

将所有容器设为同一类

然后,您可以说,“如果单击y,则对x执行某些操作”,您将已经知道每个容器中有哪个元素


我将编写代码,但我将离开工作…

如果您想在二维网格上查找两点之间的距离,可以使用以下公式:

(对于二维点A和B)

距离x=A.x-B.x

距离y=A.y-B.y

总距离=平方根((distX*distX)+(distY*distY))


一旦你可以检查两点之间的距离,你就可以很容易地找出你鼠标点击的哪个矩形角是最近的。你可以做很多事情来优化你想要的算法,但这应该给你一个好的开始。

哈哈,问题是你为什么要考虑形状? 你的问题实际上是“如果我点击一个坐标,找到离我点击最近的节点/点”,这是一个遍历各个节点并计算距离的问题

如果X相同,则使用y差

如果y相同,则使用x差

否则使用抵押权

一旦找到最近的点,就可以得到正确的父图形?
这将起作用,因为您正在尝试捕捉到最近的点。因此,它甚至可以处理像星星这样的奇特形状。

您的算法是正确的。因为您需要的是代码方面的帮助,而不是算法方面的帮助,下面是代码:

它可能不是最有效的。但它是有效的

// Define the click
var click = Array(-1, -2); // coodinates in x,y

// Define the buttons
// Assuming buttons do not overlap
var button0 = Array(
    Array(0, 0), // bottom-left point (assuming x is horizontal and y is vertical)
    Array(6, 6) // upper-right point
);

var button1 = Array(
    Array(10, 11),
    Array(17, 15)
);

var button2 = Array(
    Array(-8, -5),
    Array(-3, -1)
);

// Which button to trigger for a click
i = which(click, Array(button0, button1, button2));
alert(i);


function which(click, buttons){
    // Check if click is inside any of the buttons
    for (i in buttons){
        var button = buttons[i];
        var bl = button[0];
        var tr = button[1];

        if ( (click[0] >= bl[0] && click[0] <= tr[0]) &&
             (click[1] >= bl[1] && click[1] <= tr[1]) ){
            return i;
        }
    }

    // Now calculate distances
    var distances = Array();

    for (i in buttons){
        var button = buttons[i];
        var bl = button[0];
        var tr = button[1];

        if ( (click[0] >= bl[0] && click[0] <= tr[0])) {
            distances[i] = Math.min( Math.abs(click[1]-bl[1]), Math.abs(click[1]-tr[1]) );
        }
        else if ( (click[1] >= bl[1] && click[1] <= tr[1])) {
            distances[i] = Math.min( Math.abs(click[0]-bl[0]), Math.abs(click[0]-tr[0]) );
        }
        else{
            distances[i] =  Math.sqrt(
                                (Math.pow(Math.min( Math.abs(click[0]-bl[0]), Math.abs(click[0]-tr[0]) ), 2)) +
                                (Math.pow(Math.min( Math.abs(click[1]-bl[1]), Math.abs(click[1]-tr[1]) ), 2))
                            );
        }
    }

    var min_id = 0;
    for (j in distances){
        if (distances[j] < distances[min_id]){
            min_id = j;
        }
    }

    return min_id;
}
//定义单击
var click=Array(-1,-2);//x,y中的坐标
//定义按钮
//假设按钮不重叠
var button0=数组(
数组(0,0),//左下角点(假设x是水平的,y是垂直的)
数组(6,6)//右上角点
);
var button1=数组(
阵列(10,11),
阵列(17,15)
);
var button2=数组(
阵列(-8,-5),
数组(-3,-1)
);
//单击要触发哪个按钮
i=哪个(单击,数组(按钮0,按钮1,按钮2));
警报(一);
功能(单击、按钮){
//检查单击是否在任何按钮内
用于(按钮中的i){
var按钮=按钮[i];
var bl=按钮[0];
var tr=按钮[1];

如果((单击[0]>=bl[0]&&click[0]=bl[1]&&click[1]=bl[0]&&click[0]=bl[1]&&click[1]相对新的API的添加让我们可以采取另一种可能更轻的方法:我们可以围绕鼠标光标点击test,在更大的圆圈中进行,直到找到最近的元素

我在这里总结了一个快速的非生产性示例:(Chrome/Safari只是因为使用了WebKitMatcheSelector)。由于在可视化算法时使用了点,性能可能会变得滞后

除了轻型性能优化和事件绑定之外,代码的核心是:

function hitTest(x, y){
    var element, i = 0;
    while (!element){
        i = i + 7; // Or some other threshold.

        if (i > 250){ // We do want some safety belts on our while loop.
            break;
        }

        var increment = i/Math.sqrt(2);
        var points = [
            [x-increment, y-increment], [x+increment, y-increment],
            [x+increment, y+increment], [x-increment, y+increment]
        ];

        // Pop additional points onto the stack as the value of i gets larger.
        // ...

        // Perhaps prematurely optimized: we're using Array.prototype.some to bail-out
        // early once we've found a valid hit target.
        points.some(function(coordinates){
            var hit = document.elementFromPoint.apply(document, coordinates); 
            // isValidHit() could simply be a method that sees whether the current
            // element matches the kinds of elements we'd like to see.
            if (isValidHit(hit)){
                element = hit;
                return true;
            }
       });
}

在最近邻算法中使用表示矩形的4个点。或者使用矩形的中心点cx=(左+宽)/2,cy=(顶+高)/2.你有没有可能在jsfiddle.net中发布一些代码或做点什么?这都是假设的,否则…添加了一个说明来解释问题以及如何解决。太好了。这正是我需要的。我如何使代码适应任何宽度和高度?它适应任何宽度和高度。你只需要定义尺寸JavaScript顶部的按钮和点击坐标。