⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 treediam.c

📁 任意给定三维空间的点集
💻 C
📖 第 1 页 / 共 4 页
字号:
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* * TreeDiam.C - *     Implementation of algorithms for computing the diameter  * using tree heirarchies. *  * Copyright 2000 Sariel Har-Peled (ssaarriieell@cs.uiuc.edu) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. *  * Code is based on the paper: *   A Practical Approach for Computing the Diameter of a Point-Set. *   Sariel Har-Peled (http://www.uiuc.edu/~sariel)\*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/#include  <iostream>#include  <assert.h>#include  <stdlib.h>#include  <stdio.h>#include  <time.h>#include  <math.h>#include  <queue>//#include  "dmalloc.h"#include  "globjwin.h"#include  "_generic.h"#include  "sarray.h"#include  "real.h"#include  "point.h"#include  "bbox.h"#include  "ftree.h"#include  "ftree2d.h"#include  "ftreeptr.h"#include  "TreeDiam.h"#include  "mat3d.h"#include  "misc.h"//#include  "terrain.h"#define  HEAP_LIMIT  100000#define  HEAP_DELTA  100000//class  heap_pairs;//class  FSPairArray;struct lt_fspair{  bool operator()(const FSPair  & a , const FSPair  & b ) const  {      bool  a_iis, b_iis;      if  ( ( ! a.isIdenticalSides() )              &&  ( ! b.isIdenticalSides() ) )          return   a.maxDiam() < b.maxDiam();            a_iis = a.isIdenticalSides();      b_iis = b.isIdenticalSides();      if  ( a_iis  &&  b_iis )          return   a.maxDiam() < b.maxDiam();      if  ( a_iis  &&  (! b_iis ) )          return  false;      else          return  true;      //return   a.minAprxDiam() < b.minAprxDiam();  }};struct lt_fspair_wspd{  bool operator()(const FSPair  & a , const FSPair  & b ) const  {      return   a.maxError() < b.maxError();      //return   a.minAprxDiam() < b.minAprxDiam();  }};struct lt_fsppair{    bool operator()(const FSPPair  & a , const FSPPair  & b ) const    {        return   a.maxDiam() < b.maxDiam();        //return   a.minAprxDiam() < b.minAprxDiam();    }};struct lt_fspair_2d{  bool operator()(const FS2dPair  & a , const FS2dPair  & b ) const  {      return   a.maxDiam() < b.maxDiam();      //return   a.minAprxDiam() < b.minAprxDiam();  }};/*--- Constants ---*/#define   THRESHOLD_LOCAL   400#define  THRESHOLD   10class  heap_pairs : public std::priority_queue<FSPair,                     std::vector<FSPair>, lt_fspair>{};//   heap_pairs;class  FSPairArray : public  Array<FSPair> {};/*--- Start of Code ---*/real   brute_diameter_range( const ArrPoint3d  & arr,                             int  start,                             int  end,                             PointPair  & diam ){    for  ( int  ind = start; ind < end; ind++ )        for  ( int  jnd = ind + 1; jnd <= end; jnd++ )             diam.update_diam( arr[ ind ], arr[ jnd ] );    return  diam.distance;}#define   THRESHOLD_LOCAL   400real   brute_diameter_local_bi( const ArrPoint3d  & arr,                                int  a_start,                                int  a_end,                                int  b_start,                                int  b_end,                                PointPair  & diam ){    int   a_mid, b_mid;    if  ( ( a_end - a_start ) < THRESHOLD_LOCAL ) {        for  ( int  ind = a_start; ind <= a_end; ind++ )            for  ( int  jnd = b_start; jnd <= b_end; jnd++ )                 diam.update_diam( arr[ ind ], arr[ jnd ] );        return  diam.distance;    }    a_mid = (a_start + a_end) / 2;    b_mid = (b_start + b_end) / 2;    brute_diameter_local_bi( arr,                              a_start, a_mid,                              b_start, b_mid, diam );    brute_diameter_local_bi( arr,                             a_start, a_mid,                              b_mid + 1, b_end, diam );    brute_diameter_local_bi( arr,                             a_mid + 1, a_end,                              b_start, b_mid, diam );    brute_diameter_local_bi( arr,                             a_mid + 1, a_end,                             b_mid + 1, b_end, diam );    return  diam.distance;}real   brute_diameter_local( const ArrPoint3d  & arr,                             int  start,                             int  end,                             PointPair  & out ){    int  mid;    if  ( ( end - start ) < THRESHOLD_LOCAL )        return   brute_diameter_range( arr, start, end, out );            mid = ( start + end ) / 2;    brute_diameter_local_bi( arr, start, mid, mid + 1, end, out );    brute_diameter_local( arr, start, mid, out );    brute_diameter_local( arr, mid + 1, end, out );    return  out.distance;}real   brute_diameter_local( const ArrPoint3d  & arr,                             PointPair  & out ){    out.p = out.q = arr[ 0 ];    out.distance = 0;    return  brute_diameter_local( arr, 0, arr.size() - 1, out );}void   fill_array_cube( ArrPoint3d  & arr, int  num ){    arr.init( num + 10, 43897543 );    for  ( int  ind = 0; ind < num; ind++ ) {        Point3d  pnt;                pnt.fillRandom();        arr.pushx( pnt );    }}void   fill_array_box( ArrPoint3d  & arr, int  num,                       double  a, double  b, double  c ){    arr.init( num + 10, 43897543 );    for  ( int  ind = 0; ind < num; ind++ ) {        Point3d  pnt;                pnt.fillRandom();        Point3d  pntx( pnt[ 0 ] * a, pnt[ 1 ] * b, pnt[ 2 ] * c );        arr.pushx( pntx );    }}void   fill_array_sphere( ArrPoint3d  & arr, int  num ){    arr.init( num + 10, 43897543 );    for  ( int  ind = 0; ind < num; ind++ ) {        double  alpha, beta;        Point3d  pnt;                alpha = realRand() * 2.0 * 3.1415926535;        beta = realRand() * 2.0 * 3.1415926535;        pnt.setCoord( 0, cos( alpha ) * sin( beta ) );        pnt.setCoord( 1, cos( alpha ) * cos( beta ) );        pnt.setCoord( 2, sin( alpha ) );                //pnt.fillRandom();        arr.pushx( pnt );    }}void   fill_array_sphere_caps( ArrPoint3d  & arr, int  num,                            double  eps ){    arr.init( num + 10, 43897543 );    for  ( int  ind = 0; ind < num; ind++ ) {        double  alpha, beta;        Point3d  pnt;                alpha = (1.0 - eps * realRand()) * 3.1415926535 / 2.0;        if  ( realRand() >= 0.5 )             alpha = -alpha;        beta = realRand() * 2.0 * 3.1415926535;        pnt.setCoord( 0, cos( alpha ) * sin( beta ) );        pnt.setCoord( 1, cos( alpha ) * cos( beta ) );        pnt.setCoord( 2, sin( alpha ) );                //pnt.fillRandom();        arr.pushx( pnt );    }}void   fill_array_two_arcs( ArrPoint3d  & arr, int  num ){    double  alpha_limit, alpha_increment, alpha;    Point3d  pnt;    arr.init( num + 10, 43897543 );    num  = num / 2;    alpha_limit = 1.0 /((double)num*num);    alpha_increment = 2.0 * alpha_limit  / (double)num;        Transform3d  trans_x, trans_z;    trans_x.init_rot_around_x( 3.14150265358979323 / 4.0 );    trans_z.init_rot_around_z( 3.14150265358979323 / 4.0 );    alpha = -alpha_limit;    for  ( int  ind = 0; ind < num; ind++ ) {        pnt = Point3d( -cos( alpha ), 0, sin( alpha ) );        trans_x.transform( pnt );        trans_z.transform( pnt );        arr.pushx( pnt );        pnt = Point3d( cos( alpha ), sin( alpha ), 0 );        trans_x.transform( pnt );        trans_z.transform( pnt );        arr.pushx( pnt );        alpha += alpha_increment;    }}void   fill_array_mutated_ellipsoid( ArrPoint3d  & arr, int  num,                                     double  a, double  b, double  c ){    Point3d  new_pnt, pnt;    arr.init( num + 10, 43897543 );    Point3d  vec1( 1, 1, 1 );    Point3d  vec2( 1, -1, 0 );    Point3d  vec3;    vec3 = cross_prod( vec1, vec2 );    vec1.normalize();    vec2.normalize();    vec3.normalize();    int  limit;    limit = num / 11;    for  ( int  ind = 0; ind < limit; ind++ ) {        double  alpha, beta;        Point3d  pnt;                alpha = realRand() * 2.0 * 3.1415926535;        beta = realRand() * 2.0 * 3.1415926535;        pnt.setCoord( 0, a * cos( alpha ) * sin( beta ) );        pnt.setCoord( 1, b * cos( alpha ) * cos( beta ) );        pnt.setCoord( 2, c * sin( alpha ) );                new_pnt = changeBase( vec1, vec2, vec3, pnt );                //pnt.fillRandom();        arr.pushx( new_pnt );    }    limit = 5 * num / 11;    for  ( int  ind = 0; ind < limit; ind++ ) {        pnt.setCoord( 0, 0 );        pnt.setCoord( 1, 0 );        pnt.setCoord( 2, 0.999 * c );        new_pnt = changeBase( vec1, vec2, vec3, pnt );                arr.pushx( new_pnt );    }    for  ( int  ind = 0; ind < limit; ind++ ) {        pnt.setCoord( 0, 0 );        pnt.setCoord( 1, 0.999 * b );        pnt.setCoord( 2, 0 );        new_pnt = changeBase( vec1, vec2, vec3, pnt );                arr.pushx( new_pnt );    }}static void   addPoint( ArrPoint3d  & arr, double  x, double  y, double  z ){    Point3d  pnt( x, y, z );    Point3d  pnt1;    pnt1.fillRandom();    pnt.add_scale( pnt1, 0.00001 );    arr.pushx( pnt );}// Cheats the regular bbox/pca algorithm. so they realize 1.72// approximation in 3dvoid   fill_array_strange_cube( ArrPoint3d  & arr, int  num ){    int limit;    //Point3d  pnt, pnt1;            arr.init( num + 10, 43897543 );    addPoint( arr, -1, -1, -1 );    addPoint( arr, -1, -1,  1 );    addPoint( arr, -1,  1, -1 );    addPoint( arr, -1,  1,  1 );    addPoint( arr,  1, -1, -1 );    addPoint( arr,  1, -1,  1 );    addPoint( arr,  1,  1, -1 );    addPoint( arr,  1,  1,  1 );    addPoint( arr,  0,  0,  1.01000001 );    addPoint( arr,  0,  0, -1.0100001 );    addPoint( arr,  0,  1.01, 0 );    addPoint( arr,  0, -1.01, 0 );    addPoint( arr,  1.01, 0, 0 );    addPoint( arr, -1.01, 0, 0 );    limit = num / 12;    for  ( int  ind = 0; ind < limit; ind++ ) {        addPoint( arr,  0.001,  0,  1.011 );        addPoint( arr,  0,  0.0001, -1.011 );        addPoint( arr,  0.001,  0,  1.011 );        addPoint( arr,  0,  0.0001, -1.011 );        addPoint( arr,  0.001,  0,  1.011 );        addPoint( arr,  0,  0.0001, -1.011 );        addPoint( arr,  0,  1.011, 0 );        addPoint( arr,  0, -1.011, 0 );        addPoint( arr,  0,  1.011, 0 );        addPoint( arr,  0, -1.011, 0 );        addPoint( arr,   1.011, 0, 0 );        addPoint( arr,  -1.011, 0, 0 );    }}void   fill_array_strange_cube_diag( ArrPoint3d  & arr, int  num ){    int limit;    //Point3d  pnt, pnt1;            arr.init( num + 10, 43897543 );    addPoint( arr, -1, -1, -1 );    addPoint( arr, -1, -1,  1 );    addPoint( arr, -1,  1, -1 );    addPoint( arr, -1,  1,  1 );    addPoint( arr,  1, -1, -1 );    addPoint( arr,  1, -1,  1 );    addPoint( arr,  1,  1, -1 );    addPoint( arr,  1,  1,  1 );    addPoint( arr,  0,  0,  1.1000001 );    addPoint( arr,  0,  0, -1.100001 );    addPoint( arr,  0,  1.1, 0 );    addPoint( arr,  0, -1.1, 0 );    addPoint( arr,  1.1, 0, 0 );    addPoint( arr, -1.1, 0, 0 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -