MultiGravity.tioga
An Algorithm for Best-N Hit Testing
Eric Bier
April 4, 1986
The Problem
Given a scene with many curves and with distinguished points, and given a test point, find the n closest objects to the testpoint. The algorithm should be easy to implement, and the space requirements should be low.
Algorithm
Let there be an array H with n elements, H[i], 0 <= i <= n-1. Each element H[i] consists of a real number H[i].dist, and a pointer to the scene object which the element represents, H[i].pointer. Initialize all H[i].dist to infinity, and all H[i].pointer to NIL. Let size be the number of elements currently stored in H. Throughout the algorithm, elements H[0] ... H[size-1] will be occupied. Initialize size to 0. Other elements are empty. We will not keep the elements of H sorted. We will, however, keep track of the value and index of the largest and smallest elements (where H[i].dist is the "size" of H[i]) currently stored, in two variables, max and min. Initialize max to zero and min to infinity. Let overflow be true, if there are known to be objects of distance exactly max from the testpoint, which are not in H. overflow is initially false.
Initialize
H[i].dist ← , for all i.
H[i].pointer ← NIL, for all i.
size ← 0;
max ← 0;
min ← ;
overflow ← FALSE;
For each object in the scene, find the distance d of that object from the test point.
1. Compare d to max and compare size to n.
IF d > max AND size < n THEN max ← d; Goto Add.
IF d <= max AND size < n THEN Goto Add.
IF d < max AND size = n THEN Goto AddAndComputeNewMax.
IF d > max AND size = n THEN Goto End. -- we already have n and this is no better.
IF d = max AND size = n THEN overflow ← true; Goto End.
2. Consider next object.
3. Add. H[size].dist ← d. H[size].pointer ← p. size ← size + 1. If d < min THEN min ← d.
4. AddAndComputeNewMax. Find the value of i, i* such that H[i].dist is maximized. Let H[i*].dist ← d; H[i*].pointer ← p. Now, find the value of j, j* such that H[i].dist is maximized. Let max = H[j*].dist. If max is unchanged, overflow ← true, ELSE overflow ← false;
Using the Algorithm for Strict Distance Gravity
After H is computed, sort the elements, and pick those points which are in at a distance
min <= d <= min + t
where t is a fixed tolerance, and where min MIN[min for points, min for lines]; The tolerance should be computed as a fixed percentage of the gravity extent.