2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								---
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								id: 5a23c84252665b21eecc7ecb
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								title: K-d tree
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								challengeType: 5
							 
						 
					
						
							
								
									
										
										
										
											2019-08-05 09:17:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								forumTopicId: 302295
							 
						 
					
						
							
								
									
										
										
										
											2021-01-13 03:31:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								dashedName: k-d-tree
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								---
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# --description--
  
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								A k-d tree (short for *k* -dimensional tree) is a space-partitioning data structure for organizing points in a k-dimensional space. k-d trees are a useful data structure for several applications, such as searches involving a multidimensional search key (e.g. range searches and nearest neighbor searches). k-d trees are a special case of binary space partitioning trees. k-d trees are not suitable, however, for efficiently finding the nearest neighbor in high dimensional spaces. As a general rule, if the dimensionality is *k* , the number of points in the data, *N* , should be *N*  ≫ 2< sup >< i > k</ i ></ sup > . Otherwise, when k-d trees are used with high-dimensional data, most of the points in the tree will be evaluated and the efficiency is no better than exhaustive search, and other methods such as approximate nearest-neighbor are used instead.
							 
						 
					
						
							
								
									
										
										
										
											2019-07-18 17:32:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# --instructions--
  
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Write a function to perform a nearest neighbour search using k-d tree. The function takes two parameters: an array of k-dimensional points, and a single k-dimensional point whose nearest neighbour should be returned by the function. A k-dimensional point will be given as an array of k elements.
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# --hints--
  
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								`kdNN`  should be a function. 
						 
					
						
							
								
									
										
										
										
											2019-07-18 17:32:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								assert(typeof kdNN == 'function');
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								`kdNN([[[2, 3], [5, 4], [9, 6], [4, 7], [8, 1], [7, 2]], [9, 2])`  should return an array. 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								assert(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  Array.isArray(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    kdNN(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [2, 3],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [5, 4],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [9, 6],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [4, 7],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [8, 1],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        [7, 2]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [9, 2]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  )
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								);
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								`kdNN([[[2, 3], [5, 4], [9, 6], [4, 7], [8, 1], [7, 2]], [9, 2])`  should return `[ 8, 1 ]` . 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								assert.deepEqual(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  kdNN(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [2, 3],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [5, 4],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [9, 6],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [4, 7],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [8, 1],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [7, 2]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [9, 2]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  [8, 1]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								`kdNN([[[2, 3], [5, 4], [9, 6], [4, 7], [8, 1], [7, 2]], [7, 1])`  should return `[ 8, 1 ]` . 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								assert.deepEqual(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  kdNN(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [2, 3],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [5, 4],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [9, 6],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [4, 7],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [8, 1],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [7, 2]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [7, 1]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  [8, 1]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
									
										
										
										
											2019-07-18 17:32:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								`kdNN([[[2, 3], [5, 4], [9, 6], [4, 7], [8, 1], [7, 2]], [3, 2])`  should return `[ 2, 3 ]` . 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								assert.deepEqual(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  kdNN(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [2, 3],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [5, 4],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [9, 6],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [4, 7],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [8, 1],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [7, 2]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [3, 2]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  [2, 3]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
									
										
										
										
											2020-09-15 09:57:40 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								`kdNN([[2, 3, 1], [9, 4, 5], [4, 6, 7], [1, 2, 5], [7, 8, 9], [3, 6, 1]], [1, 2, 3])`  should return `[ 1, 2, 5 ]` . 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								assert.deepEqual(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  kdNN(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [2, 3, 1],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [9, 4, 5],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [4, 6, 7],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [1, 2, 5],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [7, 8, 9],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [3, 6, 1]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [1, 2, 3]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  [1, 2, 5]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								);
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								`kdNN([[2, 3, 1], [9, 4, 5], [4, 6, 7], [1, 2, 5], [7, 8, 9], [3, 6, 1]], [4, 5, 6])`  should return `[ 4, 6, 7 ]` . 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								assert.deepEqual(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  kdNN(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [2, 3, 1],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [9, 4, 5],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [4, 6, 7],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [1, 2, 5],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [7, 8, 9],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [3, 6, 1]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [4, 5, 6]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  [4, 6, 7]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								`kdNN([[2, 3, 1], [9, 4, 5], [4, 6, 7], [1, 2, 5], [7, 8, 9], [3, 6, 1]], [8, 8, 8])`  should return `[ 7, 8, 9 ]` . 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								assert.deepEqual(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  kdNN(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [2, 3, 1],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [9, 4, 5],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [4, 6, 7],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [1, 2, 5],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [7, 8, 9],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      [3, 6, 1]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    [8, 8, 8]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  [7, 8, 9]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-27 19:02:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# --seed--
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								## --seed-contents--
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function kdNN(fpoints, fpoint) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# --solutions--
  
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```js
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function kdNN(fpoints, fpoint) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  function Node(obj, dimension, parent) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    this.obj = obj;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    this.left = null;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    this.right = null;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    this.parent = parent;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    this.dimension = dimension;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  function kdTree(points, metric, dimensions) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var self = this;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    function buildTree(points, depth, parent) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      var dim = depth % dimensions.length,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        median,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        node;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if (points.length === 0) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return null;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if (points.length === 1) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return new Node(points[0], dim, parent);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      points.sort(function(a, b) {
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        return a[dimensions[dim]] - b[dimensions[dim]];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      });
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      median = Math.floor(points.length / 2);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      node = new Node(points[median], dim, parent);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      node.left = buildTree(points.slice(0, median), depth + 1, node);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      node.right = buildTree(points.slice(median + 1), depth + 1, node);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return node;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    this.root = buildTree(points, 0, null);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    this.insert = function(point) {
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      function innerSearch(node, parent) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if (node === null) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          return parent;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        var dimension = dimensions[node.dimension];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if (point[dimension] <  node.obj [ dimension ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          return innerSearch(node.left, node);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } else {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          return innerSearch(node.right, node);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      var insertPosition = innerSearch(this.root, null),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        newNode,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dimension;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if (insertPosition === null) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this.root = new Node(point, 0, null);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      newNode = new Node(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        point,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        (insertPosition.dimension + 1) % dimensions.length,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        insertPosition
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      );
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      dimension = dimensions[insertPosition.dimension];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if (point[dimension] <  insertPosition.obj [ dimension ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        insertPosition.left = newNode;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } else {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        insertPosition.right = newNode;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    };
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    this.nearest = function(point, maxNodes, maxDistance) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      var i, result, bestNodes;
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      bestNodes = new BinaryHeap(function(e) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return -e[1];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      });
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      function nearestSearch(node) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        var bestChild,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          dimension = dimensions[node.dimension],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          ownDistance = metric(point, node.obj),
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          linearPoint = {},
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          linearDistance,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          otherChild,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          i;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        function saveNode(node, distance) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          bestNodes.push([node, distance]);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if (bestNodes.size() > maxNodes) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bestNodes.pop();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for (i = 0; i <  dimensions.length ;  i  + =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if (i === node.dimension) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            linearPoint[dimensions[i]] = point[dimensions[i]];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } else {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            linearPoint[dimensions[i]] = node.obj[dimensions[i]];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        linearDistance = metric(linearPoint, node.obj);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if (node.right === null & &  node.left === null) {
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          if (
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bestNodes.size() <  maxNodes  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ownDistance <  bestNodes.peek ( ) [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          ) {
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            saveNode(node, ownDistance);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          return;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if (node.right === null) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          bestChild = node.left;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } else if (node.left === null) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          bestChild = node.right;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } else {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if (point[dimension] <  node.obj [ dimension ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bestChild = node.left;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } else {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bestChild = node.right;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        nearestSearch(bestChild);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if (bestNodes.size() <  maxNodes  | |  ownDistance  <  bestNodes . peek ( ) [ 1 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          saveNode(node, ownDistance);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if (
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          bestNodes.size() <  maxNodes  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          Math.abs(linearDistance) <  bestNodes.peek ( ) [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        ) {
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								          if (bestChild === node.left) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            otherChild = node.right;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          } else {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            otherChild = node.left;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if (otherChild !== null) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            nearestSearch(otherChild);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if (maxDistance) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for (i = 0; i <  maxNodes ;  i  + =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          bestNodes.push([null, maxDistance]);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if (self.root) nearestSearch(self.root);
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      result = [];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for (i = 0; i <  Math.min ( maxNodes ,  bestNodes . content . length ) ;  i  + =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if (bestNodes.content[i][0]) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          result.push([bestNodes.content[i][0].obj, bestNodes.content[i][1]]);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return result;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    };
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  function BinaryHeap(scoreFunction) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    this.content = [];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    this.scoreFunction = scoreFunction;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  BinaryHeap.prototype = {
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    push: function(element) {
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      // Add the new element to the end of the array.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      this.content.push(element);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // Allow it to bubble up.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      this.bubbleUp(this.content.length - 1);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    },
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    pop: function() {
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      // Store the first element so we can return it later.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      var result = this.content[0];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // Get the element at the end of the array.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      var end = this.content.pop();
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // If there are any elements left, put the end element at the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // start, and let it sink down.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if (this.content.length > 0) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this.content[0] = end;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        this.sinkDown(0);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return result;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    },
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    peek: function() {
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      return this.content[0];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    },
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    size: function() {
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      return this.content.length;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    },
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    bubbleUp: function(n) {
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      // Fetch the element that has to be moved.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      var element = this.content[n];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // When at 0, an element can not go up any further.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      while (n > 0) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Compute the parent element's index, and fetch it.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        var parentN = Math.floor((n + 1) / 2) - 1,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          parent = this.content[parentN];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Swap the elements if the parent is greater.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if (this.scoreFunction(element) <  this.scoreFunction ( parent ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          this.content[parentN] = element;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          this.content[n] = parent;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          // Update 'n' to continue at the new position.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          n = parentN;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Found a parent that is less, no need to move it further.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    },
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    sinkDown: function(n) {
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      // Look up the target element and its score.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      var length = this.content.length,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        element = this.content[n],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        elemScore = this.scoreFunction(element);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      while (true) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Compute the indices of the child elements.
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        var child2N = (n + 1) * 2,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          child1N = child2N - 1;
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        // This is used to store the new position of the element,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // if any.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        var swap = null;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // If the first child exists (is inside the array)...
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if (child1N <  length )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          // Look it up and compute its score.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          var child1 = this.content[child1N],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            child1Score = this.scoreFunction(child1);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          // If the score is less than our element's, we need to swap.
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								          if (child1Score <  elemScore )  swap  =  child1N; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Do the same checks for the other child.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if (child2N <  length )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          var child2 = this.content[child2N],
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            child2Score = this.scoreFunction(child2);
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          if (child2Score <  (swap == null ? elemScore : child1Score)) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            swap = child2N;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // If the element needs to be moved, swap it, and continue.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if (swap != null) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          this.content[n] = this.content[swap];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          this.content[swap] = element;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          n = swap;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Otherwise, we are done.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          break;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  };
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  var dims = [];
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  for (var i = 0; i <  fpoint.length ;  i + + )  dims . push ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  var tree = new kdTree(
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    fpoints,
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    function(e1, e2) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      var d = 0;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      var e3 = e1;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if (!Array.isArray(e1)) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        e3 = [];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for (var key in e1) e3.push(e1[key]);
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-30 11:23:18 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        e1 = e3;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      }
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      e1.forEach(function(e, i) {
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        var sqd = e1[i] - e2[i];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        d += sqd * sqd;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      });
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      return d;
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    },
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    dims
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  );
							 
						 
					
						
							
								
									
										
										
										
											2019-03-21 11:52:35 +05:30 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return tree.nearest(fpoint, 1, 1000)[0][0];
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								```