简体   繁体   English

画线JavaScript的循环逻辑

[英]Loop logic for drawing line javascript

I have following two arrays: 我有以下两个数组:

var element_1 = new Array([x1,y1],[x2,y2],[x3,y3],[x4,y4]);
var element_2 = new Array([x1,y1],[x2,y2],[x3,y3],[x4,y4]);

Logic: I want to run a loop (nested) where each element of element_1 (for eg [x1,y1] ) is compared to each element of element_2 and the shortest distance between them shall be calculated within the loop (I know how to calculate the shortest path). 逻辑:我想运行一个循环(嵌套),其中将element_1每个元素(例如[x1,y1] )与element_2每个元素进行比较,并且应在循环内计算它们之间的最短距离 (我知道如何计算最短路径)。 The tricky part here is that I need a reference that which pair made the shortest past and then obtain those [x1,y1] and [x2,y2] combinations to draw a line. 这里最棘手的部分是,我需要一个参考,该参考对使配对最短,然后获得那些[x1,y1][x2,y2]组合以画一条线。

Sample data: 样本数据:

var element_1 = new Array([10,0],[20,10],[10,20],[0,10]);
var element_2 = new Array([10,30],[20,40],[10,50],[0,40]);

Line should be made between [10,20] and [10,30]. 线应该在[10,20]和[10,30]之间。 Also, I would somehow need to store the coordinates somewhere to pass it to the line drawing function 此外,我将以某种方式需要将坐标存储在某处以将其传递给线条绘制函数

How can I do this? 我怎样才能做到这一点? Any leads would be highly appreciated. 任何线索将不胜感激。

Here is how I would do it: 这是我的方法:

 var element_1 = [[0,0],[1,2],[5,3],[6,8]]; var element_2 = [[0,1],[1,4],[5,9],[9,8]]; var closest = {a: false, b: false, distance: false}; for(var i=0; i<element_1.length; i++) { for(var j=0; j<element_2.length; j++) { var distance = calculate_distance(element_1[i], element_2[j]); console.log('Distance between element_1['+i+'] and element_2['+j+']: ' + distance); if(closest.distance === false || distance < closest.distance) { closest = {a: element_1[i], b: element_2[j], distance: distance}; } } } console.log('The shortest path is between '+closest.a+' and '+closest.b+', which is '+closest.distance); function calculate_distance(a, b) { var width = Math.abs( a[0] - b[0] ), height = Math.abs( a[1] - b[1] ), hypothenuse = Math.sqrt( width*width + height*height ); return hypothenuse; } 

As Roko C. Buljan said, in your case you can just replace new Array() with [] . 正如Roko C. Buljan所说,在您的情况下,您可以只用[]替换new Array() Here's why . 这就是为什么

Well i liked this question a lot. 好吧,我非常喜欢这个问题。 It inspired me to invent a generic Array method to apply a callback with each other items of two arrays. 它启发了我发明一个通用的Array方法,以对两个数组中的每个其他项应用回调。 So i called it Array.prototype.withEachOther() . 所以我称它为Array.prototype.withEachOther() What it does is exactly what @blex has done in his solution with nested for loops. 它确实是@blex在嵌套的for循环解决方案中所做的。 It applies an operation (provided by the callback) to each array item with the other array's item. 它将操作(由回调提供)应用于每个数组项以及另一个数组的项。 Let's see how it works. 让我们看看它是如何工作的。

 Array.prototype.withEachOther = function(a,cb,s=0){ return this.reduce((p,et) => a.reduce((q,ea) => cb(et,ea,q),p),s); }; var element_1 = [[10,0],[20,10],[10,20],[0,10]], element_2 = [[10,30],[20,40],[10,50],[0,40]], cb = (p1,p2,q) => {var h = Math.hypot(p1[0]-p2[0],p1[1]-p2[1]); return h < qd ? {d:h,p1:p1,p2:p2} : q}, minDist = element_1.withEachOther(element_2,cb,{d:Number.MAX_SAFE_INTEGER,p1:[],p2:[]}); console.log(minDist); 

So let's explain what's going on. 因此,让我们解释发生了什么。

Array.prototype.withEachOther = function(a,cb,s=0){
  return this.reduce((p,et) => a.reduce((q,ea) => cb(et,ea,q),p),s);
};

is a reusable function. 是可重用的功能。 It will execute the operation that is provided in a callback function, with each other element of the two arrays. 它将与两个数组中的其他每个元素一起执行回调函数中提供的操作。 It takes 3 arguments (a,cb,s=0) . 它需要3个参数(a,cb,s=0)

  • a is the second array that we will apply our callback to each item for each item of the array that is invoking .withEachOther . a是第二个数组,我们将对每个调用.withEachOther的数组的每个项应用回调。
  • cb is the callback. cb是回调。 Below I will explain the callback applied specific for this problem . 下面,我将解释专门针对此问题的回调。
  • s=0 is the initial (with a default value of 0) value that we will start with. s=0是我们将开始使用的初始值(默认值为0)。 It can be anything depending on the callback function. 它可以是任何东西,具体取决于回调函数。

return this.reduce((p,et) => a.reduce((q,ea) => cb(et,ea,q),p),s);

this part is the core of the function. 这部分是功能的核心。 As you see it has two nested reduces. 如您所见,它有两个嵌套的reduces。 The outer reduce has an initial value designated by the s , which is provided as explained above. 外部reduce具有由s表示的初始值,该初始值如上所述提供。 The initial value gets initially assigned to the p argument of the outer reduce's callback and the other argument et is assigned one by one with each of the items of invoking array. 初始值最初分配给外部reduce的回调的p参数,另一个参数et与调用数组的每个项一个一分配。 ( e lement of t his). (T他的电子字元素)。 In the outer reduce we invoke another reduce (the inner reduce). 在外部Reduce中,我们调用另一个Reduce(内部Reduce)。 The inner reduce starts with the initial value of the result of previous loop which is the p of outer reduce and after each calculation returns the result to it's reduced value variable q . 内部约简从上一个循环结果的初始值开始,即外部约简的p ,并在每次计算后将结果返回到其减少值变量q q is our memory and tested in the callback to see if we keep it as it is or replace it with the result of our calculation. q是我们的内存,并在回调中进行了测试,以查看是否保持原样或将其替换为计算结果。 After inner reduce finishes a complete round it will return the q to p and the same mechanism will run again until we finish with all items of the array that's invoking .withEachOther . 内部reduce完成一轮完整处理后,它将q返回p ,并且相同的机制将再次运行,直到我们完成调用.withEachOther的数组的所有项目.withEachOther

cb = (p1,p2,q) => {var h = Math.hypot(p1[0]-p2[0],p1[1]-p2[1]);
                   return h < q.d ? {d:h,p1:p1,p2:p2} : q}

The callback is special to this problem. 回调对于此问题是特殊的。 It will receive two points (each with x and y coordinates) Will calculate the distance between them and will compare it with the previously made calculation. 它将收到两个点(每个点都有x和y坐标),将计算它们之间的距离并将其与先前进行的计算进行比较。 If it's smaller it will replace q by returning this new value; 如果较小,它将通过返回此新值来替换q if not it will return q as it is. 如果不是,它将按原样返回q

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM