*** empty log message ***

This commit is contained in:
Hans Tangelder 2003-01-14 13:38:08 +00:00
parent 4a985f37c8
commit 9af0f8544b
3 changed files with 526 additions and 7 deletions

View File

@ -0,0 +1,72 @@
// Example illustrating for each separate splitting rule
// building a kd-tree
#include <vector>
#include <numeric>
#include <cassert>
#include <string>
#include <iostream>
#include <fstream>
#include <CGAL/Kd_tree_rectangle.h>
#include <CGAL/Kd_tree.h>
#include <CGAL/Kd_tree_traits_point.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/algorithm.h>
#include <CGAL/Splitting_rules.h>
// use CGAL Point type
#include <CGAL/Cartesian.h>
#include <CGAL/Point_3.h>
typedef CGAL::Cartesian<double> R;
typedef R::Point_3 Point;
typedef CGAL::Plane_separator<double> Separator;
typedef CGAL::Kd_tree_traits_point<Separator,Point> Traits;
typedef CGAL::Creator_uniform_3<double,Point> Creator;
int generate_kd_tree(CGAL::Split_rule_enumeration::Split_rule s) {
int bucket_size=10;
const int data_point_number=1000;
typedef std::list<Point> point_list;
point_list data_points;
CGAL::Random_points_in_cube_3<Point,Creator> g( 1.0);
CGAL::copy_n( g, data_point_number, std::back_inserter(data_points));
Traits tr(bucket_size, s, 3.0, true);
typedef CGAL::Kd_tree<Traits> Tree;
Tree d(data_points.begin(), data_points.end(), tr);
std::cout << "created kd tree using splitting rule " << s << " containing "
<< data_point_number << " points. " << std::endl;
d.statistics();
return 0;
};
int main() {
generate_kd_tree(CGAL::Split_rule_enumeration::MEDIAN_OF_MAX_SPREAD);
generate_kd_tree(CGAL::Split_rule_enumeration::MEDIAN_OF_BOX);
generate_kd_tree(CGAL::Split_rule_enumeration::MIDPOINT_OF_MAX_SPREAD);
generate_kd_tree(CGAL::Split_rule_enumeration::MIDPOINT_OF_BOX);
generate_kd_tree(CGAL::Split_rule_enumeration::FAIR);
generate_kd_tree(CGAL::Split_rule_enumeration::SLIDING_MIDPOINT);
generate_kd_tree(CGAL::Split_rule_enumeration::SLIDING_FAIR);
/*
double dummy;
std::cout << "Enter input to stop: \n" ;
std::cin >> dummy;
*/
return 0;
};

View File

@ -0,0 +1,439 @@
// ======================================================================
//
// Copyright (c) 2002 The CGAL Consortium
//
// This software and related documentation is part of an INTERNAL release
// of the Computational Geometry Algorithms Library (CGAL). It is not
// intended for general use.
//
// ----------------------------------------------------------------------
//
// release :
// release_date :
//
// file : include/CGAL/Orthogonal_distance_search.h
// package : ASPAS
// revision : 1.4
// revision_date : 2002/16/08
// authors : Hans Tangelder (<hanst@cs.uu.nl>)
// maintainer : Hans Tangelder (<hanst@cs.uu.nl>)
// coordinator : Utrecht University
//
// ======================================================================
#ifndef ORTHOGONAL_DISTANCE_SEARCH
#define ORTHOGONAL_DISTANCE_SEARCH
#include <cstring>
#include <list>
#include <queue>
#include <memory>
#include <CGAL/Kd_tree_node.h>
namespace CGAL {
template <class Tree_traits, class Orthogonal_Distance>
class Orthogonal_distance_search {
public:
typedef typename Tree_traits::Item Item;
typedef typename Tree_traits::NT NT;
typedef Item** Item_iterator;
typedef Kd_tree_node<Tree_traits> Node;
typedef Kd_tree<Tree_traits> Tree;
typedef typename Tree_traits::Item_with_distance Item_with_distance;
typedef std::pair<Node*,NT> Node_with_distance;
private:
// this forward declaration may cause problems for g++
class iterator;
typedef std::vector<Node_with_distance*> Node_with_distance_vector;
typedef std::vector<Item_with_distance*> Item_with_distance_vector;
typedef std::vector<NT> Distance_vector;
iterator *start;
iterator *past_the_end;
public:
// constructor
Orthogonal_distance_search(Tree& tree,
Orthogonal_Distance& tr, Item& q, bool Standard_search, NT Eps = 0.0,
bool Search_nearest=true)
{
if (!Standard_search) {
start = new iterator(tree,q,tr,Eps,Search_nearest);
past_the_end = new iterator();
}
search_nearest_neighbour=Search_nearest;
};
// destructor
Orthogonal_distance_search() {
delete start;
delete past_the_end;
};
iterator begin() {
return *start;
}
iterator end() {
return *past_the_end;
}
class iterator {
public:
typedef std::input_iterator_tag iterator_category;
typedef Item_with_distance value_type;
typedef int distance_type;
class Iterator_implementation;
Iterator_implementation *Ptr_implementation;
public:
// default constructor
iterator() {Ptr_implementation=0;}
int the_number_of_items_visited() {
return Ptr_implementation->number_of_items_visited;
}
// constructor
iterator(Tree& tree, Item& q, Orthogonal_Distance& tr, NT eps=0.0, bool search_nearest=true){
Ptr_implementation =
new Iterator_implementation(tree, q, tr, eps, search_nearest);
}
// copy constructor
iterator(iterator& Iter) {
Ptr_implementation = Iter.Ptr_implementation;
if (Ptr_implementation != 0) Ptr_implementation->reference_count++;
}
Item_with_distance& operator* () {
return *(*Ptr_implementation);
}
// prefix operator
iterator& operator++() {
++(*Ptr_implementation);
return *this;
}
// postfix operator
std::auto_ptr<Item_with_distance> operator++(int) {
std::auto_ptr<Item_with_distance> result = (*Ptr_implementation)++;
return result;
}
bool operator==(const iterator& It) const {
if (
((Ptr_implementation == 0) ||
Ptr_implementation->Item_PriorityQueue.empty()) &&
((It.Ptr_implementation == 0) ||
It.Ptr_implementation->Item_PriorityQueue.empty())
)
return true;
// else
return (Ptr_implementation == It.Ptr_implementation);
}
bool operator!=(const iterator& It) const {
return !(*this == It);
}
~iterator() {
if (Ptr_implementation != 0) {
Ptr_implementation->reference_count--;
if (Ptr_implementation->reference_count==0) {
delete Ptr_implementation;
Ptr_implementation = 0;
}
}
}
class Iterator_implementation {
public:
int number_of_neighbours_computed;
int number_of_internal_nodes_visited;
int number_of_leaf_nodes_visited;
int number_of_items_visited;
private:
NT multiplication_factor;
Item* query_point;
int total_item_number;
NT distance_to_root;
bool search_nearest_neighbour;
NT rd;
class Priority_higher
{
public:
bool search_nearest;
Priority_higher(bool search_the_nearest_neighbour) {
search_nearest = search_the_nearest_neighbour;
}
//highest priority is smallest distance
bool operator() (Node_with_distance* n1, Node_with_distance* n2) const
{
if (search_nearest) { return (n1->second > n2->second);}
else {return (n2->second > n1->second);}
}
};
class Distance_smaller
{
public:
bool search_nearest;
Distance_smaller(bool search_the_nearest_neighbour) {
// Search_traits s;
search_nearest = search_the_nearest_neighbour;
}
//highest priority is smallest distance
bool operator() (Item_with_distance* p1, Item_with_distance* p2) const
{
if (search_nearest) {return (p1->second > p2->second);}
else {return (p2->second > p1->second);}
}
};
std::priority_queue<Node_with_distance*, Node_with_distance_vector,
Priority_higher>* PriorityQueue;
std::priority_queue<Item_with_distance*, Item_with_distance_vector,
Distance_smaller>* Item_PriorityQueue;
Orthogonal_Distance* Orthogonal_Distance_instance;
public:
int reference_count;
// constructor
Iterator_implementation(Tree& tree, Item& q, Orthogonal_Distance& tr,
NT Eps=0.0, bool search_nearest=true)
{
PriorityQueue= new std::priority_queue<Node_with_distance*, Node_with_distance_vector,
Priority_higher>(Priority_higher(search_nearest));
Item_PriorityQueue= new std::priority_queue<Item_with_distance*, Item_with_distance_vector,
Distance_smaller>(Distance_smaller(search_nearest));
search_nearest_neighbour=search_nearest;
reference_count=1;
Orthogonal_Distance_instance=&tr;
multiplication_factor=
Orthogonal_Distance_instance->transformed_distance(1.0+Eps);
if (search_nearest) distance_to_root=
Orthogonal_Distance_instance->lower_bound_distance_to_box(q,
*(tree.bounding_box()));
else distance_to_root=
Orthogonal_Distance_instance->upper_bound_distance_to_box(q,
*(tree.bounding_box()));
query_point = &q;
total_item_number=tree.item_number();
number_of_leaf_nodes_visited=0;
number_of_internal_nodes_visited=0;
number_of_items_visited=0;
number_of_neighbours_computed=0;
Node_with_distance *The_Root = new Node_with_distance(tree.root(),
distance_to_root);
PriorityQueue->push(The_Root);
// rd is the distance of the top of the priority queue to q
rd=The_Root->second;
Compute_the_next_nearest_neighbour();
}
// * operator
Item_with_distance& operator* () {
return *(Item_PriorityQueue->top());
}
// prefix operator
Iterator_implementation& operator++() {
// std::cout << "called ++" << std::endl;
Delete_the_current_item_top();
Compute_the_next_nearest_neighbour();
return *this;
}
// postfix operator
std::auto_ptr<Item_with_distance> operator++(int) {
Item_with_distance Value = *(Item_PriorityQueue->top());
std::auto_ptr<Item_with_distance>
result(new Item_with_distance(Value));
++*this;
return result;
}
//destructor
~Iterator_implementation() {
// std::cout << "called destructor" << std::endl;
while (PriorityQueue->size()>0) {
Node_with_distance* The_top=PriorityQueue->top();
PriorityQueue->pop();
delete The_top;
};
while (Item_PriorityQueue->size()>0) {
Item_with_distance* The_top=Item_PriorityQueue->top();
Item_PriorityQueue->pop();
delete The_top;
};
delete PriorityQueue;
delete Item_PriorityQueue;
}
private:
void Delete_the_current_item_top() {
Item_with_distance* The_item_top=Item_PriorityQueue->top();
Item_PriorityQueue->pop();
delete The_item_top;
}
void Compute_the_next_nearest_neighbour() {
// compute the next item
bool next_neighbour_found=false;
if (!(Item_PriorityQueue->empty())) {
if (search_nearest_neighbour)
next_neighbour_found=
(multiplication_factor*rd > Item_PriorityQueue->top()->second);
else
next_neighbour_found=
(multiplication_factor*rd < Item_PriorityQueue->top()->second);
}
// otherwise browse the tree further
while ((!next_neighbour_found) && (!PriorityQueue->empty())) {
Node_with_distance* The_node_top=PriorityQueue->top();
Node* N= The_node_top->first;
PriorityQueue->pop();
delete The_node_top;
while (!(N->is_leaf())) { // compute new distance
number_of_internal_nodes_visited++;
int new_cut_dim=N->separator()->cutting_dimension();
NT old_off, new_rd;
NT new_off =
(*query_point)[new_cut_dim] -
N->separator()->cutting_value();
if ( ((new_off < 0.0) && (search_nearest_neighbour)) ||
(( new_off >= 0.0) && (!search_nearest_neighbour)) ) {
old_off=
(*query_point)[new_cut_dim]-N->low_value();
if (old_off>0.0) old_off=0.0;
new_rd=
Orthogonal_Distance_instance->
new_distance(rd,old_off,new_off,new_cut_dim);
Node_with_distance *Upper_Child =
new Node_with_distance(N->upper(),new_rd);
PriorityQueue->push(Upper_Child);
N=N->lower();
}
else { // compute new distance
old_off= N->high_value() -
(*query_point)[new_cut_dim];
if (old_off>0.0) old_off=0.0;
new_rd=Orthogonal_Distance_instance->
new_distance(rd,old_off,new_off,new_cut_dim);
Node_with_distance *Lower_Child =
new Node_with_distance(N->lower(),new_rd);
PriorityQueue->push(Lower_Child);
N=N->upper();
}
}
// n is a leaf
number_of_leaf_nodes_visited++;
for (Item_iterator it=N->begin(); it != N->end(); it++) {
number_of_items_visited++;
NT distance_to_query_point=
Orthogonal_Distance_instance->
distance(*query_point,**it);
Item_with_distance *NN_Candidate=
new Item_with_distance(*it,distance_to_query_point);
Item_PriorityQueue->push(NN_Candidate);
}
// old top of PriorityQueue has been processed,
// hence update rd
if (!PriorityQueue->empty()) {
rd = PriorityQueue->top()->second;
if (search_nearest_neighbour)
next_neighbour_found =
(multiplication_factor*rd > Item_PriorityQueue->top()->second);
else
next_neighbour_found =
(multiplication_factor*rd < Item_PriorityQueue->top()->second);
}
else // priority queue empty => last neighbour found
{
next_neighbour_found=true;
};
number_of_neighbours_computed++;
} // next_neighbour_found or priority queue is empty
// in the latter case also the item priority quee is empty
}
}; // class Iterator_implementaion
}; // class iterator
}; // class Nearest neighbour_L2
template <class Tree_traits, class Orthogonal_Distance>
void swap (typename Orthogonal_distance_search<Tree_traits,
Orthogonal_Distance>::iterator& x,
typename Orthogonal_distance_search<Tree_traits,
Orthogonal_Distance>::iterator& y) {
typename Orthogonal_distance_search<Tree_traits,
Orthogonal_Distance>::iterator::Iterator_implementation
*tmp = x.Ptr_implementation;
x.Ptr_implementation = y.Ptr_implementation;
y.Ptr_implementation = tmp;
}
} // namespace CGAL
#endif // ORTHOGONAL_DISTANCE_SEARCH_H

View File

@ -34,13 +34,14 @@ namespace CGAL {
template <class Item> class Point_container;
/* problem with platform sparc_SunOS-5.6_CC-5.30
template <class Item> struct comp_coord_val {
int coord;
comp_coord_val(const int i) : coord(i) {}
bool operator() (const Item *a, const Item *b) {
return (*a)[coord] < (*b)[coord];
}
};
}; */
template <class Item>
std::ostream& operator<< (std::ostream& s, Point_container<Item>& c) {
@ -56,7 +57,7 @@ namespace CGAL {
private:
Point_list p_list; // list of pointers to points
int built_coord; // a coordinate for which the pointer list is built
Kd_tree_rectangle<NT> bbox; // bounding box, i.e. cell of node
Kd_tree_rectangle<NT> bbox; // bounding box, i.e. rectangle of node
Kd_tree_rectangle<NT> tbox; // tight bounding box, i.e. minimal enclosing bounding
// box of points
public:
@ -300,11 +301,18 @@ namespace CGAL {
// assert(c.is_valid());
}
NT median(const int split_coord) {
/* if (p_list.empty()) {
// copy p_list[built_coord] to p_list[split_coord]
p_list[split_coord]=p_list[built_coord]; */
// sort p_list[split_coord]
template <class Item_>
struct comp_coord_val {
int coord;
comp_coord_val(const int i) : coord(i) {}
bool operator() (const Item_ *a, const Item_ *b) {
return (*a)[coord] < (*b)[coord];
}
};
NT median(const int split_coord) {
p_list.sort(comp_coord_val<Item>(split_coord));
// }
typename Point_list::iterator