//----------------------------------------------------------------------
//	File:		kd_util.h
//	Programmer:	Sunil Arya and David Mount
//	Last modified:	03/04/98 (Release 0.1)
//	Description:	Common utilities for kd- trees
//----------------------------------------------------------------------
// Copyright (c) 1997-1998 University of Maryland and Sunil Arya and David
// Mount.  All Rights Reserved.
// 
// This software and related documentation is part of the 
// Approximate Nearest Neighbor Library (ANN).
// 
// Permission to use, copy, and distribute this software and its 
// documentation is hereby granted free of charge, provided that 
// (1) it is not a component of a commercial product, and 
// (2) this notice appears in all copies of the software and
//     related documentation. 
// 
// The University of Maryland (U.M.) and the authors make no representations
// about the suitability or fitness of this software for any purpose.  It is
// provided "as is" without express or implied warranty.
//----------------------------------------------------------------------

#ifndef ANN_kd_util_H
#define ANN_kd_util_H

#include "kd_tree.h"			// kd-tree declarations

//----------------------------------------------------------------------
//  externally accessible functions
//----------------------------------------------------------------------

double annAspectRatio(		// compute aspect ratio of box
    int			dim,		// dimension
    const ANNorthRect	&bnd_box);	// bounding cube

void annEnclRect(		// compute smallest enclosing rectangle
    ANNpointArray	pa,		// point array
    ANNidxArray		pidx,		// point indices
    int			n,		// number of points
    int			dim,		// dimension
    ANNorthRect	&bnds);			// bounding cube (returned)

void annEnclCube(		// compute smallest enclosing cube
    ANNpointArray	pa,		// point array
    ANNidxArray		pidx,		// point indices
    int			n,		// number of points
    int			dim,		// dimension
    ANNorthRect	&bnds);			// bounding cube (returned)

ANNdist annBoxDistance(		// compute distance from point to box
    const ANNpoint	q,		// the point
    const ANNpoint	lo,		// low point of box
    const ANNpoint	hi,		// high point of box
    int			dim);		// dimension of space

ANNcoord annSpread(		// compute point spread along dimension
    ANNpointArray	pa,		// point array
    ANNidxArray		pidx,		// point indices
    int			n,		// number of points
    int			d);		// dimension to check

void annMinMax(			// compute min and max coordinates along dim
    ANNpointArray	pa,		// point array
    ANNidxArray		pidx,		// point indices
    int			n,		// number of points
    int			d,		// dimension to check
    ANNcoord&		min,		// minimum value (returned)
    ANNcoord&		max);		// maximum value (returned)

int annMaxSpread(		// compute dimension of max spread
    ANNpointArray	pa,		// point array
    ANNidxArray		pidx,		// point indices
    int			n,		// number of points
    int			dim);		// dimension of space

void annMedianSplit(		// split points along median value
    ANNpointArray	pa,		// points to split
    ANNidxArray		pidx,		// point indices
    int			n,		// number of points
    int			d,		// dimension along which to split
    ANNcoord		&cv,		// cutting value
    int			n_lo);		// split into n_lo and n-n_lo

void annPlaneSplit(		// split points by a plane
    ANNpointArray	pa,		// points to split
    ANNidxArray		pidx,		// point indices
    int			n,		// number of points
    int			d,		// dimension along which to split
    ANNcoord		cv,		// cutting value
    int			&br1,		// first break (values < cv)
    int			&br2);		// second break (values == cv)

void annBoxSplit(		// split points by a box
    ANNpointArray	pa,		// points to split
    ANNidxArray		pidx,		// point indices
    int			n,		// number of points
    int			dim,		// dimension of space
    ANNorthRect		&box,		// the box
    int			&n_in);		// number of points inside (returned)

int annSplitBalance(		// determine balance factor of a split
    ANNpointArray	pa,		// points to split
    ANNidxArray		pidx,		// point indices
    int			n,		// number of points
    int			d,		// dimension along which to split
    ANNcoord		cv);		// cutting value

void annBox2Bnds(		// convert inner box to bounds
    const ANNorthRect	&inner_box,	// inner box
    const ANNorthRect	&bnd_box,	// enclosing box
    int			dim,		// dimension of space
    int			&n_bnds,	// number of bounds (returned)
    ANNorthHSArray	&bnds);		// bounds array (returned)

void annBnds2Box(		// convert bounds to inner box
    const ANNorthRect	&bnd_box,	// enclosing box
    int			dim,		// dimension of space
    int			n_bnds,		// number of bounds
    ANNorthHSArray	bnds,		// bounds array
    ANNorthRect		&inner_box);	// inner box (returned)

#endif
