K-d tree: Difference between revisions

Content added Content deleted
(→‎{{header|jq}}: simplify)
Line 3,487: Line 3,487:
# Input: a KdTree
# Input: a KdTree
def nearest($p):
def nearest($p):
# Input: a KdTree

def nn_($kd; $target; $hr; $maxDistSqd):
def nn_($target; $hr; $maxDistSqd):
if ($kd | not) then NearestNeighbor(null; infinite; 0)
if not then NearestNeighbor(null; infinite; 0)
else { nodesVisited: 1,
else .split as $s
leftHr: $hr,
| .domElt as $pivot
rightHr: $hr }
| .left as $left
| $kd.split as $s
| .right as $right
| $kd.domElt as $pivot
| ($target[$s] <= $pivot[$s]) as $targetInLeft
| { nodesVisited: 1,
leftHr: $hr,
rightHr: $hr }
| .leftHr.max[$s] = $pivot[$s]
| .leftHr.max[$s] = $pivot[$s]
| .rightHr.min[$s] = $pivot[$s]
| .rightHr.min[$s] = $pivot[$s]
| ($target[$s] <= $pivot[$s]) as $targetInLeft
| (if $targetInLeft then $left else $right end) as $nearerKd
| (if $targetInLeft then $kd.left else $kd.right end) as $nearerKd
| (if $targetInLeft then .leftHr else .rightHr end) as $nearerHr
| (if $targetInLeft then .leftHr else .rightHr end) as $nearerHr
| (if $targetInLeft then $kd.right else $kd.left end) as $furtherKd
| (if $targetInLeft then $right else $left end) as $furtherKd
| (if $targetInLeft then .rightHr else .leftHr end) as $furtherHr
| (if $targetInLeft then .rightHr else .leftHr end) as $furtherHr
| nn_($nearerKd; $target; $nearerHr; $maxDistSqd) as $res
| ($nearerKd | nn_($target; $nearerHr; $maxDistSqd)) as $res
| .nearest = $res.nearest
| .nearest = $res.nearest
| .distSqd = $res.distSqd
| .distSqd = $res.distSqd
Line 3,516: Line 3,518:
else .
else .
end
end
| nn_($furtherKd; $target; $furtherHr; .maxDistSqd2) as $temp
| ($furtherKd | nn_($target; $furtherHr; .maxDistSqd2)) as $temp
| .nodesVisited += $temp.nodesVisited
| .nodesVisited += $temp.nodesVisited
| if $temp.distSqd < .distSqd
| if $temp.distSqd < .distSqd
Line 3,527: Line 3,529:
end ;
end ;
nn_(.n; $p; .bounds; infinite);
.n | nn_($p; .bounds; infinite);


def showNearest($heading; $kd; $p):
def example($heading; $hr; $points; $p):
KdTree($points; .hr)
($kd | nearest($p)) as $res
| nearest($p)
| "\(heading):",
| "\(heading):",
"Point : \($p)",
"Point : \($p)",
"Nearest neighbor : \($res.nearest)",
"Nearest neighbor : \(.nearest)",
"Distance : \($res.distSqd | sqrt)",
"Distance : \(.distSqd | sqrt)",
"Nodes visited : \($res.nodesVisited)",
"Nodes visited : \(.nodesVisited)",
"";
"";

def example($title; $hr; $points; $point):
KdTree($points; .hr) as $kd
| showNearest($title; $kd; $point);



### Examples
### Examples