The dichotomic procedure uses the projections (X,Y) of the directions on the 6 faces of a cube numbered 1 (z=1), 2 (y=1), 3 (x=1), 4 (x=–1), 5 (y=–1) and 6 (z=–1).
Each cube face is then divided into 4 areas; each area is further divided into four pieces, etc. The schematic repreentation is:
+---------+
| ^ |
| | |
| 1+--->|
| (N) x |
| |
+---------+---------+---------+---------+
| ^ | ^ | | |
| | | | | (P) | (Q) |
| 5+--->| 3 +--->| 2+--->| 4+--->|
| (R) x | (O) x | x| | x| |
| | | v | v |
+---------+---------+---------+---------+
| ^ |
| |x |
|<---+ |
| 6(S) |
| |
+---------+
Illustrations are given in the Aitoff or Zenital projections.
The number of valid qboxes is
|
Level |Lower qbox# |Number of qboxes |Max rad. |Min rad. |Mean size|Images| |-1 |0 |1 |180.00000 |180.00000 |200° ||| |0 |9 |6 |54.73561 |45.00000 |83° |A|Z| |1 |36 |24 |30.36119 |21.79319 |41° |A|Z| |2 |144 |96 |16.40309 |9.61290 |20° |A|Z| |3 |576 |384 |8.63959 |4.55775 |10° |A|Z| |4 |2304 |1536 |4.44936 |2.21341 |5° ||| |5 |9216 |6144 |2.25967 |1.08995 |150' ||| |6 |36864 |24576 |1.13891 |0.54074 |75' ||| |7 |147456 |98304 |0.57176 |0.26930 |40' ||| |8 |589824 |393216 |0.28646 |0.13438 |20' ||| |9 |2359296 |1572864 |0.14338 |0.06713 |10' ||| |10 |9437184 |6291456 |0.07173 |0.03355 |5' ||| |11 |37748736 |25165824 |0.03587 |0.01677 |150'' ||| |12 |150994944 |100663296 |0.01794 |0.00838 |75'' ||| |
where level is a number which can be changed at any time using qbox_set(level) procedure.
The present implementation assumes that level <=6, corresponding to a maximum of 16 bits in the qbox number; this condition can be removed with a redefinition of the QBOX_BITS definition in this module; constants can be obtained by compiling the program with the DEBUG option set to 1.
For a level 6, the qbox number is a short integer with bits (from left to right) 1ppp xyxy xyxy xyxy. The leftmost `1' bit allows the recognition of the level; bits p represent the face number (1 to 6), x and y the position, expressed with level bits, along the axises defined above for the face. Going down the hierarchy therefore just means a left shift of two bits, and adding (or or'ing) the terminal values 0, 1, 2 or 3.
Qboxes may be edited either as numbers (e.g. 1.300000 which represents, the cell close to the North Pole with RA between 0 and 6hr in level=6), or with letters NPOQRS for faces (N=North, O=0h, P=6h, Q=12h, R=18h, S=South), followed by letters a to p for 2-level aggregations, and terminated by a number 0 to 3 if the level is odd. In this scheme, the names Nmaa and 1.300000 represent the same cell.
The qbox_next routine is aimed to list all subqboxes making up a qbox of an upper level. It must be called a first time with the value of a qbox (e.g. 9 for a qbox at level 0, or a number in the range 9216—15359 for level 5); it returns the number of the first qbox within the "superqbox" (e.g. 36864 for level 6), and continues the list when the argument to qbox_next is zero.
The selection of valid qboxes makes usage of an `action routine', a user–supplied function which is called after the tests and has synopsis routine(qbox_no, status) where status may take the values
The list of selection functions are as follows:
This user-supplied function fct is called with the arguments qboxno, the number of the qbox selected, and a status which can be
#include <qbox.h>
#include <stdio.h>
static int my_action(int qboxno, int status)
{
double qbox_center[2] ;
if (!status) /* Cell not selected at all... */
printf("....The qbox %d (%s) is to be ignored\n",
qboxno, qbox2a(qboxno)) ;
else {
qbox_co(qboxno, qbox_center) ;
printf("====The qbox at %010.6f%+010.6f %d (%s) is %s\n",
qbox_center[0], qbox_center[1], qboxno, qbox2a(qboxno),
status == QBOX_ANY ? "(ANY)" : "(to check)") ;
}
return(0) ;
}
main()
{
double radius, center[2] ;
qbox_set(9) ; /* 1.5 million qboxes... */
qbox_act(my_action) ; /* What I do with selected qboxes... */
center[0] = 1.234; center[1] = -78.912 ; /* That's my target */
for (radius=0.01; radius < 100; radius *= 10) {
printf("\n====Select around (%010.6f%+010.6f), radius=%g (hit Ret)",
center[0], center[1], radius) ;
getchar() ;
qbox_or(center, radius) ;
}
}
As a simple example, the following program just lists all qboxes touched by a target defined by its position and radius:
#include <qbox.h>
#include <stdio.h>
/* Target definitions */
static double target_center[2] = { 180., 10. } ; /* 12h, +10deg */
static double target_radius = 0.25; /* 15' radius */
static double target_u[3] ; /* Dir. cosines of Center */
int show_boxes(int boxid)
/*++++++++++++++++
.PURPOSE This function recursively lists all boxes at deepest level.
.RETURNS Number of printed boxes
-----------------*/
{
int n, i, qb, u ;
double uc[3], maxr ;
n = 0 ;
if (boxid <= 0) { /* Whole Sky */
for (i=9; i<15; i++) n += show_boxes(i) ;
return (n);
}
qbox_cu(boxid, uc) ; /* Box Center */
maxr = qbox_radius(boxid) + target_radius ;
/* The box has no intersection with the target when the distance
target_center/box_center is larger than the added radiuses */
if (dist_u(uc, target_u) >= maxr) return (0) ;
/* At deepest level, the boxid is matched */
if (qbox_level(boxid) >= qbox_get()) {
printf("OK for %d\n", boxid) ;
return(1) ;
}
/* Recursively find all boxes */
for (qb = boxid<<2, i=4, n=0; --i>=0; qb++) n += show_boxes(qb) ;
return(n) ;
}
/* The main program */
main()
{
qbox_set(8) ; /* About 400,000 boxes... */
tr_ou(target_center, target_u) ; /* Get direction cosines */
show_boxes(0) ;
}
<!-- **Error Opening File: /usr/users/francois/src/as4/qbox.h --> [missing file: /usr/users/francois/src/as4/qbox.h]