#include <cstring>
#include <ctime>
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include "emdata.h"
#include "util.h"
#include "fundamentals.h"
#include "lapackblas.h"
#include "lbfgsb.h"
#include "steepest.h"
#include "emassert.h"
#include "randnum.h"
#include <gsl/gsl_sf_bessel.h>
#include <cmath>
Include dependency graph for util_sparx.cpp:
Go to the source code of this file.
Classes | |
struct | ori_t |
struct | cmpang |
struct | t_BPCQ_line |
struct | tmpstruct |
struct | stcom_ |
struct | assign_groups_comparator |
struct | d_ang |
struct | ccf_point |
struct | ccf_value |
struct | point3d_t |
Defines | |
#define | fdata(i, j) fdata[ i-1 + (j-1)*nxdata ] |
#define | fdata(i, j) fdata[ i-1 + (j-1)*nxdata ] |
#define | circ(i) circ[i-1] |
#define | numr(i, j) numr[(j-1)*3 + i-1] |
#define | xim(i, j) xim[(j-1)*nsam + i-1] |
#define | tab1(i) tab1[i-1] |
#define | xcmplx(i, j) xcmplx [(j-1)*2 + i-1] |
#define | br(i) br[i-1] |
#define | bi(i) bi[i-1] |
#define | b(i) b[i-1] |
#define | circ1(i) circ1[i-1] |
#define | circ2(i) circ2[i-1] |
#define | t(i) t[i-1] |
#define | q(i) q[i-1] |
#define | b(i) b[i-1] |
#define | t7(i) t7[i-1] |
#define | dout(i, j) dout[i+maxrin*j] |
#define | circ1b(i) circ1b[i-1] |
#define | circ2b(i) circ2b[i-1] |
#define | dout(i, j) dout[i+maxrin*j] |
#define | circ1b(i) circ1b[i-1] |
#define | circ2b(i) circ2b[i-1] |
#define | QUADPI 3.141592653589793238462643383279502884197 |
#define | PI2 2*QUADPI |
#define | QUADPI 3.141592653589793238462643383279502884197 |
#define | PI2 QUADPI*2 |
#define | deg_rad QUADPI/180.0 |
#define | rad_deg 180.0/QUADPI |
#define | old_ptr(i, j, k) old_ptr[i+(j+(k*ny))*(size_t)nx] |
#define | new_ptr(iptr, jptr, kptr) new_ptr[iptr+(jptr+(kptr*new_ny))*(size_t)new_nx] |
#define | inp(i, j, k) inp[(i+new_st_x)+((j+new_st_y)+((k+new_st_z)*ny))*(size_t)nx] |
#define | outp(i, j, k) outp[i+(j+(k*new_ny))*(size_t)new_nx] |
#define | inp(i, j, k) inp[i+(j+(k*ny))*(size_t)nx] |
#define | outp(i, j, k) outp[(i+new_st_x)+((j+new_st_y)+((k+new_st_z)*new_ny))*(size_t)new_nx] |
#define | QUADPI 3.141592653589793238462643383279502884197 |
#define | DGR_TO_RAD QUADPI/180 |
#define | DM(I) DM [I-1] |
#define | SS(I) SS [I-1] |
#define | W(i, j) Wptr [i+(j)*Wnx] |
#define | PROJ(i, j) PROJptr [i+(j)*NNNN] |
#define | SS(i, j) SS [i+(j)*6] |
#define | W(i, j) Wptr [i-1+((j-1)*Wnx)] |
#define | PROJ(i, j) PROJptr [i-1+((j-1)*NNNN)] |
#define | SS(I, J) SS [I-1 + (J-1)*6] |
#define | RI(i, j) RI [(i-1) + ((j-1)*3)] |
#define | CC(i) CC [i-1] |
#define | CP(i) CP [i-1] |
#define | VP(i) VP [i-1] |
#define | VV(i) VV [i-1] |
#define | AMAX1(i, j) i>j?i:j |
#define | AMIN1(i, j) i<j?i:j |
#define | mymax(x, y) (((x)>(y))?(x):(y)) |
#define | mymin(x, y) (((x)<(y))?(x):(y)) |
#define | sign(x, y) (((((y)>0)?(1):(-1))*(y!=0))*(x)) |
#define | quadpi 3.141592653589793238462643383279502884197 |
#define | dgr_to_rad quadpi/180 |
#define | deg_to_rad quadpi/180 |
#define | rad_to_deg 180/quadpi |
#define | rad_to_dgr 180/quadpi |
#define | TRUE 1 |
#define | FALSE 0 |
#define | theta(i) theta [i-1] |
#define | phi(i) phi [i-1] |
#define | weight(i) weight [i-1] |
#define | lband(i) lband [i-1] |
#define | ts(i) ts [i-1] |
#define | thetast(i) thetast [i-1] |
#define | key(i) key [i-1] |
#define | TRUE_ (1) |
#define | FALSE_ (0) |
#define | abs(x) ((x) >= 0 ? (x) : -(x)) |
#define | img_ptr(i, j, k) img_ptr[2*(i-1)+((j-1)+((k-1)*ny))*(size_t)nxo] |
#define | img_ptr(i, j, k) img_ptr[i+(j+(k*ny))*(size_t)nx] |
#define | img2_ptr(i, j, k) img2_ptr[i+(j+(k*ny))*(size_t)nx] |
#define | cent(i) out[i+N] |
#define | assign(i) out[i] |
#define | data(i, j) group[i*ny+j] |
Functions | |
int | circum_ (double *, double *, double *, double *, int *) |
long int | left_ (double *, double *, double *, double *, double *, double *, double *, double *, double *) |
int | addnod_ (int *, int *, double *, double *, double *, int *, int *, int *, int *, int *) |
int | i_dnnt (double *x) |
double | angle_ (double *v1, double *v2, double *v3) |
double | areas_ (double *v1, double *v2, double *v3) |
double | areav_new__ (int *k, int *n, double *x, double *y, double *z__, int *list, int *lptr, int *lend, int *ier) |
int | bdyadd_ (int *kk, int *i1, int *i2, int *list, int *lptr, int *lend, int *lnew) |
int | bnodes_ (int *n, int *list, int *lptr, int *lend, int *nodes, int *nb, int *na, int *nt) |
int | circle_ (int *k, double *xc, double *yc, int *ier) |
int | covsph_ (int *kk, int *n0, int *list, int *lptr, int *lend, int *lnew) |
int | crlist_ (int *n, int *ncol, double *x, double *y, double *z__, int *list, int *lend, int *lptr, int *lnew, int *ltri, int *listc, int *nb, double *xc, double *yc, double *zc, double *rc, int *ier) |
int | delarc_ (int *n, int *io1, int *io2, int *list, int *lptr, int *lend, int *lnew, int *ier) |
int | delnb_ (int *n0, int *nb, int *n, int *list, int *lptr, int *lend, int *lnew, int *lph) |
int | delnod_ (int *k, int *n, double *x, double *y, double *z__, int *list, int *lptr, int *lend, int *lnew, int *lwk, int *iwk, int *ier) |
int | drwarc_ (int *, double *p, double *q, double *tol, int *nseg) |
int | edge_ (int *in1, int *in2, double *x, double *y, double *z__, int *lwk, int *iwk, int *list, int *lptr, int *lend, int *ier) |
int | getnp_ (double *x, double *y, double *z__, int *list, int *lptr, int *lend, int *l, int *npts, double *df, int *ier) |
int | insert_ (int *k, int *lp, int *list, int *lptr, int *lnew) |
long int | inside_ (double *p, int *lv, double *xv, double *yv, double *zv, int *nv, int *listv, int *ier) |
int | intadd_ (int *kk, int *i1, int *i2, int *i3, int *list, int *lptr, int *lend, int *lnew) |
int | intrsc_ (double *p1, double *p2, double *cn, double *p, int *ier) |
int | jrand_ (int *n, int *ix, int *iy, int *iz) |
int | lstptr_ (int *lpl, int *nb, int *list, int *lptr) |
int | nbcnt_ (int *lpl, int *lptr) |
int | nearnd_ (double *p, int *ist, int *n, double *x, double *y, double *z__, int *list, int *lptr, int *lend, double *al) |
int | optim_ (double *x, double *y, double *z__, int *na, int *list, int *lptr, int *lend, int *nit, int *iwk, int *ier) |
int | projct_ (double *px, double *py, double *pz, double *ox, double *oy, double *oz, double *ex, double *ey, double *ez, double *vx, double *vy, double *vz, long int *init, double *x, double *y, double *z__, int *ier) |
int | scoord_ (double *px, double *py, double *pz, double *plat, double *plon, double *pnrm) |
double | store_ (double *x) |
int | swap_ (int *in1, int *in2, int *io1, int *io2, int *list, int *lptr, int *lend, int *lp21) |
long int | swptst_ (int *n1, int *n2, int *n3, int *n4, double *x, double *y, double *z__) |
int | trans_ (int *n, double *rlat, double *rlon, double *x, double *y, double *z__) |
int | trfind_ (int *nst, double *p, int *n, double *x, double *y, double *z__, int *list, int *lptr, int *lend, double *b1, double *b2, double *b3, int *i1, int *i2, int *i3) |
int | trlist_ (int *n, int *list, int *lptr, int *lend, int *nrow, int *nt, int *ltri, int *ier) |
int | trlprt_ (int *n, double *x, double *y, double *z__, int *iflag, int *nrow, int *nt, int *ltri, int *lout) |
int | trmesh_ (int *n, double *x, double *y, double *z__, int *list, int *lptr, int *lend, int *lnew, int *near__, int *next, double *dist, int *ier) |
int | trplot_ (int *lun, double *pltsiz, double *elat, double *elon, double *a, int *n, double *x, double *y, double *z__, int *list, int *lptr, int *lend, char *, long int *numbr, int *ier, short) |
int | trprnt_ (int *n, double *x, double *y, double *z__, int *iflag, int *list, int *lptr, int *lend, int *lout) |
int | vrplot_ (int *lun, double *pltsiz, double *elat, double *elon, double *a, int *n, double *x, double *y, double *z__, int *nt, int *listc, int *lptr, int *lend, double *xc, double *yc, double *zc, char *, long int *numbr, int *ier, short) |
int | random_ (int *ix, int *iy, int *iz, double *rannum) |
int | find_group (int ix, int iy, int iz, int grpid, EMData *mg, EMData *visited) |
bool | jiafunc (int i, int j) |
static void | compose_transform2 (float psi1, float sx1, float sy1, float psi2, float sx2, float sy2, float &out_psi, float &out_sx, float &out_sy) |
Variables | |
stcom_ | stcom_1 |
int | branch_all = 0 |
int * | costlist_global |
#define abs | ( | x | ) | ((x) >= 0 ? (x) : -(x)) |
Definition at line 7773 of file util_sparx.cpp.
#define AMAX1 | ( | i, | |||
j | ) | i>j?i:j |
#define AMIN1 | ( | i, | |||
j | ) | i<j?i:j |
#define assign | ( | i | ) | out[i] |
#define b | ( | i | ) | b[i-1] |
Definition at line 3187 of file util_sparx.cpp.
#define b | ( | i | ) | b[i-1] |
Definition at line 3187 of file util_sparx.cpp.
Referenced by EMAN::CtfCAutoAverager::add_image(), EMAN::CtfCWautoAverager::add_image(), bmv_(), EMAN::Util::cml_line_insino(), EMAN::Util::cml_line_insino_all(), EMAN::OptVarianceCmp::cmp(), Derivatives(), Derivatives_G(), formk_(), GCVmin_Tik(), EMAN::TetrahedralSym::get_asym_unit_points(), EMAN::PlatonicSym::get_asym_unit_points(), EMAN::HSym::get_asym_unit_points(), EMAN::EMUtil::get_euler_names(), EMAN::Util::initial_prune(), inside_(), EMAN::Matrix4::inverse(), main(), EMAN::Matrix4::operator *(), EMAN::operator *(), EMAN::Quaternion::operator *=(), ccf_value::operator()(), cmpang::operator()(), EMAN::operator+(), EMAN::operator-(), EMAN::operator/(), EMAN::Quaternion::operator/=(), EMAN::Util::prb1d(), prb1d(), EMAN::TestImageEllipse::process_inplace(), EMAN::TestImageGradient::process_inplace(), EMAN::NormalizeToLeastSquareProcessor::process_inplace(), EMAN::GradientRemoverProcessor::process_inplace(), EMAN::Util::splint(), subsm_(), and varmx().
#define bi | ( | i | ) | bi[i-1] |
Definition at line 2622 of file util_sparx.cpp.
Referenced by EMAN::Util::fftc_d(), fftc_d(), EMAN::Util::fftc_q(), fftc_q(), EMAN::EMData::onelinenn(), EMAN::EMData::onelinenn_ctf(), EMAN::EMData::onelinenn_ctf_applied(), EMAN::EMData::onelinenn_mult(), and EMAN::TestImageEllipse::process_inplace().
#define br | ( | i | ) | br[i-1] |
Definition at line 2621 of file util_sparx.cpp.
Referenced by EMAN::Util::fftc_d(), fftc_d(), EMAN::Util::fftc_q(), fftc_q(), EMAN::EMData::render_amp24(), and EMAN::EMData::render_ap24().
#define CC | ( | i | ) | CC [i-1] |
#define cent | ( | i | ) | out[i+N] |
#define circ | ( | i | ) | circ[i-1] |
Definition at line 2139 of file util_sparx.cpp.
Referenced by EMAN::Util::alrl_ms(), alrq(), alrq_ms(), EMAN::Util::Applyws(), applyws(), Applyws(), EMAN::Util::Frngs(), frngs(), EMAN::Util::Frngs_inv(), EMAN::Util::Polar2D(), EMAN::Util::Polar2Dm(), and EMAN::Util::Polar2Dmi().
#define circ1 | ( | i | ) | circ1[i-1] |
Definition at line 3183 of file util_sparx.cpp.
Referenced by EMAN::Util::Crosrng_e(), crosrng_e(), EMAN::Util::Crosrng_ew(), EMAN::Util::Crosrng_ms(), crosrng_ms(), EMAN::Util::Crosrng_ms_delta(), EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_m(), EMAN::Util::Crosrng_msg_s(), EMAN::Util::Crosrng_msg_vec(), EMAN::Util::Crosrng_msg_vec_p(), EMAN::Util::Crosrng_ns(), EMAN::Util::Crosrng_psi(), and EMAN::Util::Crosrng_sm_psi().
#define circ1b | ( | i | ) | circ1b[i-1] |
Definition at line 4108 of file util_sparx.cpp.
#define circ1b | ( | i | ) | circ1b[i-1] |
Definition at line 4108 of file util_sparx.cpp.
Referenced by EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_m(), EMAN::Util::Crosrng_msg_s(), and EMAN::Util::Crosrng_msg_vec().
#define circ2 | ( | i | ) | circ2[i-1] |
Definition at line 3184 of file util_sparx.cpp.
Referenced by EMAN::Util::Crosrng_e(), crosrng_e(), EMAN::Util::Crosrng_ew(), EMAN::Util::Crosrng_ms(), crosrng_ms(), EMAN::Util::Crosrng_ms_delta(), EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_m(), EMAN::Util::Crosrng_msg_s(), EMAN::Util::Crosrng_msg_vec(), EMAN::Util::Crosrng_msg_vec_p(), EMAN::Util::Crosrng_ns(), EMAN::Util::Crosrng_psi(), and EMAN::Util::Crosrng_sm_psi().
#define circ2b | ( | i | ) | circ2b[i-1] |
Definition at line 4109 of file util_sparx.cpp.
#define circ2b | ( | i | ) | circ2b[i-1] |
Definition at line 4109 of file util_sparx.cpp.
Referenced by EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_m(), EMAN::Util::Crosrng_msg_s(), and EMAN::Util::Crosrng_msg_vec().
#define CP | ( | i | ) | CP [i-1] |
#define data | ( | i, | |||
j | ) | group[i*ny+j] |
Definition at line 20765 of file util_sparx.cpp.
Referenced by EMAN::EMData::absi(), EMAN::EMData::add(), EMAN::file_store::add_image(), EMAN::AbsMaxMinAverager::add_image(), EMAN::TomoAverager::add_image(), EMAN::EMData::addsquare(), EMAN::Refine3DAlignerGrid::align(), EMAN::RotateTranslateFlipAlignerPawel::align(), EMAN::RotateTranslateAlignerPawel::align(), EMAN::RotationalAlignerIterative::align(), EMAN::RotatePrecenterAligner::align(), EMAN::TranslationalAligner::align(), EMAN::RotationalAligner::align_180_ambiguous(), EMAN::EMData::amplitude(), EMAN::EMData::apply_radial_func(), EMAN::EMData::calc_az_dist(), EMAN::EMData::calc_center_of_mass(), EMAN::EMData::calc_highest_locations(), EMAN::EMData::calc_hist(), EMAN::MaskEdgeMeanProcessor::calc_locals(), EMAN::EMData::calc_max_location(), EMAN::EMData::calc_min_location(), EMAN::EMData::calc_n_highest_locations(), EMAN::EMData::calc_radial_dist(), EMAN::BoxingTools::classify(), EMAN::EMData::common_lines(), EMAN::EMData::common_lines_real(), EMAN::Util::cyclicshift(), EMAN::PointArray::distmx(), EMAN::EMData::div(), EMAN::EMData::do_ift_inplace(), EMAN::EMData::EMData(), EMAN::EMData::get_attr(), EMAN::EMData::get_circle_mean(), get_data_as_vector(), EMAN::EMData::get_edge_mean(), EMAN::EMData::get_fft_amplitude(), EMAN::EMData::get_fft_phase(), EMAN::file_store::get_image(), EMAN::newfile_store::get_image(), EMAN::Util::histc(), EMAN::EMData::imag(), EMAN::ImagicIO2::init_test(), EMAN::EMData::insert_scaled_sum(), EMAN::SingleSpiderIO::is_valid(), EMAN::SpiderIO::is_valid(), EMAN::SerIO::is_valid(), EMAN::PifIO::is_valid(), EMAN::OmapIO::is_valid(), EMAN::MrcIO::is_valid(), EMAN::ImagicIO2::is_valid(), EMAN::ImagicIO::is_valid(), EMAN::IcosIO::is_valid(), EMAN::Gatan2IO::is_valid(), EMAN::EmIO::is_valid(), EMAN::EmimIO::is_valid(), EMAN::DM4IO::is_valid(), EMAN::DM3IO::is_valid(), EMAN::EMData::little_big_dot(), EMAN::EMData::log(), EMAN::EMData::log10(), main(), EMAN::TestUtil::make_image_file_by_mode(), mpi_bcast_recv(), mpi_bcast_send(), mpi_init(), mpi_recv(), mpi_send(), mpi_start(), EMAN::EMData::mult(), EMAN::EMData::mult_complex_efficient(), EMAN::Util::Normalize_ring(), EMAN::EMData::operator=(), EMAN::EMData::phase(), EMAN::XYZProcessor::process_inplace(), EMAN::CutoffBlockProcessor::process_inplace(), EMAN::DiffBlockProcessor::process_inplace(), EMAN::BoxStatProcessor::process_inplace(), EMAN::AreaProcessor::process_inplace(), EMAN::ComplexPixelProcessor::process_inplace(), EMAN::ToMinvalProcessor::process_inplace(), EMAN::CoordinateProcessor::process_inplace(), EMAN::RealPixelProcessor::process_inplace(), EMAN::LowpassRandomPhaseProcessor::process_inplace(), EMAN::ImageProcessor::process_inplace(), EMAN::BoxMedianProcessor::process_pixel(), EMAN::GaussFFTProjector::project3d(), EMAN::GatanDM4::TagData::read_array_data(), EMAN::Gatan::TagData::read_array_data(), EMAN::EMData::real(), EMAN::EMData::render_amp24(), EMAN::EMData::render_ap24(), EMAN::EMData::ri2ap(), EMAN::EMData::ri2inten(), EMAN::EMData::rotate_x(), EMAN::Isosurface::set_data(), EMAN::MarchingCubes::setCmapData(), EMAN::BoxSVDClassifier::setDims(), EMAN::EMData::setup4slice(), EMAN::EMData::sqrt(), EMAN::EMData::sub(), EMAN::EMData::subsquare(), EMAN::EMData::to_value(), EMAN::EMData::update_stat(), EMAN::Util::vareas(), EMAN::TestUtil::verify_image_file_by_mode(), EMAN::EMUtil::vertical_acf(), wustl_mm::SkeletonMaker::VolumeData::VolumeData(), EMAN::RT3DSphereAligner::xform_align_nbest(), and EMAN::RT3DGridAligner::xform_align_nbest().
#define deg_rad QUADPI/180.0 |
Definition at line 4469 of file util_sparx.cpp.
Referenced by EMAN::Util::cml_init_rot(), EMAN::Util::cml_line_in3d(), and EMAN::Util::cml_update_rot().
#define deg_to_rad quadpi/180 |
Definition at line 7066 of file util_sparx.cpp.
#define dgr_to_rad quadpi/180 |
Definition at line 7065 of file util_sparx.cpp.
Referenced by EMAN::Util::ang_to_xyz(), apmq(), aprq2d(), EMAN::Util::even_angles(), and EMAN::ChaoProjector::setdm().
#define DGR_TO_RAD QUADPI/180 |
Definition at line 5552 of file util_sparx.cpp.
#define DM | ( | I | ) | DM [I-1] |
Definition at line 5553 of file util_sparx.cpp.
Referenced by EMAN::Util::BPCQ(), and EMAN::Util::CANG().
#define dout | ( | i, | |||
j | ) | dout[i+maxrin*j] |
Definition at line 4107 of file util_sparx.cpp.
#define dout | ( | i, | |||
j | ) | dout[i+maxrin*j] |
Definition at line 4107 of file util_sparx.cpp.
Referenced by EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_m(), and EMAN::Util::Crosrng_msg_s().
#define FALSE 0 |
#define FALSE_ (0) |
Definition at line 7772 of file util_sparx.cpp.
#define fdata | ( | i, | |||
j | ) | fdata[ i-1 + (j-1)*nxdata ] |
Definition at line 715 of file util_sparx.cpp.
#define fdata | ( | i, | |||
j | ) | fdata[ i-1 + (j-1)*nxdata ] |
Definition at line 715 of file util_sparx.cpp.
Referenced by EMAN::Util::quadri(), quadri(), and EMAN::Util::quadri_background().
Definition at line 19972 of file util_sparx.cpp.
Referenced by EMAN::Util::addn_img(), EMAN::Util::divn_filter(), EMAN::Util::divn_img(), EMAN::Util::madn_scalar(), EMAN::Util::move_points(), EMAN::Util::muln_img(), EMAN::Util::mult_scalar(), and EMAN::Util::subn_img().
Definition at line 19971 of file util_sparx.cpp.
#define img_ptr | ( | i, | |||
j, | |||||
k | ) | img_ptr[2*(i-1)+((j-1)+((k-1)*ny))*(size_t)nxo] |
Definition at line 19971 of file util_sparx.cpp.
Referenced by EMAN::Util::add_img(), EMAN::Util::add_img2(), EMAN::Util::add_img_abs(), EMAN::Util::addn_img(), EMAN::Util::compress_image_mask(), EMAN::Util::div_filter(), EMAN::Util::div_img(), EMAN::Util::divn_filter(), EMAN::Util::divn_img(), EMAN::Util::hist_comp_freq(), EMAN::Util::mad_scalar(), EMAN::Util::madn_scalar(), EMAN::Util::move_points(), EMAN::Util::mul_img(), EMAN::Util::mul_scalar(), EMAN::Util::muln_img(), EMAN::Util::mult_scalar(), EMAN::Util::pack_complex_to_real(), ReadStackandDist(), ReadStackandDist_Cart(), EMAN::Util::reconstitute_image_mask(), EMAN::Util::set_line(), EMAN::Util::sub_img(), and EMAN::Util::subn_img().
Definition at line 5222 of file util_sparx.cpp.
Definition at line 5222 of file util_sparx.cpp.
Referenced by EMAN::Util::pad(), and EMAN::Util::window().
#define key | ( | i | ) | key [i-1] |
Definition at line 7079 of file util_sparx.cpp.
Referenced by EMAN::EMUtil::getRenderMinMax(), EMAN::Util::hsortd(), mpi_comm_split(), EMAN::Log::vlog(), EMAN::Util::voronoi(), and EMAN::Util::vrdg().
#define lband | ( | i | ) | lband [i-1] |
Definition at line 7076 of file util_sparx.cpp.
#define mymax | ( | x, | |||
y | ) | (((x)>(y))?(x):(y)) |
Definition at line 7059 of file util_sparx.cpp.
#define mymin | ( | x, | |||
y | ) | (((x)<(y))?(x):(y)) |
Definition at line 7060 of file util_sparx.cpp.
#define new_ptr | ( | iptr, | |||
jptr, | |||||
kptr | ) | new_ptr[iptr+(jptr+(kptr*new_ny))*(size_t)new_nx] |
Definition at line 5118 of file util_sparx.cpp.
Referenced by EMAN::Util::compress_image_mask(), EMAN::Util::decimate(), and EMAN::Util::reconstitute_image_mask().
#define numr | ( | i, | |||
j | ) | numr[(j-1)*3 + i-1] |
Definition at line 2140 of file util_sparx.cpp.
Referenced by ali3d_d(), alprbs(), EMAN::Util::alrl_ms(), alrq(), alrq_ms(), apmd(), apmq(), applyws(), apring1(), aprq2d(), EMAN::Util::Crosrng_e(), crosrng_e(), EMAN::Util::Crosrng_ew(), EMAN::Util::Crosrng_ms(), crosrng_ms(), EMAN::Util::Crosrng_ms_delta(), EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_m(), EMAN::Util::Crosrng_msg_s(), EMAN::Util::Crosrng_msg_vec(), EMAN::Util::Crosrng_ns(), EMAN::Util::Crosrng_psi(), EMAN::Util::Crosrng_sm_psi(), EMAN::Util::ener(), EMAN::Util::ener_tot(), EMAN::Util::Frngs(), frngs(), EMAN::Util::Frngs_inv(), numrinit(), Numrinit(), EMAN::Util::Polar2D(), EMAN::Util::Polar2Dm(), EMAN::Util::Polar2Dmi(), ringwe(), EMAN::Util::sub_fav(), and EMAN::Util::update_fav().
#define outp | ( | i, | |||
j, | |||||
k | ) | outp[(i+new_st_x)+((j+new_st_y)+((k+new_st_z)*new_ny))*(size_t)new_nx] |
Definition at line 5223 of file util_sparx.cpp.
#define outp | ( | i, | |||
j, | |||||
k | ) | outp[i+(j+(k*new_ny))*(size_t)new_nx] |
Definition at line 5223 of file util_sparx.cpp.
Referenced by EMAN::Util::pad(), and EMAN::Util::window().
#define phi | ( | i | ) | phi [i-1] |
Definition at line 7074 of file util_sparx.cpp.
Referenced by EMAN::file_store::add_image(), EMAN::OrientationGenerator::add_orientation(), ali3d_d(), EMAN::Refine3DAlignerGrid::align(), EMAN::SymAlignProcessor::align(), EMAN::PawelProjector::backproject3d(), EMAN::ChaoProjector::backproject3d(), EMAN::Util::even_angles(), fcalc(), fgcalc(), EMAN::RandomOrientationGenerator::gen_orientations(), EMAN::file_store::get_image(), EMAN::Transform::get_rotation(), EMAN::Util::hsortd(), LBD_Cart(), main(), EMAN::Util::multiref_polar_ali_2d_local(), EMAN::Util::multiref_polar_ali_2d_local_psi(), EMAN::Util::multiref_polar_ali_helical_90_local(), EMAN::Util::multiref_polar_ali_helical_local(), EMAN::TestImageSinewave::process_inplace(), EMAN::ChaoProjector::project3d(), EMAN::FourierGriddingProjector::project3d(), recons3d_4nn(), recons3d_CGLS_mpi_Cart(), recons3d_HyBR_mpi_Cart(), recons3d_sirt_mpi(), recons3d_sirt_mpi_Cart(), EMAN::Transform::set_rotation(), EMAN::ChaoProjector::setdm(), slaed4_(), trans_(), unified(), EMAN::Util::vrdg(), EMAN::RT3DSphereAligner::xform_align_nbest(), and EMAN::RT3DGridAligner::xform_align_nbest().
#define PI2 QUADPI*2 |
Definition at line 4468 of file util_sparx.cpp.
#define PI2 2*QUADPI |
Definition at line 4468 of file util_sparx.cpp.
Referenced by EMAN::Util::cml_weights(), EMAN::Util::ener(), EMAN::Util::ener_tot(), EMAN::Util::sub_fav(), and EMAN::Util::update_fav().
#define PROJ | ( | i, | |||
j | ) | PROJptr [i-1+((j-1)*NNNN)] |
Definition at line 5904 of file util_sparx.cpp.
#define PROJ | ( | i, | |||
j | ) | PROJptr [i+(j)*NNNN] |
Definition at line 5904 of file util_sparx.cpp.
Referenced by EMAN::Util::WTF(), and EMAN::Util::WTM().
#define q | ( | i | ) | q[i-1] |
Definition at line 3186 of file util_sparx.cpp.
Referenced by EMAN::Util::cluster_pairwise(), EMAN::Quaternion::create_inverse(), EMAN::Util::Crosrng_e(), crosrng_e(), EMAN::Util::Crosrng_ew(), EMAN::Util::Crosrng_ms(), crosrng_ms(), EMAN::Util::Crosrng_ms_delta(), EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_s(), EMAN::Util::Crosrng_msg_vec(), EMAN::Util::Crosrng_ns(), EMAN::Util::Crosrng_psi(), EMAN::Util::Crosrng_sm_psi(), dcstep_(), GCVmin_Tik(), EMAN::Util::getBaldwinGridWeights(), EMAN::Util::group_proj_by_phitheta(), inside_(), EMAN::Quaternion::interpolate(), EMAN::Util::list_mutation(), EMAN::Util::nonconvex(), EMAN::operator *(), EMAN::Quaternion::operator *=(), EMAN::operator+(), EMAN::Quaternion::operator+=(), EMAN::operator-(), EMAN::Quaternion::operator-=(), EMAN::operator/(), EMAN::Quaternion::operator/=(), EMAN::Util::pw_extract(), EMAN::Quaternion::Quaternion(), EMAN::PointArray::read_from_pdb(), recons3d_CGLS_mpi_Cart(), refalin3d_perturbquat(), EMAN::Quaternion::to_angle(), EMAN::Quaternion::to_axis(), trfind_(), and EMAN::Util::WTF().
#define quadpi 3.141592653589793238462643383279502884197 |
#define QUADPI 3.141592653589793238462643383279502884197 |
Definition at line 5551 of file util_sparx.cpp.
#define QUADPI 3.141592653589793238462643383279502884197 |
Definition at line 5551 of file util_sparx.cpp.
#define QUADPI 3.141592653589793238462643383279502884197 |
Definition at line 5551 of file util_sparx.cpp.
#define rad_deg 180.0/QUADPI |
Definition at line 4470 of file util_sparx.cpp.
Referenced by EMAN::Util::cml_line_in3d(), EMAN::Util::cml_line_insino(), and EMAN::Util::cml_line_insino_all().
#define rad_to_deg 180/quadpi |
Definition at line 7067 of file util_sparx.cpp.
#define rad_to_dgr 180/quadpi |
Definition at line 7068 of file util_sparx.cpp.
#define RI | ( | i, | |||
j | ) | RI [(i-1) + ((j-1)*3)] |
#define sign | ( | x, | |||
y | ) | (((((y)>0)?(1):(-1))*(y!=0))*(x)) |
Definition at line 7061 of file util_sparx.cpp.
Referenced by EMAN::Processor::EMFourierFilterFunc(), EMAN::nnSSNR_ctfReconstructor::setup(), EMAN::nn4_ctf_rectReconstructor::setup(), and EMAN::nn4_ctfReconstructor::setup().
#define SS | ( | I, | |||
J | ) | SS [I-1 + (J-1)*6] |
Definition at line 5905 of file util_sparx.cpp.
#define SS | ( | i, | |||
j | ) | SS [i+(j)*6] |
Definition at line 5905 of file util_sparx.cpp.
#define SS | ( | I | ) | SS [I-1] |
Definition at line 5905 of file util_sparx.cpp.
Referenced by EMAN::Util::CANG(), EMAN::Util::WTF(), and EMAN::Util::WTM().
#define t | ( | i | ) | t[i-1] |
Definition at line 3185 of file util_sparx.cpp.
Referenced by EMAN::OrientationGenerator::add_orientation(), EMAN::Util::ali2d_ccf_list(), EMAN::RT3DSphereAligner::align(), EMAN::RT3DGridAligner::align(), EMAN::Refine3DAlignerGrid::align(), EMAN::Refine3DAlignerQuaternion::align(), EMAN::SymAlignProcessorQuat::align(), EMAN::RefineAlignerCG::align(), EMAN::RefineAligner::align(), EMAN::SymAlignProcessor::align(), EMAN::RTFSlowExhaustiveAligner::align(), EMAN::RTFExhaustiveAligner::align(), EMAN::RotateFlipAlignerIterative::align(), EMAN::RotateFlipAligner::align(), EMAN::RotateTranslateFlipAlignerIterative::align(), EMAN::RotateTranslateFlipAligner::align(), EMAN::RotateTranslateAligner::align(), EMAN::RotateTranslateAlignerIterative::align(), EMAN::TranslationalAligner::align(), EMAN::ScaleAligner::align(), EMAN::ScaleAlignerABS::align_using_base(), EMAN::Util::array_mutation(), bmv_(), EMAN::Symmetry3D::cache_au_planes(), EMAN::EMData::calc_max_location(), EMAN::EMData::calc_min_location(), EMAN::EMData::calc_mutual_correlation(), EMAN::EMData::common_lines_real(), EMAN::Util::constrained_helix(), EMAN::Util::constrained_helix_test(), crlist_(), EMAN::Util::Crosrng_e(), crosrng_e(), EMAN::Util::Crosrng_ew(), EMAN::Util::Crosrng_ms(), crosrng_ms(), EMAN::Util::Crosrng_ms_delta(), EMAN::Util::Crosrng_msg(), EMAN::Util::Crosrng_msg_m(), EMAN::Util::Crosrng_msg_vec(), EMAN::Util::Crosrng_psi(), EMAN::EMData::cut_slice(), EMAN::EMData::do_radon(), EMAN::EMData::dot_rotate_translate(), EMAN::TestUtil::emobject_to_py(), EMAN::TestUtil::emobject_transformarray_to_py(), EMAN::EMData::extract_box(), EMAN::Util::fftc_d(), fftc_d(), EMAN::Util::fftc_q(), fftc_q(), EMAN::Util::fftr_d(), fftr_d(), EMAN::Util::fftr_q(), fftr_q(), formk_(), EMAN::RandomOrientationGenerator::gen_orientations(), EMAN::EmanOrientationGenerator::gen_orientations(), EMAN::TetrahedralSym::get_asym_unit_points(), EMAN::PlatonicSym::get_asym_unit_points(), EMAN::EMData::get_attr(), EMAN::ImagicIO2::get_datatype_from_name(), EMAN::ImagicIO::get_datatype_from_name(), EMAN::TestUtil::get_debug_transform(), EMAN::Transform::get_sym_proj(), EMAN::Util::get_time_label(), EMAN::Symmetry3D::get_touching_au_transforms(), EMAN::Transform::icos_5_to_2(), EMAN::nnSSNR_ctfReconstructor::insert_padfft_slice(), EMAN::nn4_ctf_rectReconstructor::insert_padfft_slice(), EMAN::nn4_ctfReconstructor::insert_padfft_slice(), EMAN::nnSSNR_Reconstructor::insert_padfft_slice(), EMAN::nn4_rectReconstructor::insert_padfft_slice(), EMAN::nn4Reconstructor::insert_padfft_slice(), EMAN::nnSSNR_ctfReconstructor::insert_slice(), EMAN::nn4_ctf_rectReconstructor::insert_slice(), EMAN::nn4_ctfReconstructor::insert_slice(), EMAN::nnSSNR_Reconstructor::insert_slice(), EMAN::nn4_rectReconstructor::insert_slice(), EMAN::nn4Reconstructor::insert_slice(), EMAN::BackProjectionReconstructor::insert_slice(), intrsc_(), EMAN::Transform::inverse(), EMAN::Vec2< Type >::length(), EMAN::Vec3< Type >::length(), EMAN::Vec4< Type >::length(), EMAN::Util::list_mutation(), main(), EMAN::EMData::max_3D_pixel_error(), EMAN::Util::multiref_polar_ali_2d_local(), EMAN::Util::multiref_polar_ali_2d_local_psi(), EMAN::Util::multiref_polar_ali_helical_90_local(), EMAN::Util::multiref_polar_ali_helical_local(), EMAN::Transform::negate(), EMAN::FloatPoint::operator vector(), EMAN::FloatSize::operator vector(), EMAN::padfft_slice(), EMAN::Symmetry3D::point_in_which_asym_unit(), EMAN::Util::point_is_in_triangle_2d(), EMAN::PawelProjector::prepcubes(), EMAN::BackProjectionReconstructor::preprocess_slice(), EMAN::FourierReconstructor::preprocess_slice(), EMAN::Randnum::print_generator_type(), EMAN::ScaleTransformProcessor::process(), EMAN::TransformProcessor::process(), EMAN::ApplySymProcessor::process(), EMAN::TomoTiltEdgeMaskProcessor::process_inplace(), EMAN::TestTomoImage::process_inplace(), EMAN::Rotate180Processor::process_inplace(), EMAN::ScaleTransformProcessor::process_inplace(), EMAN::TransformProcessor::process_inplace(), EMAN::TestImageEllipse::process_inplace(), EMAN::TestImageHollowEllipse::process_inplace(), EMAN::IterBinMaskProcessor::process_inplace(), EMAN::AutoMask3DProcessor::process_inplace(), EMAN::SymSearchProcessor::process_inplace(), EMAN::ACFCenterProcessor::process_inplace(), EMAN::PhaseToMassCenterProcessor::process_inplace(), EMAN::ToMassCenterProcessor::process_inplace(), EMAN::FlipProcessor::process_inplace(), EMAN::NormalizeToLeastSquareProcessor::process_inplace(), EMAN::CutoffBlockProcessor::process_inplace(), EMAN::ImageProcessor::process_inplace(), EMAN::BoxMedianProcessor::process_pixel(), EMAN::MaxValProjector::project3d(), EMAN::StandardProjector::project3d(), EMAN::Symmetry3D::reduce(), refalifn(), refalifn3dquat(), EMAN::EMData::render_amp24(), EMAN::EMData::render_ap24(), EMAN::EMData::rotate(), EMAN::Util::rotate_phase_origin(), EMAN::EMData::rotate_translate(), EMAN::Matrix4::rotation(), EMAN::EMData::scale(), EMAN::EMData::set_attr_python(), setulb_(), slaed2_(), slaed8_(), slamch_(), slasq2_(), slasq3_(), slasv2_(), sormlq_(), sormqr_(), subsm_(), symquat(), test_shared_pointer(), EMAN::Transform::tet_3_to_2(), EMAN::GatanDM4::to_em_datatype(), EMAN::Gatan::to_em_datatype(), EMAN::TransformProcessor::transform(), EMAN::EMData::translate(), EMAN::Transform::transpose(), trplot_(), EMAN::EMData::unwrap(), EMAN::EMData::unwrap_largerR(), varmx(), vrplot_(), EMAN::SpiderIO::write_single_header(), EMAN::RT3DSymmetryAligner::xform_align_nbest(), EMAN::RT3DSphereAligner::xform_align_nbest(), and EMAN::RT3DGridAligner::xform_align_nbest().
#define t7 | ( | i | ) | t7[i-1] |
Definition at line 3188 of file util_sparx.cpp.
Referenced by EMAN::Util::Crosrng_e(), crosrng_e(), EMAN::Util::Crosrng_ew(), EMAN::Util::Crosrng_ms(), crosrng_ms(), and EMAN::Util::Crosrng_ns().
#define tab1 | ( | i | ) | tab1[i-1] |
Definition at line 2619 of file util_sparx.cpp.
Referenced by EMAN::Util::fftc_d(), fftc_d(), EMAN::Util::fftc_q(), fftc_q(), EMAN::Util::fftr_d(), fftr_d(), EMAN::Util::fftr_q(), and fftr_q().
#define theta | ( | i | ) | theta [i-1] |
Definition at line 7073 of file util_sparx.cpp.
Referenced by ali3d_d(), EMAN::PawelProjector::backproject3d(), EMAN::ChaoProjector::backproject3d(), EMAN::Util::even_angles(), fcalc(), fgcalc(), EMAN::file_store::get_image(), EMAN::Util::hsortd(), LBD_Cart(), main(), mainlb_(), EMAN::Util::multiref_polar_ali_2d_local(), EMAN::Util::multiref_polar_ali_2d_local_psi(), EMAN::Util::multiref_polar_ali_helical_90_local(), EMAN::Util::multiref_polar_ali_helical_local(), EMAN::ChaoProjector::project3d(), EMAN::FourierGriddingProjector::project3d(), recons3d_4nn(), recons3d_CGLS_mpi_Cart(), recons3d_HyBR_mpi_Cart(), recons3d_sirt_mpi(), recons3d_sirt_mpi_Cart(), EMAN::Transform::set_rotation(), EMAN::ChaoProjector::setdm(), trans_(), unified(), and EMAN::Util::vrdg().
#define thetast | ( | i | ) | thetast [i-1] |
Definition at line 7078 of file util_sparx.cpp.
#define TRUE 1 |
Definition at line 7069 of file util_sparx.cpp.
#define TRUE_ (1) |
Definition at line 7771 of file util_sparx.cpp.
#define ts | ( | i | ) | ts [i-1] |
Definition at line 7077 of file util_sparx.cpp.
#define VP | ( | i | ) | VP [i-1] |
#define VV | ( | i | ) | VV [i-1] |
#define W | ( | i, | |||
j | ) | Wptr [i-1+((j-1)*Wnx)] |
Definition at line 5903 of file util_sparx.cpp.
#define W | ( | i, | |||
j | ) | Wptr [i+(j)*Wnx] |
Definition at line 5903 of file util_sparx.cpp.
Referenced by EMAN::Util::getBaldwinGridWeights(), EMAN::Util::WTF(), and EMAN::Util::WTM().
#define weight | ( | i | ) | weight [i-1] |
Definition at line 7075 of file util_sparx.cpp.
Referenced by EMAN::FourierWeightAverager::add_image(), ali3d_d(), EMAN::FRCCmp::cmp(), EMAN::WienerFourierReconstructor::do_insert_slice_work(), EMAN::BackProjectionReconstructor::insert_slice(), and EMAN::Util::vrdg().
#define xcmplx | ( | i, | |||
j | ) | xcmplx [(j-1)*2 + i-1] |
Definition at line 2620 of file util_sparx.cpp.
Referenced by EMAN::Util::fftr_d(), fftr_d(), EMAN::Util::fftr_q(), and fftr_q().
#define xim | ( | i, | |||
j | ) | xim[(j-1)*nsam + i-1] |
Definition at line 2141 of file util_sparx.cpp.
Referenced by EMAN::Util::bilinear(), EMAN::Util::Polar2D(), and EMAN::Util::Polar2Dm().
int addnod_ | ( | int * | , | |
int * | , | |||
double * | , | |||
double * | , | |||
double * | , | |||
int * | , | |||
int * | , | |||
int * | , | |||
int * | , | |||
int * | ||||
) |
Definition at line 8219 of file util_sparx.cpp.
References abs, bdyadd_(), covsph_(), intadd_(), lstptr_(), swap_(), swptst_(), and trfind_().
Referenced by trmesh_(), and EMAN::Util::trmsh3_().
08222 { 08223 /* Initialized data */ 08224 08225 static double tol = 0.; 08226 08227 /* System generated locals */ 08228 int i__1; 08229 08230 /* Local variables */ 08231 static int l; 08232 static double p[3], b1, b2, b3; 08233 static int i1, i2, i3, kk, lp, in1, io1, io2, km1, lpf, ist, lpo1; 08234 /* Subroutine */ int swap_(int *, int *, int *, 08235 int *, int *, int *, int *, int *); 08236 static int lpo1s; 08237 /* Subroutine */ int bdyadd_(int *, int *, int *, 08238 int *, int *, int *, int *), intadd_(int *, 08239 int *, int *, int *, int *, int *, int *, 08240 int *), trfind_(int *, double *, int *, 08241 double *, double *, double *, int *, int *, 08242 int *, double *, double *, double *, int *, 08243 int *, int *), covsph_(int *, int *, int *, 08244 int *, int *, int *); 08245 int lstptr_(int *, int *, int *, int *); 08246 long int swptst_(int *, int *, int *, int *, 08247 double *, double *, double *); 08248 08249 08250 /* *********************************************************** */ 08251 08252 /* From STRIPACK */ 08253 /* Robert J. Renka */ 08254 /* Dept. of Computer Science */ 08255 /* Univ. of North Texas */ 08256 /* renka@cs.unt.edu */ 08257 /* 01/08/03 */ 08258 08259 /* This subroutine adds node K to a triangulation of the */ 08260 /* convex hull of nodes 1,...,K-1, producing a triangulation */ 08261 /* of the convex hull of nodes 1,...,K. */ 08262 08263 /* The algorithm consists of the following steps: node K */ 08264 /* is located relative to the triangulation (TRFIND), its */ 08265 /* index is added to the data structure (INTADD or BDYADD), */ 08266 /* and a sequence of swaps (SWPTST and SWAP) are applied to */ 08267 /* the arcs opposite K so that all arcs incident on node K */ 08268 /* and opposite node K are locally optimal (satisfy the cir- */ 08269 /* cumcircle test). Thus, if a Delaunay triangulation is */ 08270 /* input, a Delaunay triangulation will result. */ 08271 08272 08273 /* On input: */ 08274 08275 /* NST = Index of a node at which TRFIND begins its */ 08276 /* search. Search time depends on the proximity */ 08277 /* of this node to K. If NST < 1, the search is */ 08278 /* begun at node K-1. */ 08279 08280 /* K = Nodal index (index for X, Y, Z, and LEND) of the */ 08281 /* new node to be added. K .GE. 4. */ 08282 08283 /* X,Y,Z = Arrays of length .GE. K containing Car- */ 08284 /* tesian coordinates of the nodes. */ 08285 /* (X(I),Y(I),Z(I)) defines node I for */ 08286 /* I = 1,...,K. */ 08287 08288 /* The above parameters are not altered by this routine. */ 08289 08290 /* LIST,LPTR,LEND,LNEW = Data structure associated with */ 08291 /* the triangulation of nodes 1 */ 08292 /* to K-1. The array lengths are */ 08293 /* assumed to be large enough to */ 08294 /* add node K. Refer to Subrou- */ 08295 /* tine TRMESH. */ 08296 08297 /* On output: */ 08298 08299 /* LIST,LPTR,LEND,LNEW = Data structure updated with */ 08300 /* the addition of node K as the */ 08301 /* last entry unless IER .NE. 0 */ 08302 /* and IER .NE. -3, in which case */ 08303 /* the arrays are not altered. */ 08304 08305 /* IER = Error indicator: */ 08306 /* IER = 0 if no errors were encountered. */ 08307 /* IER = -1 if K is outside its valid range */ 08308 /* on input. */ 08309 /* IER = -2 if all nodes (including K) are col- */ 08310 /* linear (lie on a common geodesic). */ 08311 /* IER = L if nodes L and K coincide for some */ 08312 /* L < K. Refer to TOL below. */ 08313 08314 /* Modules required by ADDNOD: BDYADD, COVSPH, INSERT, */ 08315 /* INTADD, JRAND, LSTPTR, */ 08316 /* STORE, SWAP, SWPTST, */ 08317 /* TRFIND */ 08318 08319 /* Intrinsic function called by ADDNOD: ABS */ 08320 08321 /* *********************************************************** */ 08322 08323 08324 /* Local parameters: */ 08325 08326 /* B1,B2,B3 = Unnormalized barycentric coordinates returned */ 08327 /* by TRFIND. */ 08328 /* I1,I2,I3 = Vertex indexes of a triangle containing K */ 08329 /* IN1 = Vertex opposite K: first neighbor of IO2 */ 08330 /* that precedes IO1. IN1,IO1,IO2 are in */ 08331 /* counterclockwise order. */ 08332 /* IO1,IO2 = Adjacent neighbors of K defining an arc to */ 08333 /* be tested for a swap */ 08334 /* IST = Index of node at which TRFIND begins its search */ 08335 /* KK = Local copy of K */ 08336 /* KM1 = K-1 */ 08337 /* L = Vertex index (I1, I2, or I3) returned in IER */ 08338 /* if node K coincides with a vertex */ 08339 /* LP = LIST pointer */ 08340 /* LPF = LIST pointer to the first neighbor of K */ 08341 /* LPO1 = LIST pointer to IO1 */ 08342 /* LPO1S = Saved value of LPO1 */ 08343 /* P = Cartesian coordinates of node K */ 08344 /* TOL = Tolerance defining coincident nodes: bound on */ 08345 /* the deviation from 1 of the cosine of the */ 08346 /* angle between the nodes. */ 08347 /* Note that |1-cos(A)| is approximately A*A/2. */ 08348 08349 /* Parameter adjustments */ 08350 --lend; 08351 --z__; 08352 --y; 08353 --x; 08354 --list; 08355 --lptr; 08356 08357 /* Function Body */ 08358 08359 kk = *k; 08360 if (kk < 4) { 08361 goto L3; 08362 } 08363 08364 /* Initialization: */ 08365 km1 = kk - 1; 08366 ist = *nst; 08367 if (ist < 1) { 08368 ist = km1; 08369 } 08370 p[0] = x[kk]; 08371 p[1] = y[kk]; 08372 p[2] = z__[kk]; 08373 08374 /* Find a triangle (I1,I2,I3) containing K or the rightmost */ 08375 /* (I1) and leftmost (I2) visible boundary nodes as viewed */ 08376 /* from node K. */ 08377 trfind_(&ist, p, &km1, &x[1], &y[1], &z__[1], &list[1], &lptr[1], &lend[1] 08378 , &b1, &b2, &b3, &i1, &i2, &i3); 08379 08380 /* Test for collinear or (nearly) duplicate nodes. */ 08381 08382 if (i1 == 0) { 08383 goto L4; 08384 } 08385 l = i1; 08386 if (p[0] * x[l] + p[1] * y[l] + p[2] * z__[l] >= 1. - tol) { 08387 goto L5; 08388 } 08389 l = i2; 08390 if (p[0] * x[l] + p[1] * y[l] + p[2] * z__[l] >= 1. - tol) { 08391 goto L5; 08392 } 08393 if (i3 != 0) { 08394 l = i3; 08395 if (p[0] * x[l] + p[1] * y[l] + p[2] * z__[l] >= 1. - tol) { 08396 goto L5; 08397 } 08398 intadd_(&kk, &i1, &i2, &i3, &list[1], &lptr[1], &lend[1], lnew); 08399 } else { 08400 if (i1 != i2) { 08401 bdyadd_(&kk, &i1, &i2, &list[1], &lptr[1], &lend[1], lnew); 08402 } else { 08403 covsph_(&kk, &i1, &list[1], &lptr[1], &lend[1], lnew); 08404 } 08405 } 08406 *ier = 0; 08407 08408 /* Initialize variables for optimization of the */ 08409 /* triangulation. */ 08410 lp = lend[kk]; 08411 lpf = lptr[lp]; 08412 io2 = list[lpf]; 08413 lpo1 = lptr[lpf]; 08414 io1 = (i__1 = list[lpo1], abs(i__1)); 08415 08416 /* Begin loop: find the node opposite K. */ 08417 08418 L1: 08419 lp = lstptr_(&lend[io1], &io2, &list[1], &lptr[1]); 08420 if (list[lp] < 0) { 08421 goto L2; 08422 } 08423 lp = lptr[lp]; 08424 in1 = (i__1 = list[lp], abs(i__1)); 08425 08426 /* Swap test: if a swap occurs, two new arcs are */ 08427 /* opposite K and must be tested. */ 08428 08429 lpo1s = lpo1; 08430 if (! swptst_(&in1, &kk, &io1, &io2, &x[1], &y[1], &z__[1])) { 08431 goto L2; 08432 } 08433 swap_(&in1, &kk, &io1, &io2, &list[1], &lptr[1], &lend[1], &lpo1); 08434 if (lpo1 == 0) { 08435 08436 /* A swap is not possible because KK and IN1 are already */ 08437 /* adjacent. This error in SWPTST only occurs in the */ 08438 /* neutral case and when there are nearly duplicate */ 08439 /* nodes. */ 08440 08441 lpo1 = lpo1s; 08442 goto L2; 08443 } 08444 io1 = in1; 08445 goto L1; 08446 08447 /* No swap occurred. Test for termination and reset */ 08448 /* IO2 and IO1. */ 08449 08450 L2: 08451 if (lpo1 == lpf || list[lpo1] < 0) { 08452 return 0; 08453 } 08454 io2 = io1; 08455 lpo1 = lptr[lpo1]; 08456 io1 = (i__1 = list[lpo1], abs(i__1)); 08457 goto L1; 08458 08459 /* KK < 4. */ 08460 08461 L3: 08462 *ier = -1; 08463 return 0; 08464 08465 /* All nodes are collinear. */ 08466 08467 L4: 08468 *ier = -2; 08469 return 0; 08470 08471 /* Nodes L and K coincide. */ 08472 08473 L5: 08474 *ier = l; 08475 return 0; 08476 } /* addnod_ */
double angle_ | ( | double * | v1, | |
double * | v2, | |||
double * | v3 | |||
) |
Definition at line 8478 of file util_sparx.cpp.
References left_(), and sqrt().
Referenced by areav_new__().
08479 { 08480 /* System generated locals */ 08481 double ret_val; 08482 08483 /* Builtin functions */ 08484 //double sqrt(double), acos(double); 08485 08486 /* Local variables */ 08487 static double a; 08488 static int i__; 08489 static double ca, s21, s23, u21[3], u23[3]; 08490 08491 08492 /* *********************************************************** */ 08493 08494 /* From STRIPACK */ 08495 /* Robert J. Renka */ 08496 /* Dept. of Computer Science */ 08497 /* Univ. of North Texas */ 08498 /* renka@cs.unt.edu */ 08499 /* 06/03/03 */ 08500 08501 /* Given a sequence of three nodes (V1,V2,V3) on the sur- */ 08502 /* face of the unit sphere, this function returns the */ 08503 /* interior angle at V2 -- the dihedral angle between the */ 08504 /* plane defined by V2 and V3 (and the origin) and the plane */ 08505 /* defined by V2 and V1 or, equivalently, the angle between */ 08506 /* the normals V2 X V3 and V2 X V1. Note that the angle is */ 08507 /* in the range 0 to Pi if V3 Left V1->V2, Pi to 2*Pi other- */ 08508 /* wise. The surface area of a spherical polygon with CCW- */ 08509 /* ordered vertices V1, V2, ..., Vm is Asum - (m-2)*Pi, where */ 08510 /* Asum is the sum of the m interior angles computed from the */ 08511 /* sequences (Vm,V1,V2), (V1,V2,V3), (V2,V3,V4), ..., */ 08512 /* (Vm-1,Vm,V1). */ 08513 08514 08515 /* On input: */ 08516 08517 /* V1,V2,V3 = Arrays of length 3 containing the Carte- */ 08518 /* sian coordinates of unit vectors. These */ 08519 /* vectors, if nonzero, are implicitly */ 08520 /* scaled to have length 1. */ 08521 08522 /* Input parameters are not altered by this function. */ 08523 08524 /* On output: */ 08525 08526 /* ANGLE = Angle defined above, or 0 if V2 X V1 = 0 or */ 08527 /* V2 X V3 = 0. */ 08528 08529 /* Module required by ANGLE: LEFT */ 08530 08531 /* Intrinsic functions called by ANGLE: ACOS, SQRT */ 08532 08533 /* *********************************************************** */ 08534 08535 08536 /* Local parameters: */ 08537 08538 /* A = Interior angle at V2 */ 08539 /* CA = cos(A) */ 08540 /* I = DO-loop index and index for U21 and U23 */ 08541 /* S21,S23 = Sum of squared components of U21 and U23 */ 08542 /* U21,U23 = Unit normal vectors to the planes defined by */ 08543 /* pairs of triangle vertices */ 08544 08545 08546 /* Compute cross products U21 = V2 X V1 and U23 = V2 X V3. */ 08547 08548 /* Parameter adjustments */ 08549 --v3; 08550 --v2; 08551 --v1; 08552 08553 /* Function Body */ 08554 u21[0] = v2[2] * v1[3] - v2[3] * v1[2]; 08555 u21[1] = v2[3] * v1[1] - v2[1] * v1[3]; 08556 u21[2] = v2[1] * v1[2] - v2[2] * v1[1]; 08557 08558 u23[0] = v2[2] * v3[3] - v2[3] * v3[2]; 08559 u23[1] = v2[3] * v3[1] - v2[1] * v3[3]; 08560 u23[2] = v2[1] * v3[2] - v2[2] * v3[1]; 08561 08562 /* Normalize U21 and U23 to unit vectors. */ 08563 08564 s21 = 0.; 08565 s23 = 0.; 08566 for (i__ = 1; i__ <= 3; ++i__) { 08567 s21 += u21[i__ - 1] * u21[i__ - 1]; 08568 s23 += u23[i__ - 1] * u23[i__ - 1]; 08569 /* L1: */ 08570 } 08571 08572 /* Test for a degenerate triangle associated with collinear */ 08573 /* vertices. */ 08574 08575 if (s21 == 0. || s23 == 0.) { 08576 ret_val = 0.; 08577 return ret_val; 08578 } 08579 s21 = sqrt(s21); 08580 s23 = sqrt(s23); 08581 for (i__ = 1; i__ <= 3; ++i__) { 08582 u21[i__ - 1] /= s21; 08583 u23[i__ - 1] /= s23; 08584 /* L2: */ 08585 } 08586 08587 /* Compute the angle A between normals: */ 08588 08589 /* CA = cos(A) = <U21,U23> */ 08590 08591 ca = u21[0] * u23[0] + u21[1] * u23[1] + u21[2] * u23[2]; 08592 if (ca < -1.) { 08593 ca = -1.; 08594 } 08595 if (ca > 1.) { 08596 ca = 1.; 08597 } 08598 a = acos(ca); 08599 08600 /* Adjust A to the interior angle: A > Pi iff */ 08601 /* V3 Right V1->V2. */ 08602 08603 if (! left_(&v1[1], &v1[2], &v1[3], &v2[1], &v2[2], &v2[3], &v3[1], &v3[2] 08604 , &v3[3])) { 08605 a = acos(-1.) * 2. - a; 08606 } 08607 ret_val = a; 08608 return ret_val; 08609 } /* angle_ */
double areas_ | ( | double * | v1, | |
double * | v2, | |||
double * | v3 | |||
) |
Definition at line 8611 of file util_sparx.cpp.
References sqrt().
Referenced by EMAN::Util::areav_().
08612 { 08613 /* System generated locals */ 08614 double ret_val; 08615 08616 /* Builtin functions */ 08617 //double sqrt(double), acos(double); 08618 08619 /* Local variables */ 08620 static int i__; 08621 static double a1, a2, a3, s12, s31, s23, u12[3], u23[3], u31[3], ca1, 08622 ca2, ca3; 08623 08624 08625 /* *********************************************************** */ 08626 08627 /* From STRIPACK */ 08628 /* Robert J. Renka */ 08629 /* Dept. of Computer Science */ 08630 /* Univ. of North Texas */ 08631 /* renka@cs.unt.edu */ 08632 /* 06/22/98 */ 08633 08634 /* This function returns the area of a spherical triangle */ 08635 /* on the unit sphere. */ 08636 08637 08638 /* On input: */ 08639 08640 /* V1,V2,V3 = Arrays of length 3 containing the Carte- */ 08641 /* sian coordinates of unit vectors (the */ 08642 /* three triangle vertices in any order). */ 08643 /* These vectors, if nonzero, are implicitly */ 08644 /* scaled to have length 1. */ 08645 08646 /* Input parameters are not altered by this function. */ 08647 08648 /* On output: */ 08649 08650 /* AREAS = Area of the spherical triangle defined by */ 08651 /* V1, V2, and V3 in the range 0 to 2*PI (the */ 08652 /* area of a hemisphere). AREAS = 0 (or 2*PI) */ 08653 /* if and only if V1, V2, and V3 lie in (or */ 08654 /* close to) a plane containing the origin. */ 08655 08656 /* Modules required by AREAS: None */ 08657 08658 /* Intrinsic functions called by AREAS: ACOS, SQRT */ 08659 08660 /* *********************************************************** */ 08661 08662 08663 /* Local parameters: */ 08664 08665 /* A1,A2,A3 = Interior angles of the spherical triangle */ 08666 /* CA1,CA2,CA3 = cos(A1), cos(A2), and cos(A3), respectively */ 08667 /* I = DO-loop index and index for Uij */ 08668 /* S12,S23,S31 = Sum of squared components of U12, U23, U31 */ 08669 /* U12,U23,U31 = Unit normal vectors to the planes defined by */ 08670 /* pairs of triangle vertices */ 08671 08672 08673 /* Compute cross products Uij = Vi X Vj. */ 08674 08675 /* Parameter adjustments */ 08676 --v3; 08677 --v2; 08678 --v1; 08679 08680 /* Function Body */ 08681 u12[0] = v1[2] * v2[3] - v1[3] * v2[2]; 08682 u12[1] = v1[3] * v2[1] - v1[1] * v2[3]; 08683 u12[2] = v1[1] * v2[2] - v1[2] * v2[1]; 08684 08685 u23[0] = v2[2] * v3[3] - v2[3] * v3[2]; 08686 u23[1] = v2[3] * v3[1] - v2[1] * v3[3]; 08687 u23[2] = v2[1] * v3[2] - v2[2] * v3[1]; 08688 08689 u31[0] = v3[2] * v1[3] - v3[3] * v1[2]; 08690 u31[1] = v3[3] * v1[1] - v3[1] * v1[3]; 08691 u31[2] = v3[1] * v1[2] - v3[2] * v1[1]; 08692 08693 /* Normalize Uij to unit vectors. */ 08694 08695 s12 = 0.; 08696 s23 = 0.; 08697 s31 = 0.; 08698 for (i__ = 1; i__ <= 3; ++i__) { 08699 s12 += u12[i__ - 1] * u12[i__ - 1]; 08700 s23 += u23[i__ - 1] * u23[i__ - 1]; 08701 s31 += u31[i__ - 1] * u31[i__ - 1]; 08702 /* L2: */ 08703 } 08704 08705 /* Test for a degenerate triangle associated with collinear */ 08706 /* vertices. */ 08707 08708 if (s12 == 0. || s23 == 0. || s31 == 0.) { 08709 ret_val = 0.; 08710 return ret_val; 08711 } 08712 s12 = sqrt(s12); 08713 s23 = sqrt(s23); 08714 s31 = sqrt(s31); 08715 for (i__ = 1; i__ <= 3; ++i__) { 08716 u12[i__ - 1] /= s12; 08717 u23[i__ - 1] /= s23; 08718 u31[i__ - 1] /= s31; 08719 /* L3: */ 08720 } 08721 08722 /* Compute interior angles Ai as the dihedral angles between */ 08723 /* planes: */ 08724 /* CA1 = cos(A1) = -<U12,U31> */ 08725 /* CA2 = cos(A2) = -<U23,U12> */ 08726 /* CA3 = cos(A3) = -<U31,U23> */ 08727 08728 ca1 = -u12[0] * u31[0] - u12[1] * u31[1] - u12[2] * u31[2]; 08729 ca2 = -u23[0] * u12[0] - u23[1] * u12[1] - u23[2] * u12[2]; 08730 ca3 = -u31[0] * u23[0] - u31[1] * u23[1] - u31[2] * u23[2]; 08731 if (ca1 < -1.) { 08732 ca1 = -1.; 08733 } 08734 if (ca1 > 1.) { 08735 ca1 = 1.; 08736 } 08737 if (ca2 < -1.) { 08738 ca2 = -1.; 08739 } 08740 if (ca2 > 1.) { 08741 ca2 = 1.; 08742 } 08743 if (ca3 < -1.) { 08744 ca3 = -1.; 08745 } 08746 if (ca3 > 1.) { 08747 ca3 = 1.; 08748 } 08749 a1 = acos(ca1); 08750 a2 = acos(ca2); 08751 a3 = acos(ca3); 08752 08753 /* Compute AREAS = A1 + A2 + A3 - PI. */ 08754 08755 ret_val = a1 + a2 + a3 - acos(-1.); 08756 if (ret_val < 0.) { 08757 ret_val = 0.; 08758 } 08759 return ret_val; 08760 } /* areas_ */
double areav_new__ | ( | int * | k, | |
int * | n, | |||
double * | x, | |||
double * | y, | |||
double * | z__, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | ier | |||
) |
Definition at line 8965 of file util_sparx.cpp.
References angle_(), circum_(), and ierr.
08968 { 08969 /* System generated locals */ 08970 double ret_val = 0; 08971 08972 /* Builtin functions */ 08973 //double acos(double); 08974 08975 /* Local variables */ 08976 static int m; 08977 static double c1[3], c2[3], c3[3]; 08978 static int n1, n2, n3; 08979 static double v1[3], v2[3], v3[3]; 08980 static int lp; 08981 static double c1s[3], c2s[3]; 08982 static int lpl, ierr; 08983 static double asum; 08984 double angle_(double *, double *, double *); 08985 static float areav; 08986 08987 08988 /* *********************************************************** */ 08989 08990 /* Robert J. Renka */ 08991 /* Dept. of Computer Science */ 08992 /* Univ. of North Texas */ 08993 /* renka@cs.unt.edu */ 08994 /* 06/03/03 */ 08995 08996 /* Given a Delaunay triangulation and the index K of an */ 08997 /* interior node, this subroutine returns the (surface) area */ 08998 /* of the Voronoi region associated with node K. The Voronoi */ 08999 /* region is the polygon whose vertices are the circumcenters */ 09000 /* of the triangles that contain node K, where a triangle */ 09001 /* circumcenter is the point (unit vector) lying at the same */ 09002 /* angular distance from the three vertices and contained in */ 09003 /* the same hemisphere as the vertices. The Voronoi region */ 09004 /* area is computed as Asum-(m-2)*Pi, where m is the number */ 09005 /* of Voronoi vertices (neighbors of K) and Asum is the sum */ 09006 /* of interior angles at the vertices. */ 09007 09008 09009 /* On input: */ 09010 09011 /* K = Nodal index in the range 1 to N. */ 09012 09013 /* N = Number of nodes in the triangulation. N > 3. */ 09014 09015 /* X,Y,Z = Arrays of length N containing the Cartesian */ 09016 /* coordinates of the nodes (unit vectors). */ 09017 09018 /* LIST,LPTR,LEND = Data structure defining the trian- */ 09019 /* gulation. Refer to Subroutine */ 09020 /* TRMESH. */ 09021 09022 /* Input parameters are not altered by this function. */ 09023 09024 /* On output: */ 09025 09026 /* AREAV = Area of Voronoi region K unless IER > 0, */ 09027 /* in which case AREAV = 0. */ 09028 09029 /* IER = Error indicator: */ 09030 /* IER = 0 if no errors were encountered. */ 09031 /* IER = 1 if K or N is outside its valid range */ 09032 /* on input. */ 09033 /* IER = 2 if K indexes a boundary node. */ 09034 /* IER = 3 if an error flag is returned by CIRCUM */ 09035 /* (null triangle). */ 09036 09037 /* Modules required by AREAV: ANGLE, CIRCUM */ 09038 09039 /* Intrinsic functions called by AREAV: ACOS, DBLE */ 09040 09041 /* *********************************************************** */ 09042 09043 09044 /* Test for invalid input. */ 09045 09046 /* Parameter adjustments */ 09047 --lend; 09048 --z__; 09049 --y; 09050 --x; 09051 --list; 09052 --lptr; 09053 09054 /* Function Body */ 09055 if (*k < 1 || *k > *n || *n <= 3) { 09056 goto L11; 09057 } 09058 09059 /* Initialization: Set N3 to the last neighbor of N1 = K. */ 09060 /* The number of neighbors and the sum of interior angles */ 09061 /* are accumulated in M and ASUM, respectively. */ 09062 09063 n1 = *k; 09064 v1[0] = x[n1]; 09065 v1[1] = y[n1]; 09066 v1[2] = z__[n1]; 09067 lpl = lend[n1]; 09068 n3 = list[lpl]; 09069 if (n3 < 0) { 09070 goto L12; 09071 } 09072 lp = lpl; 09073 m = 0; 09074 asum = 0.; 09075 09076 /* Loop on triangles (N1,N2,N3) containing N1 = K. */ 09077 09078 L1: 09079 ++m; 09080 n2 = n3; 09081 lp = lptr[lp]; 09082 n3 = list[lp]; 09083 v2[0] = x[n2]; 09084 v2[1] = y[n2]; 09085 v2[2] = z__[n2]; 09086 v3[0] = x[n3]; 09087 v3[1] = y[n3]; 09088 v3[2] = z__[n3]; 09089 if (m == 1) { 09090 09091 /* First triangle: compute the circumcenter C2 and save a */ 09092 /* copy in C1S. */ 09093 09094 circum_(v1, v2, v3, c2, &ierr); 09095 if (ierr != 0) { 09096 goto L13; 09097 } 09098 c1s[0] = c2[0]; 09099 c1s[1] = c2[1]; 09100 c1s[2] = c2[2]; 09101 } else if (m == 2) { 09102 09103 /* Second triangle: compute the circumcenter C3 and save a */ 09104 /* copy in C2S. */ 09105 09106 circum_(v1, v2, v3, c3, &ierr); 09107 if (ierr != 0) { 09108 goto L13; 09109 } 09110 c2s[0] = c3[0]; 09111 c2s[1] = c3[1]; 09112 c2s[2] = c3[2]; 09113 } else { 09114 09115 /* Set C1 to C2, set C2 to C3, compute the new circumcenter */ 09116 /* C3, and compute the interior angle at C2 from the */ 09117 /* sequence of vertices (C1,C2,C3). */ 09118 09119 c1[0] = c2[0]; 09120 c1[1] = c2[1]; 09121 c1[2] = c2[2]; 09122 c2[0] = c3[0]; 09123 c2[1] = c3[1]; 09124 c2[2] = c3[2]; 09125 circum_(v1, v2, v3, c3, &ierr); 09126 if (ierr != 0) { 09127 goto L13; 09128 } 09129 asum += angle_(c1, c2, c3); 09130 } 09131 09132 /* Bottom on loop on neighbors of K. */ 09133 09134 if (lp != lpl) { 09135 goto L1; 09136 } 09137 09138 /* C3 is the last vertex. Compute its interior angle from */ 09139 /* the sequence (C2,C3,C1S). */ 09140 09141 asum += angle_(c2, c3, c1s); 09142 09143 /* Compute the interior angle at C1S from */ 09144 /* the sequence (C3,C1S,C2S). */ 09145 09146 asum += angle_(c3, c1s, c2s); 09147 09148 /* No error encountered. */ 09149 09150 *ier = 0; 09151 ret_val = asum - (double) (m - 2) * acos(-1.); 09152 return ret_val; 09153 09154 /* Invalid input. */ 09155 09156 L11: 09157 *ier = 1; 09158 areav = 0.f; 09159 return ret_val; 09160 09161 /* K indexes a boundary node. */ 09162 09163 L12: 09164 *ier = 2; 09165 areav = 0.f; 09166 return ret_val; 09167 09168 /* Error in CIRCUM. */ 09169 09170 L13: 09171 *ier = 3; 09172 areav = 0.f; 09173 return ret_val; 09174 } /* areav_new__ */
int bdyadd_ | ( | int * | kk, | |
int * | i1, | |||
int * | i2, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | lnew | |||
) |
Definition at line 9176 of file util_sparx.cpp.
References insert_().
Referenced by addnod_().
09178 { 09179 static int k, n1, n2, lp, lsav, nsav, next; 09180 /* Subroutine */ int insert_(int *, int *, int *, 09181 int *, int *); 09182 09183 09184 /* *********************************************************** */ 09185 09186 /* From STRIPACK */ 09187 /* Robert J. Renka */ 09188 /* Dept. of Computer Science */ 09189 /* Univ. of North Texas */ 09190 /* renka@cs.unt.edu */ 09191 /* 07/11/96 */ 09192 09193 /* This subroutine adds a boundary node to a triangulation */ 09194 /* of a set of KK-1 points on the unit sphere. The data */ 09195 /* structure is updated with the insertion of node KK, but no */ 09196 /* optimization is performed. */ 09197 09198 /* This routine is identical to the similarly named routine */ 09199 /* in TRIPACK. */ 09200 09201 09202 /* On input: */ 09203 09204 /* KK = Index of a node to be connected to the sequence */ 09205 /* of all visible boundary nodes. KK .GE. 1 and */ 09206 /* KK must not be equal to I1 or I2. */ 09207 09208 /* I1 = First (rightmost as viewed from KK) boundary */ 09209 /* node in the triangulation that is visible from */ 09210 /* node KK (the line segment KK-I1 intersects no */ 09211 /* arcs. */ 09212 09213 /* I2 = Last (leftmost) boundary node that is visible */ 09214 /* from node KK. I1 and I2 may be determined by */ 09215 /* Subroutine TRFIND. */ 09216 09217 /* The above parameters are not altered by this routine. */ 09218 09219 /* LIST,LPTR,LEND,LNEW = Triangulation data structure */ 09220 /* created by Subroutine TRMESH. */ 09221 /* Nodes I1 and I2 must be in- */ 09222 /* cluded in the triangulation. */ 09223 09224 /* On output: */ 09225 09226 /* LIST,LPTR,LEND,LNEW = Data structure updated with */ 09227 /* the addition of node KK. Node */ 09228 /* KK is connected to I1, I2, and */ 09229 /* all boundary nodes in between. */ 09230 09231 /* Module required by BDYADD: INSERT */ 09232 09233 /* *********************************************************** */ 09234 09235 09236 /* Local parameters: */ 09237 09238 /* K = Local copy of KK */ 09239 /* LP = LIST pointer */ 09240 /* LSAV = LIST pointer */ 09241 /* N1,N2 = Local copies of I1 and I2, respectively */ 09242 /* NEXT = Boundary node visible from K */ 09243 /* NSAV = Boundary node visible from K */ 09244 09245 /* Parameter adjustments */ 09246 --lend; 09247 --lptr; 09248 --list; 09249 09250 /* Function Body */ 09251 k = *kk; 09252 n1 = *i1; 09253 n2 = *i2; 09254 09255 /* Add K as the last neighbor of N1. */ 09256 09257 lp = lend[n1]; 09258 lsav = lptr[lp]; 09259 lptr[lp] = *lnew; 09260 list[*lnew] = -k; 09261 lptr[*lnew] = lsav; 09262 lend[n1] = *lnew; 09263 ++(*lnew); 09264 next = -list[lp]; 09265 list[lp] = next; 09266 nsav = next; 09267 09268 /* Loop on the remaining boundary nodes between N1 and N2, */ 09269 /* adding K as the first neighbor. */ 09270 09271 L1: 09272 lp = lend[next]; 09273 insert_(&k, &lp, &list[1], &lptr[1], lnew); 09274 if (next == n2) { 09275 goto L2; 09276 } 09277 next = -list[lp]; 09278 list[lp] = next; 09279 goto L1; 09280 09281 /* Add the boundary nodes between N1 and N2 as neighbors */ 09282 /* of node K. */ 09283 09284 L2: 09285 lsav = *lnew; 09286 list[*lnew] = n1; 09287 lptr[*lnew] = *lnew + 1; 09288 ++(*lnew); 09289 next = nsav; 09290 09291 L3: 09292 if (next == n2) { 09293 goto L4; 09294 } 09295 list[*lnew] = next; 09296 lptr[*lnew] = *lnew + 1; 09297 ++(*lnew); 09298 lp = lend[next]; 09299 next = list[lp]; 09300 goto L3; 09301 09302 L4: 09303 list[*lnew] = -n2; 09304 lptr[*lnew] = lsav; 09305 lend[k] = *lnew; 09306 ++(*lnew); 09307 return 0; 09308 } /* bdyadd_ */
int bnodes_ | ( | int * | n, | |
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | nodes, | |||
int * | nb, | |||
int * | na, | |||
int * | nt | |||
) |
Definition at line 9310 of file util_sparx.cpp.
References nn().
09312 { 09313 /* System generated locals */ 09314 int i__1; 09315 09316 /* Local variables */ 09317 static int k, n0, lp, nn, nst; 09318 09319 09320 /* *********************************************************** */ 09321 09322 /* From STRIPACK */ 09323 /* Robert J. Renka */ 09324 /* Dept. of Computer Science */ 09325 /* Univ. of North Texas */ 09326 /* renka@cs.unt.edu */ 09327 /* 06/26/96 */ 09328 09329 /* Given a triangulation of N nodes on the unit sphere */ 09330 /* created by Subroutine TRMESH, this subroutine returns an */ 09331 /* array containing the indexes (if any) of the counterclock- */ 09332 /* wise-ordered sequence of boundary nodes -- the nodes on */ 09333 /* the boundary of the convex hull of the set of nodes. (The */ 09334 /* boundary is empty if the nodes do not lie in a single */ 09335 /* hemisphere.) The numbers of boundary nodes, arcs, and */ 09336 /* triangles are also returned. */ 09337 09338 09339 /* On input: */ 09340 09341 /* N = Number of nodes in the triangulation. N .GE. 3. */ 09342 09343 /* LIST,LPTR,LEND = Data structure defining the trian- */ 09344 /* gulation. Refer to Subroutine */ 09345 /* TRMESH. */ 09346 09347 /* The above parameters are not altered by this routine. */ 09348 09349 /* NODES = int array of length at least NB */ 09350 /* (NB .LE. N). */ 09351 09352 /* On output: */ 09353 09354 /* NODES = Ordered sequence of boundary node indexes */ 09355 /* in the range 1 to N (in the first NB loca- */ 09356 /* tions). */ 09357 09358 /* NB = Number of boundary nodes. */ 09359 09360 /* NA,NT = Number of arcs and triangles, respectively, */ 09361 /* in the triangulation. */ 09362 09363 /* Modules required by BNODES: None */ 09364 09365 /* *********************************************************** */ 09366 09367 09368 /* Local parameters: */ 09369 09370 /* K = NODES index */ 09371 /* LP = LIST pointer */ 09372 /* N0 = Boundary node to be added to NODES */ 09373 /* NN = Local copy of N */ 09374 /* NST = First element of nodes (arbitrarily chosen to be */ 09375 /* the one with smallest index) */ 09376 09377 /* Parameter adjustments */ 09378 --lend; 09379 --list; 09380 --lptr; 09381 --nodes; 09382 09383 /* Function Body */ 09384 nn = *n; 09385 09386 /* Search for a boundary node. */ 09387 09388 i__1 = nn; 09389 for (nst = 1; nst <= i__1; ++nst) { 09390 lp = lend[nst]; 09391 if (list[lp] < 0) { 09392 goto L2; 09393 } 09394 /* L1: */ 09395 } 09396 09397 /* The triangulation contains no boundary nodes. */ 09398 09399 *nb = 0; 09400 *na = (nn - 2) * 3; 09401 *nt = nn - (2<<1); 09402 return 0; 09403 09404 /* NST is the first boundary node encountered. Initialize */ 09405 /* for traversal of the boundary. */ 09406 09407 L2: 09408 nodes[1] = nst; 09409 k = 1; 09410 n0 = nst; 09411 09412 /* Traverse the boundary in counterclockwise order. */ 09413 09414 L3: 09415 lp = lend[n0]; 09416 lp = lptr[lp]; 09417 n0 = list[lp]; 09418 if (n0 == nst) { 09419 goto L4; 09420 } 09421 ++k; 09422 nodes[k] = n0; 09423 goto L3; 09424 09425 /* Store the counts. */ 09426 09427 L4: 09428 *nb = k; 09429 *nt = (*n << 1) - *nb - 2; 09430 *na = *nt + *n - 1; 09431 return 0; 09432 } /* bnodes_ */
int circle_ | ( | int * | k, | |
double * | xc, | |||
double * | yc, | |||
int * | ier | |||
) |
Definition at line 9434 of file util_sparx.cpp.
09436 { 09437 /* System generated locals */ 09438 int i__1; 09439 09440 /* Builtin functions */ 09441 //double atan(double), cos(double), sin(double); 09442 09443 /* Local variables */ 09444 static double a, c__; 09445 static int i__; 09446 static double s; 09447 static int k2, k3; 09448 static double x0, y0; 09449 static int kk, np1; 09450 09451 09452 /* *********************************************************** */ 09453 09454 /* From STRIPACK */ 09455 /* Robert J. Renka */ 09456 /* Dept. of Computer Science */ 09457 /* Univ. of North Texas */ 09458 /* renka@cs.unt.edu */ 09459 /* 04/06/90 */ 09460 09461 /* This subroutine computes the coordinates of a sequence */ 09462 /* of N equally spaced points on the unit circle centered at */ 09463 /* (0,0). An N-sided polygonal approximation to the circle */ 09464 /* may be plotted by connecting (XC(I),YC(I)) to (XC(I+1), */ 09465 /* YC(I+1)) for I = 1,...,N, where XC(N+1) = XC(1) and */ 09466 /* YC(N+1) = YC(1). A reasonable value for N in this case */ 09467 /* is 2*PI*R, where R is the radius of the circle in device */ 09468 /* coordinates. */ 09469 09470 09471 /* On input: */ 09472 09473 /* K = Number of points in each quadrant, defining N as */ 09474 /* 4K. K .GE. 1. */ 09475 09476 /* XC,YC = Arrays of length at least N+1 = 4K+1. */ 09477 09478 /* K is not altered by this routine. */ 09479 09480 /* On output: */ 09481 09482 /* XC,YC = Cartesian coordinates of the points on the */ 09483 /* unit circle in the first N+1 locations. */ 09484 /* XC(I) = cos(A*(I-1)), YC(I) = sin(A*(I-1)), */ 09485 /* where A = 2*PI/N. Note that XC(N+1) = XC(1) */ 09486 /* and YC(N+1) = YC(1). */ 09487 09488 /* IER = Error indicator: */ 09489 /* IER = 0 if no errors were encountered. */ 09490 /* IER = 1 if K < 1 on input. */ 09491 09492 /* Modules required by CIRCLE: None */ 09493 09494 /* Intrinsic functions called by CIRCLE: ATAN, COS, DBLE, */ 09495 /* SIN */ 09496 09497 /* *********************************************************** */ 09498 09499 09500 /* Local parameters: */ 09501 09502 /* I = DO-loop index and index for XC and YC */ 09503 /* KK = Local copy of K */ 09504 /* K2 = K*2 */ 09505 /* K3 = K*3 */ 09506 /* NP1 = N+1 = 4*K + 1 */ 09507 /* A = Angular separation between adjacent points */ 09508 /* C,S = Cos(A) and sin(A), respectively, defining a */ 09509 /* rotation through angle A */ 09510 /* X0,Y0 = Cartesian coordinates of a point on the unit */ 09511 /* circle in the first quadrant */ 09512 09513 /* Parameter adjustments */ 09514 --yc; 09515 --xc; 09516 09517 /* Function Body */ 09518 kk = *k; 09519 k2 = kk << 1; 09520 k3 = kk * 3; 09521 np1 = (kk << 2) + 1; 09522 09523 /* Test for invalid input, compute A, C, and S, and */ 09524 /* initialize (X0,Y0) to (1,0). */ 09525 09526 if (kk < 1) { 09527 goto L2; 09528 } 09529 a = atan(1.) * 2. / (double) kk; 09530 c__ = cos(a); 09531 s = sin(a); 09532 x0 = 1.; 09533 y0 = 0.; 09534 09535 /* Loop on points (X0,Y0) in the first quadrant, storing */ 09536 /* the point and its reflections about the x axis, the */ 09537 /* y axis, and the line y = -x. */ 09538 09539 i__1 = kk; 09540 for (i__ = 1; i__ <= i__1; ++i__) { 09541 xc[i__] = x0; 09542 yc[i__] = y0; 09543 xc[i__ + kk] = -y0; 09544 yc[i__ + kk] = x0; 09545 xc[i__ + k2] = -x0; 09546 yc[i__ + k2] = -y0; 09547 xc[i__ + k3] = y0; 09548 yc[i__ + k3] = -x0; 09549 09550 /* Rotate (X0,Y0) counterclockwise through angle A. */ 09551 09552 x0 = c__ * x0 - s * y0; 09553 y0 = s * x0 + c__ * y0; 09554 /* L1: */ 09555 } 09556 09557 /* Store the coordinates of the first point as the last */ 09558 /* point. */ 09559 09560 xc[np1] = xc[1]; 09561 yc[np1] = yc[1]; 09562 *ier = 0; 09563 return 0; 09564 09565 /* K < 1. */ 09566 09567 L2: 09568 *ier = 1; 09569 return 0; 09570 } /* circle_ */
int circum_ | ( | double * | , | |
double * | , | |||
double * | , | |||
double * | , | |||
int * | ||||
) |
Definition at line 9572 of file util_sparx.cpp.
References sqrt().
Referenced by EMAN::Util::areav_(), areav_new__(), and crlist_().
09574 { 09575 /* Builtin functions */ 09576 //double sqrt(double); 09577 09578 /* Local variables */ 09579 static int i__; 09580 static double e1[3], e2[3], cu[3], cnorm; 09581 09582 09583 /* *********************************************************** */ 09584 09585 /* From STRIPACK */ 09586 /* Robert J. Renka */ 09587 /* Dept. of Computer Science */ 09588 /* Univ. of North Texas */ 09589 /* renka@cs.unt.edu */ 09590 /* 10/27/02 */ 09591 09592 /* This subroutine returns the circumcenter of a spherical */ 09593 /* triangle on the unit sphere: the point on the sphere sur- */ 09594 /* face that is equally distant from the three triangle */ 09595 /* vertices and lies in the same hemisphere, where distance */ 09596 /* is taken to be arc-length on the sphere surface. */ 09597 09598 09599 /* On input: */ 09600 09601 /* V1,V2,V3 = Arrays of length 3 containing the Carte- */ 09602 /* sian coordinates of the three triangle */ 09603 /* vertices (unit vectors) in CCW order. */ 09604 09605 /* The above parameters are not altered by this routine. */ 09606 09607 /* C = Array of length 3. */ 09608 09609 /* On output: */ 09610 09611 /* C = Cartesian coordinates of the circumcenter unless */ 09612 /* IER > 0, in which case C is not defined. C = */ 09613 /* (V2-V1) X (V3-V1) normalized to a unit vector. */ 09614 09615 /* IER = Error indicator: */ 09616 /* IER = 0 if no errors were encountered. */ 09617 /* IER = 1 if V1, V2, and V3 lie on a common */ 09618 /* line: (V2-V1) X (V3-V1) = 0. */ 09619 /* (The vertices are not tested for validity.) */ 09620 09621 /* Modules required by CIRCUM: None */ 09622 09623 /* Intrinsic function called by CIRCUM: SQRT */ 09624 09625 /* *********************************************************** */ 09626 09627 09628 /* Local parameters: */ 09629 09630 /* CNORM = Norm of CU: used to compute C */ 09631 /* CU = Scalar multiple of C: E1 X E2 */ 09632 /* E1,E2 = Edges of the underlying planar triangle: */ 09633 /* V2-V1 and V3-V1, respectively */ 09634 /* I = DO-loop index */ 09635 09636 /* Parameter adjustments */ 09637 --c__; 09638 --v3; 09639 --v2; 09640 --v1; 09641 09642 /* Function Body */ 09643 for (i__ = 1; i__ <= 3; ++i__) { 09644 e1[i__ - 1] = v2[i__] - v1[i__]; 09645 e2[i__ - 1] = v3[i__] - v1[i__]; 09646 /* L1: */ 09647 } 09648 09649 /* Compute CU = E1 X E2 and CNORM**2. */ 09650 09651 cu[0] = e1[1] * e2[2] - e1[2] * e2[1]; 09652 cu[1] = e1[2] * e2[0] - e1[0] * e2[2]; 09653 cu[2] = e1[0] * e2[1] - e1[1] * e2[0]; 09654 cnorm = cu[0] * cu[0] + cu[1] * cu[1] + cu[2] * cu[2]; 09655 09656 /* The vertices lie on a common line if and only if CU is */ 09657 /* the zero vector. */ 09658 09659 if (cnorm != 0.) { 09660 09661 /* No error: compute C. */ 09662 09663 cnorm = sqrt(cnorm); 09664 for (i__ = 1; i__ <= 3; ++i__) { 09665 c__[i__] = cu[i__ - 1] / cnorm; 09666 /* L2: */ 09667 } 09668 09669 /* If the vertices are nearly identical, the problem is */ 09670 /* ill-conditioned and it is possible for the computed */ 09671 /* value of C to be 180 degrees off: <C,V1> near -1 */ 09672 /* when it should be positive. */ 09673 09674 if (c__[1] * v1[1] + c__[2] * v1[2] + c__[3] * v1[3] < -.5) { 09675 c__[1] = -c__[1]; 09676 c__[2] = -c__[2]; 09677 c__[3] = -c__[3]; 09678 } 09679 *ier = 0; 09680 } else { 09681 09682 /* CU = 0. */ 09683 09684 *ier = 1; 09685 } 09686 return 0; 09687 } /* circum_ */
static void compose_transform2 | ( | float | psi1, | |
float | sx1, | |||
float | sy1, | |||
float | psi2, | |||
float | sx2, | |||
float | sy2, | |||
float & | out_psi, | |||
float & | out_sx, | |||
float & | out_sy | |||
) | [static] |
Definition at line 21914 of file util_sparx.cpp.
References EMAN::Transform::get_params().
Referenced by EMAN::Util::constrained_helix(), and EMAN::Util::constrained_helix_test().
21915 { 21916 Dict t_params; 21917 t_params["type"] = "2D"; 21918 t_params["alpha"] = psi1; 21919 t_params["tx"] = sx1; 21920 t_params["ty"] = sy1; 21921 t_params["mirror"] = 0; 21922 t_params["scale"] = 1.0; 21923 Transform t1(t_params); 21924 t_params["alpha"] = psi2; 21925 t_params["tx"] = sx2; 21926 t_params["ty"] = sy2; 21927 Transform t2(t_params); 21928 Transform tt = t2*t1; 21929 Dict d = tt.get_params("2D"); 21930 out_psi = d["alpha"]; 21931 out_sx = d["tx"]; 21932 out_sy = d["ty"]; 21933 }
int covsph_ | ( | int * | kk, | |
int * | n0, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | lnew | |||
) |
Definition at line 9689 of file util_sparx.cpp.
References insert_().
Referenced by addnod_().
09691 { 09692 static int k, lp, nst, lsav, next; 09693 /* Subroutine */ int insert_(int *, int *, int *, 09694 int *, int *); 09695 09696 09697 /* *********************************************************** */ 09698 09699 /* From STRIPACK */ 09700 /* Robert J. Renka */ 09701 /* Dept. of Computer Science */ 09702 /* Univ. of North Texas */ 09703 /* renka@cs.unt.edu */ 09704 /* 07/17/96 */ 09705 09706 /* This subroutine connects an exterior node KK to all */ 09707 /* boundary nodes of a triangulation of KK-1 points on the */ 09708 /* unit sphere, producing a triangulation that covers the */ 09709 /* sphere. The data structure is updated with the addition */ 09710 /* of node KK, but no optimization is performed. All boun- */ 09711 /* dary nodes must be visible from node KK. */ 09712 09713 09714 /* On input: */ 09715 09716 /* KK = Index of the node to be connected to the set of */ 09717 /* all boundary nodes. KK .GE. 4. */ 09718 09719 /* N0 = Index of a boundary node (in the range 1 to */ 09720 /* KK-1). N0 may be determined by Subroutine */ 09721 /* TRFIND. */ 09722 09723 /* The above parameters are not altered by this routine. */ 09724 09725 /* LIST,LPTR,LEND,LNEW = Triangulation data structure */ 09726 /* created by Subroutine TRMESH. */ 09727 /* Node N0 must be included in */ 09728 /* the triangulation. */ 09729 09730 /* On output: */ 09731 09732 /* LIST,LPTR,LEND,LNEW = Data structure updated with */ 09733 /* the addition of node KK as the */ 09734 /* last entry. The updated */ 09735 /* triangulation contains no */ 09736 /* boundary nodes. */ 09737 09738 /* Module required by COVSPH: INSERT */ 09739 09740 /* *********************************************************** */ 09741 09742 09743 /* Local parameters: */ 09744 09745 /* K = Local copy of KK */ 09746 /* LP = LIST pointer */ 09747 /* LSAV = LIST pointer */ 09748 /* NEXT = Boundary node visible from K */ 09749 /* NST = Local copy of N0 */ 09750 09751 /* Parameter adjustments */ 09752 --lend; 09753 --lptr; 09754 --list; 09755 09756 /* Function Body */ 09757 k = *kk; 09758 nst = *n0; 09759 09760 /* Traverse the boundary in clockwise order, inserting K as */ 09761 /* the first neighbor of each boundary node, and converting */ 09762 /* the boundary node to an interior node. */ 09763 09764 next = nst; 09765 L1: 09766 lp = lend[next]; 09767 insert_(&k, &lp, &list[1], &lptr[1], lnew); 09768 next = -list[lp]; 09769 list[lp] = next; 09770 if (next != nst) { 09771 goto L1; 09772 } 09773 09774 /* Traverse the boundary again, adding each node to K's */ 09775 /* adjacency list. */ 09776 09777 lsav = *lnew; 09778 L2: 09779 lp = lend[next]; 09780 list[*lnew] = next; 09781 lptr[*lnew] = *lnew + 1; 09782 ++(*lnew); 09783 next = list[lp]; 09784 if (next != nst) { 09785 goto L2; 09786 } 09787 09788 lptr[*lnew - 1] = lsav; 09789 lend[k] = *lnew - 1; 09790 return 0; 09791 } /* covsph_ */
int crlist_ | ( | int * | n, | |
int * | ncol, | |||
double * | x, | |||
double * | y, | |||
double * | z__, | |||
int * | list, | |||
int * | lend, | |||
int * | lptr, | |||
int * | lnew, | |||
int * | ltri, | |||
int * | listc, | |||
int * | nb, | |||
double * | xc, | |||
double * | yc, | |||
double * | zc, | |||
double * | rc, | |||
int * | ier | |||
) |
Definition at line 9794 of file util_sparx.cpp.
References abs, circum_(), FALSE_, ierr, lstptr_(), nn(), swptst_(), t, and TRUE_.
09799 { 09800 /* System generated locals */ 09801 int i__1, i__2; 09802 09803 /* Builtin functions */ 09804 //double acos(double); 09805 09806 /* Local variables */ 09807 static double c__[3], t; 09808 static int i1, i2, i3, i4, n0, n1, n2, n3, n4; 09809 static double v1[3], v2[3], v3[3]; 09810 static int lp, kt, nn, nt, nm2, kt1, kt2, kt11, kt12, kt21, kt22, lpl, 09811 lpn; 09812 static long int swp; 09813 static int ierr; 09814 int lstptr_(int *, int *, int *, int *); 09815 long int swptst_(int *, int *, int *, int *, 09816 double *, double *, double *); 09817 09818 09819 /* *********************************************************** */ 09820 09821 /* From STRIPACK */ 09822 /* Robert J. Renka */ 09823 /* Dept. of Computer Science */ 09824 /* Univ. of North Texas */ 09825 /* renka@cs.unt.edu */ 09826 /* 03/05/03 */ 09827 09828 /* Given a Delaunay triangulation of nodes on the surface */ 09829 /* of the unit sphere, this subroutine returns the set of */ 09830 /* triangle circumcenters corresponding to Voronoi vertices, */ 09831 /* along with the circumradii and a list of triangle indexes */ 09832 /* LISTC stored in one-to-one correspondence with LIST/LPTR */ 09833 /* entries. */ 09834 09835 /* A triangle circumcenter is the point (unit vector) lying */ 09836 /* at the same angular distance from the three vertices and */ 09837 /* contained in the same hemisphere as the vertices. (Note */ 09838 /* that the negative of a circumcenter is also equidistant */ 09839 /* from the vertices.) If the triangulation covers the sur- */ 09840 /* face, the Voronoi vertices are the circumcenters of the */ 09841 /* triangles in the Delaunay triangulation. LPTR, LEND, and */ 09842 /* LNEW are not altered in this case. */ 09843 09844 /* On the other hand, if the nodes are contained in a sin- */ 09845 /* gle hemisphere, the triangulation is implicitly extended */ 09846 /* to the entire surface by adding pseudo-arcs (of length */ 09847 /* greater than 180 degrees) between boundary nodes forming */ 09848 /* pseudo-triangles whose 'circumcenters' are included in the */ 09849 /* list. This extension to the triangulation actually con- */ 09850 /* sists of a triangulation of the set of boundary nodes in */ 09851 /* which the swap test is reversed (a non-empty circumcircle */ 09852 /* test). The negative circumcenters are stored as the */ 09853 /* pseudo-triangle 'circumcenters'. LISTC, LPTR, LEND, and */ 09854 /* LNEW contain a data structure corresponding to the ex- */ 09855 /* tended triangulation (Voronoi diagram), but LIST is not */ 09856 /* altered in this case. Thus, if it is necessary to retain */ 09857 /* the original (unextended) triangulation data structure, */ 09858 /* copies of LPTR and LNEW must be saved before calling this */ 09859 /* routine. */ 09860 09861 09862 /* On input: */ 09863 09864 /* N = Number of nodes in the triangulation. N .GE. 3. */ 09865 /* Note that, if N = 3, there are only two Voronoi */ 09866 /* vertices separated by 180 degrees, and the */ 09867 /* Voronoi regions are not well defined. */ 09868 09869 /* NCOL = Number of columns reserved for LTRI. This */ 09870 /* must be at least NB-2, where NB is the number */ 09871 /* of boundary nodes. */ 09872 09873 /* X,Y,Z = Arrays of length N containing the Cartesian */ 09874 /* coordinates of the nodes (unit vectors). */ 09875 09876 /* LIST = int array containing the set of adjacency */ 09877 /* lists. Refer to Subroutine TRMESH. */ 09878 09879 /* LEND = Set of pointers to ends of adjacency lists. */ 09880 /* Refer to Subroutine TRMESH. */ 09881 09882 /* The above parameters are not altered by this routine. */ 09883 09884 /* LPTR = Array of pointers associated with LIST. Re- */ 09885 /* fer to Subroutine TRMESH. */ 09886 09887 /* LNEW = Pointer to the first empty location in LIST */ 09888 /* and LPTR (list length plus one). */ 09889 09890 /* LTRI = int work space array dimensioned 6 by */ 09891 /* NCOL, or unused dummy parameter if NB = 0. */ 09892 09893 /* LISTC = int array of length at least 3*NT, where */ 09894 /* NT = 2*N-4 is the number of triangles in the */ 09895 /* triangulation (after extending it to cover */ 09896 /* the entire surface if necessary). */ 09897 09898 /* XC,YC,ZC,RC = Arrays of length NT = 2*N-4. */ 09899 09900 /* On output: */ 09901 09902 /* LPTR = Array of pointers associated with LISTC: */ 09903 /* updated for the addition of pseudo-triangles */ 09904 /* if the original triangulation contains */ 09905 /* boundary nodes (NB > 0). */ 09906 09907 /* LNEW = Pointer to the first empty location in LISTC */ 09908 /* and LPTR (list length plus one). LNEW is not */ 09909 /* altered if NB = 0. */ 09910 09911 /* LTRI = Triangle list whose first NB-2 columns con- */ 09912 /* tain the indexes of a clockwise-ordered */ 09913 /* sequence of vertices (first three rows) */ 09914 /* followed by the LTRI column indexes of the */ 09915 /* triangles opposite the vertices (or 0 */ 09916 /* denoting the exterior region) in the last */ 09917 /* three rows. This array is not generally of */ 09918 /* any use. */ 09919 09920 /* LISTC = Array containing triangle indexes (indexes */ 09921 /* to XC, YC, ZC, and RC) stored in 1-1 corres- */ 09922 /* pondence with LIST/LPTR entries (or entries */ 09923 /* that would be stored in LIST for the */ 09924 /* extended triangulation): the index of tri- */ 09925 /* angle (N1,N2,N3) is stored in LISTC(K), */ 09926 /* LISTC(L), and LISTC(M), where LIST(K), */ 09927 /* LIST(L), and LIST(M) are the indexes of N2 */ 09928 /* as a neighbor of N1, N3 as a neighbor of N2, */ 09929 /* and N1 as a neighbor of N3. The Voronoi */ 09930 /* region associated with a node is defined by */ 09931 /* the CCW-ordered sequence of circumcenters in */ 09932 /* one-to-one correspondence with its adjacency */ 09933 /* list (in the extended triangulation). */ 09934 09935 /* NB = Number of boundary nodes unless IER = 1. */ 09936 09937 /* XC,YC,ZC = Arrays containing the Cartesian coordi- */ 09938 /* nates of the triangle circumcenters */ 09939 /* (Voronoi vertices). XC(I)**2 + YC(I)**2 */ 09940 /* + ZC(I)**2 = 1. The first NB-2 entries */ 09941 /* correspond to pseudo-triangles if NB > 0. */ 09942 09943 /* RC = Array containing circumradii (the arc lengths */ 09944 /* or angles between the circumcenters and associ- */ 09945 /* ated triangle vertices) in 1-1 correspondence */ 09946 /* with circumcenters. */ 09947 09948 /* IER = Error indicator: */ 09949 /* IER = 0 if no errors were encountered. */ 09950 /* IER = 1 if N < 3. */ 09951 /* IER = 2 if NCOL < NB-2. */ 09952 /* IER = 3 if a triangle is degenerate (has ver- */ 09953 /* tices lying on a common geodesic). */ 09954 09955 /* Modules required by CRLIST: CIRCUM, LSTPTR, SWPTST */ 09956 09957 /* Intrinsic functions called by CRLIST: ABS, ACOS */ 09958 09959 /* *********************************************************** */ 09960 09961 09962 /* Local parameters: */ 09963 09964 /* C = Circumcenter returned by Subroutine CIRCUM */ 09965 /* I1,I2,I3 = Permutation of (1,2,3): LTRI row indexes */ 09966 /* I4 = LTRI row index in the range 1 to 3 */ 09967 /* IERR = Error flag for calls to CIRCUM */ 09968 /* KT = Triangle index */ 09969 /* KT1,KT2 = Indexes of a pair of adjacent pseudo-triangles */ 09970 /* KT11,KT12 = Indexes of the pseudo-triangles opposite N1 */ 09971 /* and N2 as vertices of KT1 */ 09972 /* KT21,KT22 = Indexes of the pseudo-triangles opposite N1 */ 09973 /* and N2 as vertices of KT2 */ 09974 /* LP,LPN = LIST pointers */ 09975 /* LPL = LIST pointer of the last neighbor of N1 */ 09976 /* N0 = Index of the first boundary node (initial */ 09977 /* value of N1) in the loop on boundary nodes */ 09978 /* used to store the pseudo-triangle indexes */ 09979 /* in LISTC */ 09980 /* N1,N2,N3 = Nodal indexes defining a triangle (CCW order) */ 09981 /* or pseudo-triangle (clockwise order) */ 09982 /* N4 = Index of the node opposite N2 -> N1 */ 09983 /* NM2 = N-2 */ 09984 /* NN = Local copy of N */ 09985 /* NT = Number of pseudo-triangles: NB-2 */ 09986 /* SWP = long int variable set to TRUE in each optimiza- */ 09987 /* tion loop (loop on pseudo-arcs) iff a swap */ 09988 /* is performed */ 09989 /* V1,V2,V3 = Vertices of triangle KT = (N1,N2,N3) sent to */ 09990 /* Subroutine CIRCUM */ 09991 09992 /* Parameter adjustments */ 09993 --lend; 09994 --z__; 09995 --y; 09996 --x; 09997 ltri -= 7; 09998 --list; 09999 --lptr; 10000 --listc; 10001 --xc; 10002 --yc; 10003 --zc; 10004 --rc; 10005 10006 /* Function Body */ 10007 nn = *n; 10008 *nb = 0; 10009 nt = 0; 10010 if (nn < 3) { 10011 goto L21; 10012 } 10013 10014 /* Search for a boundary node N1. */ 10015 10016 i__1 = nn; 10017 for (n1 = 1; n1 <= i__1; ++n1) { 10018 lp = lend[n1]; 10019 if (list[lp] < 0) { 10020 goto L2; 10021 } 10022 /* L1: */ 10023 } 10024 10025 /* The triangulation already covers the sphere. */ 10026 10027 goto L9; 10028 10029 /* There are NB .GE. 3 boundary nodes. Add NB-2 pseudo- */ 10030 /* triangles (N1,N2,N3) by connecting N3 to the NB-3 */ 10031 /* boundary nodes to which it is not already adjacent. */ 10032 10033 /* Set N3 and N2 to the first and last neighbors, */ 10034 /* respectively, of N1. */ 10035 10036 L2: 10037 n2 = -list[lp]; 10038 lp = lptr[lp]; 10039 n3 = list[lp]; 10040 10041 /* Loop on boundary arcs N1 -> N2 in clockwise order, */ 10042 /* storing triangles (N1,N2,N3) in column NT of LTRI */ 10043 /* along with the indexes of the triangles opposite */ 10044 /* the vertices. */ 10045 10046 L3: 10047 ++nt; 10048 if (nt <= *ncol) { 10049 ltri[nt * 6 + 1] = n1; 10050 ltri[nt * 6 + 2] = n2; 10051 ltri[nt * 6 + 3] = n3; 10052 ltri[nt * 6 + 4] = nt + 1; 10053 ltri[nt * 6 + 5] = nt - 1; 10054 ltri[nt * 6 + 6] = 0; 10055 } 10056 n1 = n2; 10057 lp = lend[n1]; 10058 n2 = -list[lp]; 10059 if (n2 != n3) { 10060 goto L3; 10061 } 10062 10063 *nb = nt + 2; 10064 if (*ncol < nt) { 10065 goto L22; 10066 } 10067 ltri[nt * 6 + 4] = 0; 10068 if (nt == 1) { 10069 goto L7; 10070 } 10071 10072 /* Optimize the exterior triangulation (set of pseudo- */ 10073 /* triangles) by applying swaps to the pseudo-arcs N1-N2 */ 10074 /* (pairs of adjacent pseudo-triangles KT1 and KT2 > KT1). */ 10075 /* The loop on pseudo-arcs is repeated until no swaps are */ 10076 /* performed. */ 10077 10078 L4: 10079 swp = FALSE_; 10080 i__1 = nt - 1; 10081 for (kt1 = 1; kt1 <= i__1; ++kt1) { 10082 for (i3 = 1; i3 <= 3; ++i3) { 10083 kt2 = ltri[i3 + 3 + kt1 * 6]; 10084 if (kt2 <= kt1) { 10085 goto L5; 10086 } 10087 10088 /* The LTRI row indexes (I1,I2,I3) of triangle KT1 = */ 10089 /* (N1,N2,N3) are a cyclical permutation of (1,2,3). */ 10090 10091 if (i3 == 1) { 10092 i1 = 2; 10093 i2 = 3; 10094 } else if (i3 == 2) { 10095 i1 = 3; 10096 i2 = 1; 10097 } else { 10098 i1 = 1; 10099 i2 = 2; 10100 } 10101 n1 = ltri[i1 + kt1 * 6]; 10102 n2 = ltri[i2 + kt1 * 6]; 10103 n3 = ltri[i3 + kt1 * 6]; 10104 10105 /* KT2 = (N2,N1,N4) for N4 = LTRI(I,KT2), where */ 10106 /* LTRI(I+3,KT2) = KT1. */ 10107 10108 if (ltri[kt2 * 6 + 4] == kt1) { 10109 i4 = 1; 10110 } else if (ltri[kt2 * 6 + 5] == kt1) { 10111 i4 = 2; 10112 } else { 10113 i4 = 3; 10114 } 10115 n4 = ltri[i4 + kt2 * 6]; 10116 10117 /* The empty circumcircle test is reversed for the pseudo- */ 10118 /* triangles. The reversal is implicit in the clockwise */ 10119 /* ordering of the vertices. */ 10120 10121 if (! swptst_(&n1, &n2, &n3, &n4, &x[1], &y[1], &z__[1])) { 10122 goto L5; 10123 } 10124 10125 /* Swap arc N1-N2 for N3-N4. KTij is the triangle opposite */ 10126 /* Nj as a vertex of KTi. */ 10127 10128 swp = TRUE_; 10129 kt11 = ltri[i1 + 3 + kt1 * 6]; 10130 kt12 = ltri[i2 + 3 + kt1 * 6]; 10131 if (i4 == 1) { 10132 i2 = 2; 10133 i1 = 3; 10134 } else if (i4 == 2) { 10135 i2 = 3; 10136 i1 = 1; 10137 } else { 10138 i2 = 1; 10139 i1 = 2; 10140 } 10141 kt21 = ltri[i1 + 3 + kt2 * 6]; 10142 kt22 = ltri[i2 + 3 + kt2 * 6]; 10143 ltri[kt1 * 6 + 1] = n4; 10144 ltri[kt1 * 6 + 2] = n3; 10145 ltri[kt1 * 6 + 3] = n1; 10146 ltri[kt1 * 6 + 4] = kt12; 10147 ltri[kt1 * 6 + 5] = kt22; 10148 ltri[kt1 * 6 + 6] = kt2; 10149 ltri[kt2 * 6 + 1] = n3; 10150 ltri[kt2 * 6 + 2] = n4; 10151 ltri[kt2 * 6 + 3] = n2; 10152 ltri[kt2 * 6 + 4] = kt21; 10153 ltri[kt2 * 6 + 5] = kt11; 10154 ltri[kt2 * 6 + 6] = kt1; 10155 10156 /* Correct the KT11 and KT22 entries that changed. */ 10157 10158 if (kt11 != 0) { 10159 i4 = 4; 10160 if (ltri[kt11 * 6 + 4] != kt1) { 10161 i4 = 5; 10162 if (ltri[kt11 * 6 + 5] != kt1) { 10163 i4 = 6; 10164 } 10165 } 10166 ltri[i4 + kt11 * 6] = kt2; 10167 } 10168 if (kt22 != 0) { 10169 i4 = 4; 10170 if (ltri[kt22 * 6 + 4] != kt2) { 10171 i4 = 5; 10172 if (ltri[kt22 * 6 + 5] != kt2) { 10173 i4 = 6; 10174 } 10175 } 10176 ltri[i4 + kt22 * 6] = kt1; 10177 } 10178 L5: 10179 ; 10180 } 10181 /* L6: */ 10182 } 10183 if (swp) { 10184 goto L4; 10185 } 10186 10187 /* Compute and store the negative circumcenters and radii of */ 10188 /* the pseudo-triangles in the first NT positions. */ 10189 10190 L7: 10191 i__1 = nt; 10192 for (kt = 1; kt <= i__1; ++kt) { 10193 n1 = ltri[kt * 6 + 1]; 10194 n2 = ltri[kt * 6 + 2]; 10195 n3 = ltri[kt * 6 + 3]; 10196 v1[0] = x[n1]; 10197 v1[1] = y[n1]; 10198 v1[2] = z__[n1]; 10199 v2[0] = x[n2]; 10200 v2[1] = y[n2]; 10201 v2[2] = z__[n2]; 10202 v3[0] = x[n3]; 10203 v3[1] = y[n3]; 10204 v3[2] = z__[n3]; 10205 circum_(v2, v1, v3, c__, &ierr); 10206 if (ierr != 0) { 10207 goto L23; 10208 } 10209 10210 /* Store the negative circumcenter and radius (computed */ 10211 /* from <V1,C>). */ 10212 10213 xc[kt] = -c__[0]; 10214 yc[kt] = -c__[1]; 10215 zc[kt] = -c__[2]; 10216 t = -(v1[0] * c__[0] + v1[1] * c__[1] + v1[2] * c__[2]); 10217 if (t < -1.) { 10218 t = -1.; 10219 } 10220 if (t > 1.) { 10221 t = 1.; 10222 } 10223 rc[kt] = acos(t); 10224 /* L8: */ 10225 } 10226 10227 /* Compute and store the circumcenters and radii of the */ 10228 /* actual triangles in positions KT = NT+1, NT+2, ... */ 10229 /* Also, store the triangle indexes KT in the appropriate */ 10230 /* LISTC positions. */ 10231 10232 L9: 10233 kt = nt; 10234 10235 /* Loop on nodes N1. */ 10236 10237 nm2 = nn - 2; 10238 i__1 = nm2; 10239 for (n1 = 1; n1 <= i__1; ++n1) { 10240 lpl = lend[n1]; 10241 lp = lpl; 10242 n3 = list[lp]; 10243 10244 /* Loop on adjacent neighbors N2,N3 of N1 for which N2 > N1 */ 10245 /* and N3 > N1. */ 10246 10247 L10: 10248 lp = lptr[lp]; 10249 n2 = n3; 10250 n3 = (i__2 = list[lp], abs(i__2)); 10251 if (n2 <= n1 || n3 <= n1) { 10252 goto L11; 10253 } 10254 ++kt; 10255 10256 /* Compute the circumcenter C of triangle KT = (N1,N2,N3). */ 10257 10258 v1[0] = x[n1]; 10259 v1[1] = y[n1]; 10260 v1[2] = z__[n1]; 10261 v2[0] = x[n2]; 10262 v2[1] = y[n2]; 10263 v2[2] = z__[n2]; 10264 v3[0] = x[n3]; 10265 v3[1] = y[n3]; 10266 v3[2] = z__[n3]; 10267 circum_(v1, v2, v3, c__, &ierr); 10268 if (ierr != 0) { 10269 goto L23; 10270 } 10271 10272 /* Store the circumcenter, radius and triangle index. */ 10273 10274 xc[kt] = c__[0]; 10275 yc[kt] = c__[1]; 10276 zc[kt] = c__[2]; 10277 t = v1[0] * c__[0] + v1[1] * c__[1] + v1[2] * c__[2]; 10278 if (t < -1.) { 10279 t = -1.; 10280 } 10281 if (t > 1.) { 10282 t = 1.; 10283 } 10284 rc[kt] = acos(t); 10285 10286 /* Store KT in LISTC(LPN), where Abs(LIST(LPN)) is the */ 10287 /* index of N2 as a neighbor of N1, N3 as a neighbor */ 10288 /* of N2, and N1 as a neighbor of N3. */ 10289 10290 lpn = lstptr_(&lpl, &n2, &list[1], &lptr[1]); 10291 listc[lpn] = kt; 10292 lpn = lstptr_(&lend[n2], &n3, &list[1], &lptr[1]); 10293 listc[lpn] = kt; 10294 lpn = lstptr_(&lend[n3], &n1, &list[1], &lptr[1]); 10295 listc[lpn] = kt; 10296 L11: 10297 if (lp != lpl) { 10298 goto L10; 10299 } 10300 /* L12: */ 10301 } 10302 if (nt == 0) { 10303 goto L20; 10304 } 10305 10306 /* Store the first NT triangle indexes in LISTC. */ 10307 10308 /* Find a boundary triangle KT1 = (N1,N2,N3) with a */ 10309 /* boundary arc opposite N3. */ 10310 10311 kt1 = 0; 10312 L13: 10313 ++kt1; 10314 if (ltri[kt1 * 6 + 4] == 0) { 10315 i1 = 2; 10316 i2 = 3; 10317 i3 = 1; 10318 goto L14; 10319 } else if (ltri[kt1 * 6 + 5] == 0) { 10320 i1 = 3; 10321 i2 = 1; 10322 i3 = 2; 10323 goto L14; 10324 } else if (ltri[kt1 * 6 + 6] == 0) { 10325 i1 = 1; 10326 i2 = 2; 10327 i3 = 3; 10328 goto L14; 10329 } 10330 goto L13; 10331 L14: 10332 n1 = ltri[i1 + kt1 * 6]; 10333 n0 = n1; 10334 10335 /* Loop on boundary nodes N1 in CCW order, storing the */ 10336 /* indexes of the clockwise-ordered sequence of triangles */ 10337 /* that contain N1. The first triangle overwrites the */ 10338 /* last neighbor position, and the remaining triangles, */ 10339 /* if any, are appended to N1's adjacency list. */ 10340 10341 /* A pointer to the first neighbor of N1 is saved in LPN. */ 10342 10343 L15: 10344 lp = lend[n1]; 10345 lpn = lptr[lp]; 10346 listc[lp] = kt1; 10347 10348 /* Loop on triangles KT2 containing N1. */ 10349 10350 L16: 10351 kt2 = ltri[i2 + 3 + kt1 * 6]; 10352 if (kt2 != 0) { 10353 10354 /* Append KT2 to N1's triangle list. */ 10355 10356 lptr[lp] = *lnew; 10357 lp = *lnew; 10358 listc[lp] = kt2; 10359 ++(*lnew); 10360 10361 /* Set KT1 to KT2 and update (I1,I2,I3) such that */ 10362 /* LTRI(I1,KT1) = N1. */ 10363 10364 kt1 = kt2; 10365 if (ltri[kt1 * 6 + 1] == n1) { 10366 i1 = 1; 10367 i2 = 2; 10368 i3 = 3; 10369 } else if (ltri[kt1 * 6 + 2] == n1) { 10370 i1 = 2; 10371 i2 = 3; 10372 i3 = 1; 10373 } else { 10374 i1 = 3; 10375 i2 = 1; 10376 i3 = 2; 10377 } 10378 goto L16; 10379 } 10380 10381 /* Store the saved first-triangle pointer in LPTR(LP), set */ 10382 /* N1 to the next boundary node, test for termination, */ 10383 /* and permute the indexes: the last triangle containing */ 10384 /* a boundary node is the first triangle containing the */ 10385 /* next boundary node. */ 10386 10387 lptr[lp] = lpn; 10388 n1 = ltri[i3 + kt1 * 6]; 10389 if (n1 != n0) { 10390 i4 = i3; 10391 i3 = i2; 10392 i2 = i1; 10393 i1 = i4; 10394 goto L15; 10395 } 10396 10397 /* No errors encountered. */ 10398 10399 L20: 10400 *ier = 0; 10401 return 0; 10402 10403 /* N < 3. */ 10404 10405 L21: 10406 *ier = 1; 10407 return 0; 10408 10409 /* Insufficient space reserved for LTRI. */ 10410 10411 L22: 10412 *ier = 2; 10413 return 0; 10414 10415 /* Error flag returned by CIRCUM: KT indexes a null triangle. */ 10416 10417 L23: 10418 *ier = 3; 10419 return 0; 10420 } /* crlist_ */
int delarc_ | ( | int * | n, | |
int * | io1, | |||
int * | io2, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | lnew, | |||
int * | ier | |||
) |
Definition at line 10422 of file util_sparx.cpp.
References abs, delnb_(), and lstptr_().
10424 { 10425 /* System generated locals */ 10426 int i__1; 10427 10428 /* Local variables */ 10429 static int n1, n2, n3, lp, lph, lpl; 10430 /* Subroutine */ int delnb_(int *, int *, int *, 10431 int *, int *, int *, int *, int *); 10432 int lstptr_(int *, int *, int *, int *); 10433 10434 10435 /* *********************************************************** */ 10436 10437 /* From STRIPACK */ 10438 /* Robert J. Renka */ 10439 /* Dept. of Computer Science */ 10440 /* Univ. of North Texas */ 10441 /* renka@cs.unt.edu */ 10442 /* 07/17/96 */ 10443 10444 /* This subroutine deletes a boundary arc from a triangula- */ 10445 /* tion. It may be used to remove a null triangle from the */ 10446 /* convex hull boundary. Note, however, that if the union of */ 10447 /* triangles is rendered nonconvex, Subroutines DELNOD, EDGE, */ 10448 /* and TRFIND (and hence ADDNOD) may fail. Also, Function */ 10449 /* NEARND should not be called following an arc deletion. */ 10450 10451 /* This routine is identical to the similarly named routine */ 10452 /* in TRIPACK. */ 10453 10454 10455 /* On input: */ 10456 10457 /* N = Number of nodes in the triangulation. N .GE. 4. */ 10458 10459 /* IO1,IO2 = Indexes (in the range 1 to N) of a pair of */ 10460 /* adjacent boundary nodes defining the arc */ 10461 /* to be removed. */ 10462 10463 /* The above parameters are not altered by this routine. */ 10464 10465 /* LIST,LPTR,LEND,LNEW = Triangulation data structure */ 10466 /* created by Subroutine TRMESH. */ 10467 10468 /* On output: */ 10469 10470 /* LIST,LPTR,LEND,LNEW = Data structure updated with */ 10471 /* the removal of arc IO1-IO2 */ 10472 /* unless IER > 0. */ 10473 10474 /* IER = Error indicator: */ 10475 /* IER = 0 if no errors were encountered. */ 10476 /* IER = 1 if N, IO1, or IO2 is outside its valid */ 10477 /* range, or IO1 = IO2. */ 10478 /* IER = 2 if IO1-IO2 is not a boundary arc. */ 10479 /* IER = 3 if the node opposite IO1-IO2 is al- */ 10480 /* ready a boundary node, and thus IO1 */ 10481 /* or IO2 has only two neighbors or a */ 10482 /* deletion would result in two triangu- */ 10483 /* lations sharing a single node. */ 10484 /* IER = 4 if one of the nodes is a neighbor of */ 10485 /* the other, but not vice versa, imply- */ 10486 /* ing an invalid triangulation data */ 10487 /* structure. */ 10488 10489 /* Module required by DELARC: DELNB, LSTPTR */ 10490 10491 /* Intrinsic function called by DELARC: ABS */ 10492 10493 /* *********************************************************** */ 10494 10495 10496 /* Local parameters: */ 10497 10498 /* LP = LIST pointer */ 10499 /* LPH = LIST pointer or flag returned by DELNB */ 10500 /* LPL = Pointer to the last neighbor of N1, N2, or N3 */ 10501 /* N1,N2,N3 = Nodal indexes of a triangle such that N1->N2 */ 10502 /* is the directed boundary edge associated */ 10503 /* with IO1-IO2 */ 10504 10505 /* Parameter adjustments */ 10506 --lend; 10507 --list; 10508 --lptr; 10509 10510 /* Function Body */ 10511 n1 = *io1; 10512 n2 = *io2; 10513 10514 /* Test for errors, and set N1->N2 to the directed boundary */ 10515 /* edge associated with IO1-IO2: (N1,N2,N3) is a triangle */ 10516 /* for some N3. */ 10517 10518 if (*n < 4 || n1 < 1 || n1 > *n || n2 < 1 || n2 > *n || n1 == n2) { 10519 *ier = 1; 10520 return 0; 10521 } 10522 10523 lpl = lend[n2]; 10524 if (-list[lpl] != n1) { 10525 n1 = n2; 10526 n2 = *io1; 10527 lpl = lend[n2]; 10528 if (-list[lpl] != n1) { 10529 *ier = 2; 10530 return 0; 10531 } 10532 } 10533 10534 /* Set N3 to the node opposite N1->N2 (the second neighbor */ 10535 /* of N1), and test for error 3 (N3 already a boundary */ 10536 /* node). */ 10537 10538 lpl = lend[n1]; 10539 lp = lptr[lpl]; 10540 lp = lptr[lp]; 10541 n3 = (i__1 = list[lp], abs(i__1)); 10542 lpl = lend[n3]; 10543 if (list[lpl] <= 0) { 10544 *ier = 3; 10545 return 0; 10546 } 10547 10548 /* Delete N2 as a neighbor of N1, making N3 the first */ 10549 /* neighbor, and test for error 4 (N2 not a neighbor */ 10550 /* of N1). Note that previously computed pointers may */ 10551 /* no longer be valid following the call to DELNB. */ 10552 10553 delnb_(&n1, &n2, n, &list[1], &lptr[1], &lend[1], lnew, &lph); 10554 if (lph < 0) { 10555 *ier = 4; 10556 return 0; 10557 } 10558 10559 /* Delete N1 as a neighbor of N2, making N3 the new last */ 10560 /* neighbor. */ 10561 10562 delnb_(&n2, &n1, n, &list[1], &lptr[1], &lend[1], lnew, &lph); 10563 10564 /* Make N3 a boundary node with first neighbor N2 and last */ 10565 /* neighbor N1. */ 10566 10567 lp = lstptr_(&lend[n3], &n1, &list[1], &lptr[1]); 10568 lend[n3] = lp; 10569 list[lp] = -n1; 10570 10571 /* No errors encountered. */ 10572 10573 *ier = 0; 10574 return 0; 10575 } /* delarc_ */
int delnb_ | ( | int * | n0, | |
int * | nb, | |||
int * | n, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | lnew, | |||
int * | lph | |||
) |
Definition at line 10577 of file util_sparx.cpp.
Referenced by delarc_(), and delnod_().
10579 { 10580 /* System generated locals */ 10581 int i__1; 10582 10583 /* Local variables */ 10584 static int i__, lp, nn, lpb, lpl, lpp, lnw; 10585 10586 10587 /* *********************************************************** */ 10588 10589 /* From STRIPACK */ 10590 /* Robert J. Renka */ 10591 /* Dept. of Computer Science */ 10592 /* Univ. of North Texas */ 10593 /* renka@cs.unt.edu */ 10594 /* 07/29/98 */ 10595 10596 /* This subroutine deletes a neighbor NB from the adjacency */ 10597 /* list of node N0 (but N0 is not deleted from the adjacency */ 10598 /* list of NB) and, if NB is a boundary node, makes N0 a */ 10599 /* boundary node. For pointer (LIST index) LPH to NB as a */ 10600 /* neighbor of N0, the empty LIST,LPTR location LPH is filled */ 10601 /* in with the values at LNEW-1, pointer LNEW-1 (in LPTR and */ 10602 /* possibly in LEND) is changed to LPH, and LNEW is decremen- */ 10603 /* ted. This requires a search of LEND and LPTR entailing an */ 10604 /* expected operation count of O(N). */ 10605 10606 /* This routine is identical to the similarly named routine */ 10607 /* in TRIPACK. */ 10608 10609 10610 /* On input: */ 10611 10612 /* N0,NB = Indexes, in the range 1 to N, of a pair of */ 10613 /* nodes such that NB is a neighbor of N0. */ 10614 /* (N0 need not be a neighbor of NB.) */ 10615 10616 /* N = Number of nodes in the triangulation. N .GE. 3. */ 10617 10618 /* The above parameters are not altered by this routine. */ 10619 10620 /* LIST,LPTR,LEND,LNEW = Data structure defining the */ 10621 /* triangulation. */ 10622 10623 /* On output: */ 10624 10625 /* LIST,LPTR,LEND,LNEW = Data structure updated with */ 10626 /* the removal of NB from the ad- */ 10627 /* jacency list of N0 unless */ 10628 /* LPH < 0. */ 10629 10630 /* LPH = List pointer to the hole (NB as a neighbor of */ 10631 /* N0) filled in by the values at LNEW-1 or error */ 10632 /* indicator: */ 10633 /* LPH > 0 if no errors were encountered. */ 10634 /* LPH = -1 if N0, NB, or N is outside its valid */ 10635 /* range. */ 10636 /* LPH = -2 if NB is not a neighbor of N0. */ 10637 10638 /* Modules required by DELNB: None */ 10639 10640 /* Intrinsic function called by DELNB: ABS */ 10641 10642 /* *********************************************************** */ 10643 10644 10645 /* Local parameters: */ 10646 10647 /* I = DO-loop index */ 10648 /* LNW = LNEW-1 (output value of LNEW) */ 10649 /* LP = LIST pointer of the last neighbor of NB */ 10650 /* LPB = Pointer to NB as a neighbor of N0 */ 10651 /* LPL = Pointer to the last neighbor of N0 */ 10652 /* LPP = Pointer to the neighbor of N0 that precedes NB */ 10653 /* NN = Local copy of N */ 10654 10655 /* Parameter adjustments */ 10656 --lend; 10657 --list; 10658 --lptr; 10659 10660 /* Function Body */ 10661 nn = *n; 10662 10663 /* Test for error 1. */ 10664 10665 if (*n0 < 1 || *n0 > nn || *nb < 1 || *nb > nn || nn < 3) { 10666 *lph = -1; 10667 return 0; 10668 } 10669 10670 /* Find pointers to neighbors of N0: */ 10671 10672 /* LPL points to the last neighbor, */ 10673 /* LPP points to the neighbor NP preceding NB, and */ 10674 /* LPB points to NB. */ 10675 10676 lpl = lend[*n0]; 10677 lpp = lpl; 10678 lpb = lptr[lpp]; 10679 L1: 10680 if (list[lpb] == *nb) { 10681 goto L2; 10682 } 10683 lpp = lpb; 10684 lpb = lptr[lpp]; 10685 if (lpb != lpl) { 10686 goto L1; 10687 } 10688 10689 /* Test for error 2 (NB not found). */ 10690 10691 if ((i__1 = list[lpb], abs(i__1)) != *nb) { 10692 *lph = -2; 10693 return 0; 10694 } 10695 10696 /* NB is the last neighbor of N0. Make NP the new last */ 10697 /* neighbor and, if NB is a boundary node, then make N0 */ 10698 /* a boundary node. */ 10699 10700 lend[*n0] = lpp; 10701 lp = lend[*nb]; 10702 if (list[lp] < 0) { 10703 list[lpp] = -list[lpp]; 10704 } 10705 goto L3; 10706 10707 /* NB is not the last neighbor of N0. If NB is a boundary */ 10708 /* node and N0 is not, then make N0 a boundary node with */ 10709 /* last neighbor NP. */ 10710 10711 L2: 10712 lp = lend[*nb]; 10713 if (list[lp] < 0 && list[lpl] > 0) { 10714 lend[*n0] = lpp; 10715 list[lpp] = -list[lpp]; 10716 } 10717 10718 /* Update LPTR so that the neighbor following NB now fol- */ 10719 /* lows NP, and fill in the hole at location LPB. */ 10720 10721 L3: 10722 lptr[lpp] = lptr[lpb]; 10723 lnw = *lnew - 1; 10724 list[lpb] = list[lnw]; 10725 lptr[lpb] = lptr[lnw]; 10726 for (i__ = nn; i__ >= 1; --i__) { 10727 if (lend[i__] == lnw) { 10728 lend[i__] = lpb; 10729 goto L5; 10730 } 10731 /* L4: */ 10732 } 10733 10734 L5: 10735 i__1 = lnw - 1; 10736 for (i__ = 1; i__ <= i__1; ++i__) { 10737 if (lptr[i__] == lnw) { 10738 lptr[i__] = lpb; 10739 } 10740 /* L6: */ 10741 } 10742 10743 /* No errors encountered. */ 10744 10745 *lnew = lnw; 10746 *lph = lpb; 10747 return 0; 10748 } /* delnb_ */
int delnod_ | ( | int * | k, | |
int * | n, | |||
double * | x, | |||
double * | y, | |||
double * | z__, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | lnew, | |||
int * | lwk, | |||
int * | iwk, | |||
int * | ier | |||
) |
Definition at line 10750 of file util_sparx.cpp.
References abs, delnb_(), FALSE_, ierr, left_(), lstptr_(), nbcnt_(), nn(), optim_(), swap_(), and TRUE_.
10753 { 10754 /* System generated locals */ 10755 int i__1; 10756 10757 /* Local variables */ 10758 static int i__, j, n1, n2; 10759 static double x1, x2, y1, y2, z1, z2; 10760 static int nl, lp, nn, nr; 10761 static double xl, yl, zl, xr, yr, zr; 10762 static int nnb, lp21, lpf, lph, lpl, lpn, iwl, nit, lnw, lpl2; 10763 static long int bdry; 10764 static int ierr, lwkl; 10765 /* Subroutine */ int swap_(int *, int *, int *, 10766 int *, int *, int *, int *, int *), delnb_( 10767 int *, int *, int *, int *, int *, int *, 10768 int *, int *); 10769 int nbcnt_(int *, int *); 10770 /* Subroutine */ int optim_(double *, double *, double 10771 *, int *, int *, int *, int *, int *, int 10772 *, int *); 10773 static int nfrst; 10774 int lstptr_(int *, int *, int *, int *); 10775 10776 10777 /* *********************************************************** */ 10778 10779 /* From STRIPACK */ 10780 /* Robert J. Renka */ 10781 /* Dept. of Computer Science */ 10782 /* Univ. of North Texas */ 10783 /* renka@cs.unt.edu */ 10784 /* 11/30/99 */ 10785 10786 /* This subroutine deletes node K (along with all arcs */ 10787 /* incident on node K) from a triangulation of N nodes on the */ 10788 /* unit sphere, and inserts arcs as necessary to produce a */ 10789 /* triangulation of the remaining N-1 nodes. If a Delaunay */ 10790 /* triangulation is input, a Delaunay triangulation will */ 10791 /* result, and thus, DELNOD reverses the effect of a call to */ 10792 /* Subroutine ADDNOD. */ 10793 10794 10795 /* On input: */ 10796 10797 /* K = Index (for X, Y, and Z) of the node to be */ 10798 /* deleted. 1 .LE. K .LE. N. */ 10799 10800 /* K is not altered by this routine. */ 10801 10802 /* N = Number of nodes in the triangulation on input. */ 10803 /* N .GE. 4. Note that N will be decremented */ 10804 /* following the deletion. */ 10805 10806 /* X,Y,Z = Arrays of length N containing the Cartesian */ 10807 /* coordinates of the nodes in the triangula- */ 10808 /* tion. */ 10809 10810 /* LIST,LPTR,LEND,LNEW = Data structure defining the */ 10811 /* triangulation. Refer to Sub- */ 10812 /* routine TRMESH. */ 10813 10814 /* LWK = Number of columns reserved for IWK. LWK must */ 10815 /* be at least NNB-3, where NNB is the number of */ 10816 /* neighbors of node K, including an extra */ 10817 /* pseudo-node if K is a boundary node. */ 10818 10819 /* IWK = int work array dimensioned 2 by LWK (or */ 10820 /* array of length .GE. 2*LWK). */ 10821 10822 /* On output: */ 10823 10824 /* N = Number of nodes in the triangulation on output. */ 10825 /* The input value is decremented unless 1 .LE. IER */ 10826 /* .LE. 4. */ 10827 10828 /* X,Y,Z = Updated arrays containing nodal coordinates */ 10829 /* (with elements K+1,...,N+1 shifted up one */ 10830 /* position, thus overwriting element K) unless */ 10831 /* 1 .LE. IER .LE. 4. */ 10832 10833 /* LIST,LPTR,LEND,LNEW = Updated triangulation data */ 10834 /* structure reflecting the dele- */ 10835 /* tion unless 1 .LE. IER .LE. 4. */ 10836 /* Note that the data structure */ 10837 /* may have been altered if IER > */ 10838 /* 3. */ 10839 10840 /* LWK = Number of IWK columns required unless IER = 1 */ 10841 /* or IER = 3. */ 10842 10843 /* IWK = Indexes of the endpoints of the new arcs added */ 10844 /* unless LWK = 0 or 1 .LE. IER .LE. 4. (Arcs */ 10845 /* are associated with columns, or pairs of */ 10846 /* adjacent elements if IWK is declared as a */ 10847 /* singly-subscripted array.) */ 10848 10849 /* IER = Error indicator: */ 10850 /* IER = 0 if no errors were encountered. */ 10851 /* IER = 1 if K or N is outside its valid range */ 10852 /* or LWK < 0 on input. */ 10853 /* IER = 2 if more space is required in IWK. */ 10854 /* Refer to LWK. */ 10855 /* IER = 3 if the triangulation data structure is */ 10856 /* invalid on input. */ 10857 /* IER = 4 if K indexes an interior node with */ 10858 /* four or more neighbors, none of which */ 10859 /* can be swapped out due to collineari- */ 10860 /* ty, and K cannot therefore be deleted. */ 10861 /* IER = 5 if an error flag (other than IER = 1) */ 10862 /* was returned by OPTIM. An error */ 10863 /* message is written to the standard */ 10864 /* output unit in this case. */ 10865 /* IER = 6 if error flag 1 was returned by OPTIM. */ 10866 /* This is not necessarily an error, but */ 10867 /* the arcs may not be optimal. */ 10868 10869 /* Note that the deletion may result in all remaining nodes */ 10870 /* being collinear. This situation is not flagged. */ 10871 10872 /* Modules required by DELNOD: DELNB, LEFT, LSTPTR, NBCNT, */ 10873 /* OPTIM, SWAP, SWPTST */ 10874 10875 /* Intrinsic function called by DELNOD: ABS */ 10876 10877 /* *********************************************************** */ 10878 10879 10880 /* Local parameters: */ 10881 10882 /* BDRY = long int variable with value TRUE iff N1 is a */ 10883 /* boundary node */ 10884 /* I,J = DO-loop indexes */ 10885 /* IERR = Error flag returned by OPTIM */ 10886 /* IWL = Number of IWK columns containing arcs */ 10887 /* LNW = Local copy of LNEW */ 10888 /* LP = LIST pointer */ 10889 /* LP21 = LIST pointer returned by SWAP */ 10890 /* LPF,LPL = Pointers to the first and last neighbors of N1 */ 10891 /* LPH = Pointer (or flag) returned by DELNB */ 10892 /* LPL2 = Pointer to the last neighbor of N2 */ 10893 /* LPN = Pointer to a neighbor of N1 */ 10894 /* LWKL = Input value of LWK */ 10895 /* N1 = Local copy of K */ 10896 /* N2 = Neighbor of N1 */ 10897 /* NFRST = First neighbor of N1: LIST(LPF) */ 10898 /* NIT = Number of iterations in OPTIM */ 10899 /* NR,NL = Neighbors of N1 preceding (to the right of) and */ 10900 /* following (to the left of) N2, respectively */ 10901 /* NN = Number of nodes in the triangulation */ 10902 /* NNB = Number of neighbors of N1 (including a pseudo- */ 10903 /* node representing the boundary if N1 is a */ 10904 /* boundary node) */ 10905 /* X1,Y1,Z1 = Coordinates of N1 */ 10906 /* X2,Y2,Z2 = Coordinates of N2 */ 10907 /* XL,YL,ZL = Coordinates of NL */ 10908 /* XR,YR,ZR = Coordinates of NR */ 10909 10910 10911 /* Set N1 to K and NNB to the number of neighbors of N1 (plus */ 10912 /* one if N1 is a boundary node), and test for errors. LPF */ 10913 /* and LPL are LIST indexes of the first and last neighbors */ 10914 /* of N1, IWL is the number of IWK columns containing arcs, */ 10915 /* and BDRY is TRUE iff N1 is a boundary node. */ 10916 10917 /* Parameter adjustments */ 10918 iwk -= 3; 10919 --lend; 10920 --lptr; 10921 --list; 10922 --z__; 10923 --y; 10924 --x; 10925 10926 /* Function Body */ 10927 n1 = *k; 10928 nn = *n; 10929 if (n1 < 1 || n1 > nn || nn < 4 || *lwk < 0) { 10930 goto L21; 10931 } 10932 lpl = lend[n1]; 10933 lpf = lptr[lpl]; 10934 nnb = nbcnt_(&lpl, &lptr[1]); 10935 bdry = list[lpl] < 0; 10936 if (bdry) { 10937 ++nnb; 10938 } 10939 if (nnb < 3) { 10940 goto L23; 10941 } 10942 lwkl = *lwk; 10943 *lwk = nnb - 3; 10944 if (lwkl < *lwk) { 10945 goto L22; 10946 } 10947 iwl = 0; 10948 if (nnb == 3) { 10949 goto L3; 10950 } 10951 10952 /* Initialize for loop on arcs N1-N2 for neighbors N2 of N1, */ 10953 /* beginning with the second neighbor. NR and NL are the */ 10954 /* neighbors preceding and following N2, respectively, and */ 10955 /* LP indexes NL. The loop is exited when all possible */ 10956 /* swaps have been applied to arcs incident on N1. */ 10957 10958 x1 = x[n1]; 10959 y1 = y[n1]; 10960 z1 = z__[n1]; 10961 nfrst = list[lpf]; 10962 nr = nfrst; 10963 xr = x[nr]; 10964 yr = y[nr]; 10965 zr = z__[nr]; 10966 lp = lptr[lpf]; 10967 n2 = list[lp]; 10968 x2 = x[n2]; 10969 y2 = y[n2]; 10970 z2 = z__[n2]; 10971 lp = lptr[lp]; 10972 10973 /* Top of loop: set NL to the neighbor following N2. */ 10974 10975 L1: 10976 nl = (i__1 = list[lp], abs(i__1)); 10977 if (nl == nfrst && bdry) { 10978 goto L3; 10979 } 10980 xl = x[nl]; 10981 yl = y[nl]; 10982 zl = z__[nl]; 10983 10984 /* Test for a convex quadrilateral. To avoid an incorrect */ 10985 /* test caused by collinearity, use the fact that if N1 */ 10986 /* is a boundary node, then N1 LEFT NR->NL and if N2 is */ 10987 /* a boundary node, then N2 LEFT NL->NR. */ 10988 10989 lpl2 = lend[n2]; 10990 if (! ((bdry || left_(&xr, &yr, &zr, &xl, &yl, &zl, &x1, &y1, &z1)) && ( 10991 list[lpl2] < 0 || left_(&xl, &yl, &zl, &xr, &yr, &zr, &x2, &y2, & 10992 z2)))) { 10993 10994 /* Nonconvex quadrilateral -- no swap is possible. */ 10995 10996 nr = n2; 10997 xr = x2; 10998 yr = y2; 10999 zr = z2; 11000 goto L2; 11001 } 11002 11003 /* The quadrilateral defined by adjacent triangles */ 11004 /* (N1,N2,NL) and (N2,N1,NR) is convex. Swap in */ 11005 /* NL-NR and store it in IWK unless NL and NR are */ 11006 /* already adjacent, in which case the swap is not */ 11007 /* possible. Indexes larger than N1 must be decremented */ 11008 /* since N1 will be deleted from X, Y, and Z. */ 11009 11010 swap_(&nl, &nr, &n1, &n2, &list[1], &lptr[1], &lend[1], &lp21); 11011 if (lp21 == 0) { 11012 nr = n2; 11013 xr = x2; 11014 yr = y2; 11015 zr = z2; 11016 goto L2; 11017 } 11018 ++iwl; 11019 if (nl <= n1) { 11020 iwk[(iwl << 1) + 1] = nl; 11021 } else { 11022 iwk[(iwl << 1) + 1] = nl - 1; 11023 } 11024 if (nr <= n1) { 11025 iwk[(iwl << 1) + 2] = nr; 11026 } else { 11027 iwk[(iwl << 1) + 2] = nr - 1; 11028 } 11029 11030 /* Recompute the LIST indexes and NFRST, and decrement NNB. */ 11031 11032 lpl = lend[n1]; 11033 --nnb; 11034 if (nnb == 3) { 11035 goto L3; 11036 } 11037 lpf = lptr[lpl]; 11038 nfrst = list[lpf]; 11039 lp = lstptr_(&lpl, &nl, &list[1], &lptr[1]); 11040 if (nr == nfrst) { 11041 goto L2; 11042 } 11043 11044 /* NR is not the first neighbor of N1. */ 11045 /* Back up and test N1-NR for a swap again: Set N2 to */ 11046 /* NR and NR to the previous neighbor of N1 -- the */ 11047 /* neighbor of NR which follows N1. LP21 points to NL */ 11048 /* as a neighbor of NR. */ 11049 11050 n2 = nr; 11051 x2 = xr; 11052 y2 = yr; 11053 z2 = zr; 11054 lp21 = lptr[lp21]; 11055 lp21 = lptr[lp21]; 11056 nr = (i__1 = list[lp21], abs(i__1)); 11057 xr = x[nr]; 11058 yr = y[nr]; 11059 zr = z__[nr]; 11060 goto L1; 11061 11062 /* Bottom of loop -- test for termination of loop. */ 11063 11064 L2: 11065 if (n2 == nfrst) { 11066 goto L3; 11067 } 11068 n2 = nl; 11069 x2 = xl; 11070 y2 = yl; 11071 z2 = zl; 11072 lp = lptr[lp]; 11073 goto L1; 11074 11075 /* Delete N1 and all its incident arcs. If N1 is an interior */ 11076 /* node and either NNB > 3 or NNB = 3 and N2 LEFT NR->NL, */ 11077 /* then N1 must be separated from its neighbors by a plane */ 11078 /* containing the origin -- its removal reverses the effect */ 11079 /* of a call to COVSPH, and all its neighbors become */ 11080 /* boundary nodes. This is achieved by treating it as if */ 11081 /* it were a boundary node (setting BDRY to TRUE, changing */ 11082 /* a sign in LIST, and incrementing NNB). */ 11083 11084 L3: 11085 if (! bdry) { 11086 if (nnb > 3) { 11087 bdry = TRUE_; 11088 } else { 11089 lpf = lptr[lpl]; 11090 nr = list[lpf]; 11091 lp = lptr[lpf]; 11092 n2 = list[lp]; 11093 nl = list[lpl]; 11094 bdry = left_(&x[nr], &y[nr], &z__[nr], &x[nl], &y[nl], &z__[nl], & 11095 x[n2], &y[n2], &z__[n2]); 11096 } 11097 if (bdry) { 11098 11099 /* IF a boundary node already exists, then N1 and its */ 11100 /* neighbors cannot be converted to boundary nodes. */ 11101 /* (They must be collinear.) This is a problem if */ 11102 /* NNB > 3. */ 11103 11104 i__1 = nn; 11105 for (i__ = 1; i__ <= i__1; ++i__) { 11106 if (list[lend[i__]] < 0) { 11107 bdry = FALSE_; 11108 goto L5; 11109 } 11110 /* L4: */ 11111 } 11112 list[lpl] = -list[lpl]; 11113 ++nnb; 11114 } 11115 } 11116 L5: 11117 if (! bdry && nnb > 3) { 11118 goto L24; 11119 } 11120 11121 /* Initialize for loop on neighbors. LPL points to the last */ 11122 /* neighbor of N1. LNEW is stored in local variable LNW. */ 11123 11124 lp = lpl; 11125 lnw = *lnew; 11126 11127 /* Loop on neighbors N2 of N1, beginning with the first. */ 11128 11129 L6: 11130 lp = lptr[lp]; 11131 n2 = (i__1 = list[lp], abs(i__1)); 11132 delnb_(&n2, &n1, n, &list[1], &lptr[1], &lend[1], &lnw, &lph); 11133 if (lph < 0) { 11134 goto L23; 11135 } 11136 11137 /* LP and LPL may require alteration. */ 11138 11139 if (lpl == lnw) { 11140 lpl = lph; 11141 } 11142 if (lp == lnw) { 11143 lp = lph; 11144 } 11145 if (lp != lpl) { 11146 goto L6; 11147 } 11148 11149 /* Delete N1 from X, Y, Z, and LEND, and remove its adjacency */ 11150 /* list from LIST and LPTR. LIST entries (nodal indexes) */ 11151 /* which are larger than N1 must be decremented. */ 11152 11153 --nn; 11154 if (n1 > nn) { 11155 goto L9; 11156 } 11157 i__1 = nn; 11158 for (i__ = n1; i__ <= i__1; ++i__) { 11159 x[i__] = x[i__ + 1]; 11160 y[i__] = y[i__ + 1]; 11161 z__[i__] = z__[i__ + 1]; 11162 lend[i__] = lend[i__ + 1]; 11163 /* L7: */ 11164 } 11165 11166 i__1 = lnw - 1; 11167 for (i__ = 1; i__ <= i__1; ++i__) { 11168 if (list[i__] > n1) { 11169 --list[i__]; 11170 } 11171 if (list[i__] < -n1) { 11172 ++list[i__]; 11173 } 11174 /* L8: */ 11175 } 11176 11177 /* For LPN = first to last neighbors of N1, delete the */ 11178 /* preceding neighbor (indexed by LP). */ 11179 11180 /* Each empty LIST,LPTR location LP is filled in with the */ 11181 /* values at LNW-1, and LNW is decremented. All pointers */ 11182 /* (including those in LPTR and LEND) with value LNW-1 */ 11183 /* must be changed to LP. */ 11184 11185 /* LPL points to the last neighbor of N1. */ 11186 11187 L9: 11188 if (bdry) { 11189 --nnb; 11190 } 11191 lpn = lpl; 11192 i__1 = nnb; 11193 for (j = 1; j <= i__1; ++j) { 11194 --lnw; 11195 lp = lpn; 11196 lpn = lptr[lp]; 11197 list[lp] = list[lnw]; 11198 lptr[lp] = lptr[lnw]; 11199 if (lptr[lpn] == lnw) { 11200 lptr[lpn] = lp; 11201 } 11202 if (lpn == lnw) { 11203 lpn = lp; 11204 } 11205 for (i__ = nn; i__ >= 1; --i__) { 11206 if (lend[i__] == lnw) { 11207 lend[i__] = lp; 11208 goto L11; 11209 } 11210 /* L10: */ 11211 } 11212 11213 L11: 11214 for (i__ = lnw - 1; i__ >= 1; --i__) { 11215 if (lptr[i__] == lnw) { 11216 lptr[i__] = lp; 11217 } 11218 /* L12: */ 11219 } 11220 /* L13: */ 11221 } 11222 11223 /* Update N and LNEW, and optimize the patch of triangles */ 11224 /* containing K (on input) by applying swaps to the arcs */ 11225 /* in IWK. */ 11226 11227 *n = nn; 11228 *lnew = lnw; 11229 if (iwl > 0) { 11230 nit = iwl << 2; 11231 optim_(&x[1], &y[1], &z__[1], &iwl, &list[1], &lptr[1], &lend[1], & 11232 nit, &iwk[3], &ierr); 11233 if (ierr != 0 && ierr != 1) { 11234 goto L25; 11235 } 11236 if (ierr == 1) { 11237 goto L26; 11238 } 11239 } 11240 11241 /* Successful termination. */ 11242 11243 *ier = 0; 11244 return 0; 11245 11246 /* Invalid input parameter. */ 11247 11248 L21: 11249 *ier = 1; 11250 return 0; 11251 11252 /* Insufficient space reserved for IWK. */ 11253 11254 L22: 11255 *ier = 2; 11256 return 0; 11257 11258 /* Invalid triangulation data structure. NNB < 3 on input or */ 11259 /* N2 is a neighbor of N1 but N1 is not a neighbor of N2. */ 11260 11261 L23: 11262 *ier = 3; 11263 return 0; 11264 11265 /* N1 is interior but NNB could not be reduced to 3. */ 11266 11267 L24: 11268 *ier = 4; 11269 return 0; 11270 11271 /* Error flag (other than 1) returned by OPTIM. */ 11272 11273 L25: 11274 *ier = 5; 11275 /* WRITE (*,100) NIT, IERR */ 11276 /* 100 FORMAT (//5X,'*** Error in OPTIM (called from ', */ 11277 /* . 'DELNOD): NIT = ',I4,', IER = ',I1,' ***'/) */ 11278 return 0; 11279 11280 /* Error flag 1 returned by OPTIM. */ 11281 11282 L26: 11283 *ier = 6; 11284 return 0; 11285 } /* delnod_ */
int drwarc_ | ( | int * | , | |
double * | p, | |||
double * | q, | |||
double * | tol, | |||
int * | nseg | |||
) |
Definition at line 11287 of file util_sparx.cpp.
Referenced by trplot_(), and vrplot_().
11289 { 11290 /* System generated locals */ 11291 int i__1; 11292 double d__1; 11293 11294 /* Builtin functions */ 11295 //double sqrt(double); 11296 11297 /* Local variables */ 11298 static int i__, k; 11299 static double s, p1[3], p2[3], u1, u2, v1, v2; 11300 static int na; 11301 static double dp[3], du, dv, pm[3], um, vm, err, enrm; 11302 11303 11304 /* *********************************************************** */ 11305 11306 /* From STRIPACK */ 11307 /* Robert J. Renka */ 11308 /* Dept. of Computer Science */ 11309 /* Univ. of North Texas */ 11310 /* renka@cs.unt.edu */ 11311 /* 03/04/03 */ 11312 11313 /* Given unit vectors P and Q corresponding to northern */ 11314 /* hemisphere points (with positive third components), this */ 11315 /* subroutine draws a polygonal line which approximates the */ 11316 /* projection of arc P-Q onto the plane containing the */ 11317 /* equator. */ 11318 11319 /* The line segment is drawn by writing a sequence of */ 11320 /* 'moveto' and 'lineto' Postscript commands to unit LUN. It */ 11321 /* is assumed that an open file is attached to the unit, */ 11322 /* header comments have been written to the file, a window- */ 11323 /* to-viewport mapping has been established, etc. */ 11324 11325 /* On input: */ 11326 11327 /* LUN = long int unit number in the range 0 to 99. */ 11328 11329 /* P,Q = Arrays of length 3 containing the endpoints of */ 11330 /* the arc to be drawn. */ 11331 11332 /* TOL = Maximum distance in world coordinates between */ 11333 /* the projected arc and polygonal line. */ 11334 11335 /* Input parameters are not altered by this routine. */ 11336 11337 /* On output: */ 11338 11339 /* NSEG = Number of line segments in the polygonal */ 11340 /* approximation to the projected arc. This is */ 11341 /* a decreasing function of TOL. NSEG = 0 and */ 11342 /* no drawing is performed if P = Q or P = -Q */ 11343 /* or an error is encountered in writing to unit */ 11344 /* LUN. */ 11345 11346 /* STRIPACK modules required by DRWARC: None */ 11347 11348 /* Intrinsic functions called by DRWARC: ABS, DBLE, SQRT */ 11349 11350 /* *********************************************************** */ 11351 11352 11353 /* Local parameters: */ 11354 11355 /* DP = (Q-P)/NSEG */ 11356 /* DU,DV = Components of the projection Q'-P' of arc P->Q */ 11357 /* onto the projection plane */ 11358 /* ENRM = Euclidean norm (or squared norm) of Q'-P' or PM */ 11359 /* ERR = Orthogonal distance from the projected midpoint */ 11360 /* PM' to the line defined by P' and Q': */ 11361 /* |Q'-P' X PM'-P'|/|Q'-P'| */ 11362 /* I,K = DO-loop indexes */ 11363 /* NA = Number of arcs (segments) in the partition of P-Q */ 11364 /* P1,P2 = Pairs of adjacent points in a uniform partition of */ 11365 /* arc P-Q into NSEG segments; obtained by normal- */ 11366 /* izing PM values */ 11367 /* PM = Midpoint of arc P-Q or a point P + k*DP in a */ 11368 /* uniform partition of the line segment P-Q into */ 11369 /* NSEG segments */ 11370 /* S = Scale factor 1/NA */ 11371 /* U1,V1 = Components of P' */ 11372 /* U2,V2 = Components of Q' */ 11373 /* UM,VM = Components of the midpoint PM' */ 11374 11375 11376 /* Compute the midpoint PM of arc P-Q. */ 11377 11378 /* Parameter adjustments */ 11379 --q; 11380 --p; 11381 11382 /* Function Body */ 11383 enrm = 0.; 11384 for (i__ = 1; i__ <= 3; ++i__) { 11385 pm[i__ - 1] = p[i__] + q[i__]; 11386 enrm += pm[i__ - 1] * pm[i__ - 1]; 11387 /* L1: */ 11388 } 11389 if (enrm == 0.) { 11390 goto L5; 11391 } 11392 enrm = sqrt(enrm); 11393 pm[0] /= enrm; 11394 pm[1] /= enrm; 11395 pm[2] /= enrm; 11396 11397 /* Project P, Q, and PM to P' = (U1,V1), Q' = (U2,V2), and */ 11398 /* PM' = (UM,VM), respectively. */ 11399 11400 u1 = p[1]; 11401 v1 = p[2]; 11402 u2 = q[1]; 11403 v2 = q[2]; 11404 um = pm[0]; 11405 vm = pm[1]; 11406 11407 /* Compute the orthogonal distance ERR from PM' to the line */ 11408 /* defined by P' and Q'. This is the maximum deviation */ 11409 /* between the projected arc and the line segment. It is */ 11410 /* undefined if P' = Q'. */ 11411 11412 du = u2 - u1; 11413 dv = v2 - v1; 11414 enrm = du * du + dv * dv; 11415 if (enrm == 0.) { 11416 goto L5; 11417 } 11418 err = (d__1 = du * (vm - v1) - (um - u1) * dv, abs(d__1)) / sqrt(enrm); 11419 11420 /* Compute the number of arcs into which P-Q will be parti- */ 11421 /* tioned (the number of line segments to be drawn): */ 11422 /* NA = ERR/TOL. */ 11423 11424 na = (int) (err / *tol + 1.); 11425 11426 /* Initialize for loop on arcs P1-P2, where the intermediate */ 11427 /* points are obtained by normalizing PM = P + k*DP for */ 11428 /* DP = (Q-P)/NA */ 11429 11430 s = 1. / (double) na; 11431 for (i__ = 1; i__ <= 3; ++i__) { 11432 dp[i__ - 1] = s * (q[i__] - p[i__]); 11433 pm[i__ - 1] = p[i__]; 11434 p1[i__ - 1] = p[i__]; 11435 /* L2: */ 11436 } 11437 11438 /* Loop on arcs P1-P2, drawing the line segments associated */ 11439 /* with the projected endpoints. */ 11440 11441 i__1 = na - 1; 11442 for (k = 1; k <= i__1; ++k) { 11443 enrm = 0.; 11444 for (i__ = 1; i__ <= 3; ++i__) { 11445 pm[i__ - 1] += dp[i__ - 1]; 11446 enrm += pm[i__ - 1] * pm[i__ - 1]; 11447 /* L3: */ 11448 } 11449 if (enrm == 0.) { 11450 goto L5; 11451 } 11452 enrm = sqrt(enrm); 11453 p2[0] = pm[0] / enrm; 11454 p2[1] = pm[1] / enrm; 11455 p2[2] = pm[2] / enrm; 11456 /* WRITE (LUN,100,ERR=5) P1(1), P1(2), P2(1), P2(2) */ 11457 /* 100 FORMAT (2F12.6,' moveto',2F12.6,' lineto') */ 11458 p1[0] = p2[0]; 11459 p1[1] = p2[1]; 11460 p1[2] = p2[2]; 11461 /* L4: */ 11462 } 11463 /* WRITE (LUN,100,ERR=5) P1(1), P1(2), Q(1), Q(2) */ 11464 11465 /* No error encountered. */ 11466 11467 *nseg = na; 11468 return 0; 11469 11470 /* Invalid input value of P or Q. */ 11471 11472 L5: 11473 *nseg = 0; 11474 return 0; 11475 } /* drwarc_ */
int edge_ | ( | int * | in1, | |
int * | in2, | |||
double * | x, | |||
double * | y, | |||
double * | z__, | |||
int * | lwk, | |||
int * | iwk, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | ier | |||
) |
Definition at line 11477 of file util_sparx.cpp.
References abs, ierr, left_(), optim_(), and swap_().
11480 { 11481 /* System generated locals */ 11482 int i__1; 11483 11484 /* Local variables */ 11485 static int i__, n0, n1, n2; 11486 static double x0, x1, x2, y0, y1, y2, z0, z1, z2; 11487 static int nl, lp, nr; 11488 static double dp12; 11489 static int lp21, iwc, iwf, lft, lpl, iwl, nit; 11490 static double dp1l, dp2l, dp1r, dp2r; 11491 static int ierr; 11492 /* Subroutine */ int swap_(int *, int *, int *, 11493 int *, int *, int *, int *, int *); 11494 static int next, iwcp1, n1lst, iwend; 11495 /* Subroutine */ int optim_(double *, double *, double 11496 *, int *, int *, int *, int *, int *, int 11497 *, int *); 11498 static int n1frst; 11499 11500 11501 /* *********************************************************** */ 11502 11503 /* From STRIPACK */ 11504 /* Robert J. Renka */ 11505 /* Dept. of Computer Science */ 11506 /* Univ. of North Texas */ 11507 /* renka@cs.unt.edu */ 11508 /* 07/30/98 */ 11509 11510 /* Given a triangulation of N nodes and a pair of nodal */ 11511 /* indexes IN1 and IN2, this routine swaps arcs as necessary */ 11512 /* to force IN1 and IN2 to be adjacent. Only arcs which */ 11513 /* intersect IN1-IN2 are swapped out. If a Delaunay triangu- */ 11514 /* lation is input, the resulting triangulation is as close */ 11515 /* as possible to a Delaunay triangulation in the sense that */ 11516 /* all arcs other than IN1-IN2 are locally optimal. */ 11517 11518 /* A sequence of calls to EDGE may be used to force the */ 11519 /* presence of a set of edges defining the boundary of a non- */ 11520 /* convex and/or multiply connected region, or to introduce */ 11521 /* barriers into the triangulation. Note that Subroutine */ 11522 /* GETNP will not necessarily return closest nodes if the */ 11523 /* triangulation has been constrained by a call to EDGE. */ 11524 /* However, this is appropriate in some applications, such */ 11525 /* as triangle-based interpolation on a nonconvex domain. */ 11526 11527 11528 /* On input: */ 11529 11530 /* IN1,IN2 = Indexes (of X, Y, and Z) in the range 1 to */ 11531 /* N defining a pair of nodes to be connected */ 11532 /* by an arc. */ 11533 11534 /* X,Y,Z = Arrays of length N containing the Cartesian */ 11535 /* coordinates of the nodes. */ 11536 11537 /* The above parameters are not altered by this routine. */ 11538 11539 /* LWK = Number of columns reserved for IWK. This must */ 11540 /* be at least NI -- the number of arcs that */ 11541 /* intersect IN1-IN2. (NI is bounded by N-3.) */ 11542 11543 /* IWK = int work array of length at least 2*LWK. */ 11544 11545 /* LIST,LPTR,LEND = Data structure defining the trian- */ 11546 /* gulation. Refer to Subroutine */ 11547 /* TRMESH. */ 11548 11549 /* On output: */ 11550 11551 /* LWK = Number of arcs which intersect IN1-IN2 (but */ 11552 /* not more than the input value of LWK) unless */ 11553 /* IER = 1 or IER = 3. LWK = 0 if and only if */ 11554 /* IN1 and IN2 were adjacent (or LWK=0) on input. */ 11555 11556 /* IWK = Array containing the indexes of the endpoints */ 11557 /* of the new arcs other than IN1-IN2 unless */ 11558 /* IER > 0 or LWK = 0. New arcs to the left of */ 11559 /* IN1->IN2 are stored in the first K-1 columns */ 11560 /* (left portion of IWK), column K contains */ 11561 /* zeros, and new arcs to the right of IN1->IN2 */ 11562 /* occupy columns K+1,...,LWK. (K can be deter- */ 11563 /* mined by searching IWK for the zeros.) */ 11564 11565 /* LIST,LPTR,LEND = Data structure updated if necessary */ 11566 /* to reflect the presence of an arc */ 11567 /* connecting IN1 and IN2 unless IER > */ 11568 /* 0. The data structure has been */ 11569 /* altered if IER >= 4. */ 11570 11571 /* IER = Error indicator: */ 11572 /* IER = 0 if no errors were encountered. */ 11573 /* IER = 1 if IN1 < 1, IN2 < 1, IN1 = IN2, */ 11574 /* or LWK < 0 on input. */ 11575 /* IER = 2 if more space is required in IWK. */ 11576 /* Refer to LWK. */ 11577 /* IER = 3 if IN1 and IN2 could not be connected */ 11578 /* due to either an invalid data struc- */ 11579 /* ture or collinear nodes (and floating */ 11580 /* point error). */ 11581 /* IER = 4 if an error flag other than IER = 1 */ 11582 /* was returned by OPTIM. */ 11583 /* IER = 5 if error flag 1 was returned by OPTIM. */ 11584 /* This is not necessarily an error, but */ 11585 /* the arcs other than IN1-IN2 may not */ 11586 /* be optimal. */ 11587 11588 /* An error message is written to the standard output unit */ 11589 /* in the case of IER = 3 or IER = 4. */ 11590 11591 /* Modules required by EDGE: LEFT, LSTPTR, OPTIM, SWAP, */ 11592 /* SWPTST */ 11593 11594 /* Intrinsic function called by EDGE: ABS */ 11595 11596 /* *********************************************************** */ 11597 11598 11599 /* Local parameters: */ 11600 11601 /* DPij = Dot product <Ni,Nj> */ 11602 /* I = DO-loop index and column index for IWK */ 11603 /* IERR = Error flag returned by Subroutine OPTIM */ 11604 /* IWC = IWK index between IWF and IWL -- NL->NR is */ 11605 /* stored in IWK(1,IWC)->IWK(2,IWC) */ 11606 /* IWCP1 = IWC + 1 */ 11607 /* IWEND = Input or output value of LWK */ 11608 /* IWF = IWK (column) index of the first (leftmost) arc */ 11609 /* which intersects IN1->IN2 */ 11610 /* IWL = IWK (column) index of the last (rightmost) are */ 11611 /* which intersects IN1->IN2 */ 11612 /* LFT = Flag used to determine if a swap results in the */ 11613 /* new arc intersecting IN1-IN2 -- LFT = 0 iff */ 11614 /* N0 = IN1, LFT = -1 implies N0 LEFT IN1->IN2, */ 11615 /* and LFT = 1 implies N0 LEFT IN2->IN1 */ 11616 /* LP = List pointer (index for LIST and LPTR) */ 11617 /* LP21 = Unused parameter returned by SWAP */ 11618 /* LPL = Pointer to the last neighbor of IN1 or NL */ 11619 /* N0 = Neighbor of N1 or node opposite NR->NL */ 11620 /* N1,N2 = Local copies of IN1 and IN2 */ 11621 /* N1FRST = First neighbor of IN1 */ 11622 /* N1LST = (Signed) last neighbor of IN1 */ 11623 /* NEXT = Node opposite NL->NR */ 11624 /* NIT = Flag or number of iterations employed by OPTIM */ 11625 /* NL,NR = Endpoints of an arc which intersects IN1-IN2 */ 11626 /* with NL LEFT IN1->IN2 */ 11627 /* X0,Y0,Z0 = Coordinates of N0 */ 11628 /* X1,Y1,Z1 = Coordinates of IN1 */ 11629 /* X2,Y2,Z2 = Coordinates of IN2 */ 11630 11631 11632 /* Store IN1, IN2, and LWK in local variables and test for */ 11633 /* errors. */ 11634 11635 /* Parameter adjustments */ 11636 --lend; 11637 --lptr; 11638 --list; 11639 iwk -= 3; 11640 --z__; 11641 --y; 11642 --x; 11643 11644 /* Function Body */ 11645 n1 = *in1; 11646 n2 = *in2; 11647 iwend = *lwk; 11648 if (n1 < 1 || n2 < 1 || n1 == n2 || iwend < 0) { 11649 goto L31; 11650 } 11651 11652 /* Test for N2 as a neighbor of N1. LPL points to the last */ 11653 /* neighbor of N1. */ 11654 11655 lpl = lend[n1]; 11656 n0 = (i__1 = list[lpl], abs(i__1)); 11657 lp = lpl; 11658 L1: 11659 if (n0 == n2) { 11660 goto L30; 11661 } 11662 lp = lptr[lp]; 11663 n0 = list[lp]; 11664 if (lp != lpl) { 11665 goto L1; 11666 } 11667 11668 /* Initialize parameters. */ 11669 11670 iwl = 0; 11671 nit = 0; 11672 11673 /* Store the coordinates of N1 and N2. */ 11674 11675 L2: 11676 x1 = x[n1]; 11677 y1 = y[n1]; 11678 z1 = z__[n1]; 11679 x2 = x[n2]; 11680 y2 = y[n2]; 11681 z2 = z__[n2]; 11682 11683 /* Set NR and NL to adjacent neighbors of N1 such that */ 11684 /* NR LEFT N2->N1 and NL LEFT N1->N2, */ 11685 /* (NR Forward N1->N2 or NL Forward N1->N2), and */ 11686 /* (NR Forward N2->N1 or NL Forward N2->N1). */ 11687 11688 /* Initialization: Set N1FRST and N1LST to the first and */ 11689 /* (signed) last neighbors of N1, respectively, and */ 11690 /* initialize NL to N1FRST. */ 11691 11692 lpl = lend[n1]; 11693 n1lst = list[lpl]; 11694 lp = lptr[lpl]; 11695 n1frst = list[lp]; 11696 nl = n1frst; 11697 if (n1lst < 0) { 11698 goto L4; 11699 } 11700 11701 /* N1 is an interior node. Set NL to the first candidate */ 11702 /* for NR (NL LEFT N2->N1). */ 11703 11704 L3: 11705 if (left_(&x2, &y2, &z2, &x1, &y1, &z1, &x[nl], &y[nl], &z__[nl])) { 11706 goto L4; 11707 } 11708 lp = lptr[lp]; 11709 nl = list[lp]; 11710 if (nl != n1frst) { 11711 goto L3; 11712 } 11713 11714 /* All neighbors of N1 are strictly left of N1->N2. */ 11715 11716 goto L5; 11717 11718 /* NL = LIST(LP) LEFT N2->N1. Set NR to NL and NL to the */ 11719 /* following neighbor of N1. */ 11720 11721 L4: 11722 nr = nl; 11723 lp = lptr[lp]; 11724 nl = (i__1 = list[lp], abs(i__1)); 11725 if (left_(&x1, &y1, &z1, &x2, &y2, &z2, &x[nl], &y[nl], &z__[nl])) { 11726 11727 /* NL LEFT N1->N2 and NR LEFT N2->N1. The Forward tests */ 11728 /* are employed to avoid an error associated with */ 11729 /* collinear nodes. */ 11730 11731 dp12 = x1 * x2 + y1 * y2 + z1 * z2; 11732 dp1l = x1 * x[nl] + y1 * y[nl] + z1 * z__[nl]; 11733 dp2l = x2 * x[nl] + y2 * y[nl] + z2 * z__[nl]; 11734 dp1r = x1 * x[nr] + y1 * y[nr] + z1 * z__[nr]; 11735 dp2r = x2 * x[nr] + y2 * y[nr] + z2 * z__[nr]; 11736 if ((dp2l - dp12 * dp1l >= 0. || dp2r - dp12 * dp1r >= 0.) && (dp1l - 11737 dp12 * dp2l >= 0. || dp1r - dp12 * dp2r >= 0.)) { 11738 goto L6; 11739 } 11740 11741 /* NL-NR does not intersect N1-N2. However, there is */ 11742 /* another candidate for the first arc if NL lies on */ 11743 /* the line N1-N2. */ 11744 11745 if (! left_(&x2, &y2, &z2, &x1, &y1, &z1, &x[nl], &y[nl], &z__[nl])) { 11746 goto L5; 11747 } 11748 } 11749 11750 /* Bottom of loop. */ 11751 11752 if (nl != n1frst) { 11753 goto L4; 11754 } 11755 11756 /* Either the triangulation is invalid or N1-N2 lies on the */ 11757 /* convex hull boundary and an edge NR->NL (opposite N1 and */ 11758 /* intersecting N1-N2) was not found due to floating point */ 11759 /* error. Try interchanging N1 and N2 -- NIT > 0 iff this */ 11760 /* has already been done. */ 11761 11762 L5: 11763 if (nit > 0) { 11764 goto L33; 11765 } 11766 nit = 1; 11767 n1 = n2; 11768 n2 = *in1; 11769 goto L2; 11770 11771 /* Store the ordered sequence of intersecting edges NL->NR in */ 11772 /* IWK(1,IWL)->IWK(2,IWL). */ 11773 11774 L6: 11775 ++iwl; 11776 if (iwl > iwend) { 11777 goto L32; 11778 } 11779 iwk[(iwl << 1) + 1] = nl; 11780 iwk[(iwl << 1) + 2] = nr; 11781 11782 /* Set NEXT to the neighbor of NL which follows NR. */ 11783 11784 lpl = lend[nl]; 11785 lp = lptr[lpl]; 11786 11787 /* Find NR as a neighbor of NL. The search begins with */ 11788 /* the first neighbor. */ 11789 11790 L7: 11791 if (list[lp] == nr) { 11792 goto L8; 11793 } 11794 lp = lptr[lp]; 11795 if (lp != lpl) { 11796 goto L7; 11797 } 11798 11799 /* NR must be the last neighbor, and NL->NR cannot be a */ 11800 /* boundary edge. */ 11801 11802 if (list[lp] != nr) { 11803 goto L33; 11804 } 11805 11806 /* Set NEXT to the neighbor following NR, and test for */ 11807 /* termination of the store loop. */ 11808 11809 L8: 11810 lp = lptr[lp]; 11811 next = (i__1 = list[lp], abs(i__1)); 11812 if (next == n2) { 11813 goto L9; 11814 } 11815 11816 /* Set NL or NR to NEXT. */ 11817 11818 if (left_(&x1, &y1, &z1, &x2, &y2, &z2, &x[next], &y[next], &z__[next])) { 11819 nl = next; 11820 } else { 11821 nr = next; 11822 } 11823 goto L6; 11824 11825 /* IWL is the number of arcs which intersect N1-N2. */ 11826 /* Store LWK. */ 11827 11828 L9: 11829 *lwk = iwl; 11830 iwend = iwl; 11831 11832 /* Initialize for edge swapping loop -- all possible swaps */ 11833 /* are applied (even if the new arc again intersects */ 11834 /* N1-N2), arcs to the left of N1->N2 are stored in the */ 11835 /* left portion of IWK, and arcs to the right are stored in */ 11836 /* the right portion. IWF and IWL index the first and last */ 11837 /* intersecting arcs. */ 11838 11839 iwf = 1; 11840 11841 /* Top of loop -- set N0 to N1 and NL->NR to the first edge. */ 11842 /* IWC points to the arc currently being processed. LFT */ 11843 /* .LE. 0 iff N0 LEFT N1->N2. */ 11844 11845 L10: 11846 lft = 0; 11847 n0 = n1; 11848 x0 = x1; 11849 y0 = y1; 11850 z0 = z1; 11851 nl = iwk[(iwf << 1) + 1]; 11852 nr = iwk[(iwf << 1) + 2]; 11853 iwc = iwf; 11854 11855 /* Set NEXT to the node opposite NL->NR unless IWC is the */ 11856 /* last arc. */ 11857 11858 L11: 11859 if (iwc == iwl) { 11860 goto L21; 11861 } 11862 iwcp1 = iwc + 1; 11863 next = iwk[(iwcp1 << 1) + 1]; 11864 if (next != nl) { 11865 goto L16; 11866 } 11867 next = iwk[(iwcp1 << 1) + 2]; 11868 11869 /* NEXT RIGHT N1->N2 and IWC .LT. IWL. Test for a possible */ 11870 /* swap. */ 11871 11872 if (! left_(&x0, &y0, &z0, &x[nr], &y[nr], &z__[nr], &x[next], &y[next], & 11873 z__[next])) { 11874 goto L14; 11875 } 11876 if (lft >= 0) { 11877 goto L12; 11878 } 11879 if (! left_(&x[nl], &y[nl], &z__[nl], &x0, &y0, &z0, &x[next], &y[next], & 11880 z__[next])) { 11881 goto L14; 11882 } 11883 11884 /* Replace NL->NR with N0->NEXT. */ 11885 11886 swap_(&next, &n0, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21); 11887 iwk[(iwc << 1) + 1] = n0; 11888 iwk[(iwc << 1) + 2] = next; 11889 goto L15; 11890 11891 /* Swap NL-NR for N0-NEXT, shift columns IWC+1,...,IWL to */ 11892 /* the left, and store N0-NEXT in the right portion of */ 11893 /* IWK. */ 11894 11895 L12: 11896 swap_(&next, &n0, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21); 11897 i__1 = iwl; 11898 for (i__ = iwcp1; i__ <= i__1; ++i__) { 11899 iwk[(i__ - (1<<1)) + 1] = iwk[(i__ << 1) + 1]; 11900 iwk[(i__ - (1<<1)) + 2] = iwk[(i__ << 1) + 2]; 11901 /* L13: */ 11902 } 11903 iwk[(iwl << 1) + 1] = n0; 11904 iwk[(iwl << 1) + 2] = next; 11905 --iwl; 11906 nr = next; 11907 goto L11; 11908 11909 /* A swap is not possible. Set N0 to NR. */ 11910 11911 L14: 11912 n0 = nr; 11913 x0 = x[n0]; 11914 y0 = y[n0]; 11915 z0 = z__[n0]; 11916 lft = 1; 11917 11918 /* Advance to the next arc. */ 11919 11920 L15: 11921 nr = next; 11922 ++iwc; 11923 goto L11; 11924 11925 /* NEXT LEFT N1->N2, NEXT .NE. N2, and IWC .LT. IWL. */ 11926 /* Test for a possible swap. */ 11927 11928 L16: 11929 if (! left_(&x[nl], &y[nl], &z__[nl], &x0, &y0, &z0, &x[next], &y[next], & 11930 z__[next])) { 11931 goto L19; 11932 } 11933 if (lft <= 0) { 11934 goto L17; 11935 } 11936 if (! left_(&x0, &y0, &z0, &x[nr], &y[nr], &z__[nr], &x[next], &y[next], & 11937 z__[next])) { 11938 goto L19; 11939 } 11940 11941 /* Replace NL->NR with NEXT->N0. */ 11942 11943 swap_(&next, &n0, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21); 11944 iwk[(iwc << 1) + 1] = next; 11945 iwk[(iwc << 1) + 2] = n0; 11946 goto L20; 11947 11948 /* Swap NL-NR for N0-NEXT, shift columns IWF,...,IWC-1 to */ 11949 /* the right, and store N0-NEXT in the left portion of */ 11950 /* IWK. */ 11951 11952 L17: 11953 swap_(&next, &n0, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21); 11954 i__1 = iwf; 11955 for (i__ = iwc - 1; i__ >= i__1; --i__) { 11956 iwk[(i__ + (1<<1)) + 1] = iwk[(i__ << 1) + 1]; 11957 iwk[(i__ + (1<<1)) + 2] = iwk[(i__ << 1) + 2]; 11958 /* L18: */ 11959 } 11960 iwk[(iwf << 1) + 1] = n0; 11961 iwk[(iwf << 1) + 2] = next; 11962 ++iwf; 11963 goto L20; 11964 11965 /* A swap is not possible. Set N0 to NL. */ 11966 11967 L19: 11968 n0 = nl; 11969 x0 = x[n0]; 11970 y0 = y[n0]; 11971 z0 = z__[n0]; 11972 lft = -1; 11973 11974 /* Advance to the next arc. */ 11975 11976 L20: 11977 nl = next; 11978 ++iwc; 11979 goto L11; 11980 11981 /* N2 is opposite NL->NR (IWC = IWL). */ 11982 11983 L21: 11984 if (n0 == n1) { 11985 goto L24; 11986 } 11987 if (lft < 0) { 11988 goto L22; 11989 } 11990 11991 /* N0 RIGHT N1->N2. Test for a possible swap. */ 11992 11993 if (! left_(&x0, &y0, &z0, &x[nr], &y[nr], &z__[nr], &x2, &y2, &z2)) { 11994 goto L10; 11995 } 11996 11997 /* Swap NL-NR for N0-N2 and store N0-N2 in the right */ 11998 /* portion of IWK. */ 11999 12000 swap_(&n2, &n0, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21); 12001 iwk[(iwl << 1) + 1] = n0; 12002 iwk[(iwl << 1) + 2] = n2; 12003 --iwl; 12004 goto L10; 12005 12006 /* N0 LEFT N1->N2. Test for a possible swap. */ 12007 12008 L22: 12009 if (! left_(&x[nl], &y[nl], &z__[nl], &x0, &y0, &z0, &x2, &y2, &z2)) { 12010 goto L10; 12011 } 12012 12013 /* Swap NL-NR for N0-N2, shift columns IWF,...,IWL-1 to the */ 12014 /* right, and store N0-N2 in the left portion of IWK. */ 12015 12016 swap_(&n2, &n0, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21); 12017 i__ = iwl; 12018 L23: 12019 iwk[(i__ << 1) + 1] = iwk[(i__ - (1<<1)) + 1]; 12020 iwk[(i__ << 1) + 2] = iwk[(i__ - (1<<1)) + 2]; 12021 --i__; 12022 if (i__ > iwf) { 12023 goto L23; 12024 } 12025 iwk[(iwf << 1) + 1] = n0; 12026 iwk[(iwf << 1) + 2] = n2; 12027 ++iwf; 12028 goto L10; 12029 12030 /* IWF = IWC = IWL. Swap out the last arc for N1-N2 and */ 12031 /* store zeros in IWK. */ 12032 12033 L24: 12034 swap_(&n2, &n1, &nl, &nr, &list[1], &lptr[1], &lend[1], &lp21); 12035 iwk[(iwc << 1) + 1] = 0; 12036 iwk[(iwc << 1) + 2] = 0; 12037 12038 /* Optimization procedure -- */ 12039 12040 *ier = 0; 12041 if (iwc > 1) { 12042 12043 /* Optimize the set of new arcs to the left of IN1->IN2. */ 12044 12045 nit = iwc - (1<<2); 12046 i__1 = iwc - 1; 12047 optim_(&x[1], &y[1], &z__[1], &i__1, &list[1], &lptr[1], &lend[1], & 12048 nit, &iwk[3], &ierr); 12049 if (ierr != 0 && ierr != 1) { 12050 goto L34; 12051 } 12052 if (ierr == 1) { 12053 *ier = 5; 12054 } 12055 } 12056 if (iwc < iwend) { 12057 12058 /* Optimize the set of new arcs to the right of IN1->IN2. */ 12059 12060 nit = iwend - (iwc<<2); 12061 i__1 = iwend - iwc; 12062 optim_(&x[1], &y[1], &z__[1], &i__1, &list[1], &lptr[1], &lend[1], & 12063 nit, &iwk[(iwc + (1<<1)) + 1], &ierr); 12064 if (ierr != 0 && ierr != 1) { 12065 goto L34; 12066 } 12067 if (ierr == 1) { 12068 goto L35; 12069 } 12070 } 12071 if (*ier == 5) { 12072 goto L35; 12073 } 12074 12075 /* Successful termination (IER = 0). */ 12076 12077 return 0; 12078 12079 /* IN1 and IN2 were adjacent on input. */ 12080 12081 L30: 12082 *ier = 0; 12083 return 0; 12084 12085 /* Invalid input parameter. */ 12086 12087 L31: 12088 *ier = 1; 12089 return 0; 12090 12091 /* Insufficient space reserved for IWK. */ 12092 12093 L32: 12094 *ier = 2; 12095 return 0; 12096 12097 /* Invalid triangulation data structure or collinear nodes */ 12098 /* on convex hull boundary. */ 12099 12100 L33: 12101 *ier = 3; 12102 /* WRITE (*,130) IN1, IN2 */ 12103 /* 130 FORMAT (//5X,'*** Error in EDGE: Invalid triangula', */ 12104 /* . 'tion or null triangles on boundary'/ */ 12105 /* . 9X,'IN1 =',I4,', IN2=',I4/) */ 12106 return 0; 12107 12108 /* Error flag (other than 1) returned by OPTIM. */ 12109 12110 L34: 12111 *ier = 4; 12112 /* WRITE (*,140) NIT, IERR */ 12113 /* 140 FORMAT (//5X,'*** Error in OPTIM (called from EDGE):', */ 12114 /* . ' NIT = ',I4,', IER = ',I1,' ***'/) */ 12115 return 0; 12116 12117 /* Error flag 1 returned by OPTIM. */ 12118 12119 L35: 12120 *ier = 5; 12121 return 0; 12122 } /* edge_ */
Definition at line 20117 of file util_sparx.cpp.
References EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), nx, ny, and EMAN::EMData::set_value_at().
Referenced by EMAN::Util::get_biggest_cluster().
20118 { 20119 int offs[][3] = { {-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1} }; 20120 int noff = 6; 20121 20122 int nx = visited->get_xsize(); 20123 int ny = visited->get_ysize(); 20124 int nz = visited->get_zsize(); 20125 20126 vector< point3d_t > pts; 20127 pts.push_back( point3d_t(ix, iy, iz) ); 20128 visited->set_value_at( ix, iy, iz, (float)grpid ); 20129 20130 int start = 0; 20131 int end = pts.size(); 20132 20133 while( end > start ) { 20134 for(int i=start; i < end; ++i ) { 20135 int ix = pts[i].x; 20136 int iy = pts[i].y; 20137 int iz = pts[i].z; 20138 20139 for( int j=0; j < noff; ++j ) { 20140 int jx = ix + offs[j][0]; 20141 int jy = iy + offs[j][1]; 20142 int jz = iz + offs[j][2]; 20143 20144 if( jx < 0 || jx >= nx ) continue; 20145 if( jy < 0 || jy >= ny ) continue; 20146 if( jz < 0 || jz >= nz ) continue; 20147 20148 20149 if( (*mg)(jx, jy, jz)>0 && (*visited)(jx, jy, jz)==0.0 ) { 20150 pts.push_back( point3d_t(jx, jy, jz) ); 20151 visited->set_value_at( jx, jy, jz, (float)grpid ); 20152 } 20153 20154 } 20155 } 20156 20157 start = end; 20158 end = pts.size(); 20159 } 20160 return pts.size(); 20161 }
int getnp_ | ( | double * | x, | |
double * | y, | |||
double * | z__, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | l, | |||
int * | npts, | |||
double * | df, | |||
int * | ier | |||
) |
Definition at line 12124 of file util_sparx.cpp.
References abs.
12127 { 12128 /* System generated locals */ 12129 int i__1, i__2; 12130 12131 /* Local variables */ 12132 static int i__, n1; 12133 static double x1, y1, z1; 12134 static int nb, ni, lp, np, lm1; 12135 static double dnb, dnp; 12136 static int lpl; 12137 12138 12139 /* *********************************************************** */ 12140 12141 /* From STRIPACK */ 12142 /* Robert J. Renka */ 12143 /* Dept. of Computer Science */ 12144 /* Univ. of North Texas */ 12145 /* renka@cs.unt.edu */ 12146 /* 07/28/98 */ 12147 12148 /* Given a Delaunay triangulation of N nodes on the unit */ 12149 /* sphere and an array NPTS containing the indexes of L-1 */ 12150 /* nodes ordered by angular distance from NPTS(1), this sub- */ 12151 /* routine sets NPTS(L) to the index of the next node in the */ 12152 /* sequence -- the node, other than NPTS(1),...,NPTS(L-1), */ 12153 /* that is closest to NPTS(1). Thus, the ordered sequence */ 12154 /* of K closest nodes to N1 (including N1) may be determined */ 12155 /* by K-1 calls to GETNP with NPTS(1) = N1 and L = 2,3,...,K */ 12156 /* for K .GE. 2. */ 12157 12158 /* The algorithm uses the property of a Delaunay triangula- */ 12159 /* tion that the K-th closest node to N1 is a neighbor of one */ 12160 /* of the K-1 closest nodes to N1. */ 12161 12162 12163 /* On input: */ 12164 12165 /* X,Y,Z = Arrays of length N containing the Cartesian */ 12166 /* coordinates of the nodes. */ 12167 12168 /* LIST,LPTR,LEND = Triangulation data structure. Re- */ 12169 /* fer to Subroutine TRMESH. */ 12170 12171 /* L = Number of nodes in the sequence on output. 2 */ 12172 /* .LE. L .LE. N. */ 12173 12174 /* The above parameters are not altered by this routine. */ 12175 12176 /* NPTS = Array of length .GE. L containing the indexes */ 12177 /* of the L-1 closest nodes to NPTS(1) in the */ 12178 /* first L-1 locations. */ 12179 12180 /* On output: */ 12181 12182 /* NPTS = Array updated with the index of the L-th */ 12183 /* closest node to NPTS(1) in position L unless */ 12184 /* IER = 1. */ 12185 12186 /* DF = Value of an increasing function (negative cos- */ 12187 /* ine) of the angular distance between NPTS(1) */ 12188 /* and NPTS(L) unless IER = 1. */ 12189 12190 /* IER = Error indicator: */ 12191 /* IER = 0 if no errors were encountered. */ 12192 /* IER = 1 if L < 2. */ 12193 12194 /* Modules required by GETNP: None */ 12195 12196 /* Intrinsic function called by GETNP: ABS */ 12197 12198 /* *********************************************************** */ 12199 12200 12201 /* Local parameters: */ 12202 12203 /* DNB,DNP = Negative cosines of the angular distances from */ 12204 /* N1 to NB and to NP, respectively */ 12205 /* I = NPTS index and DO-loop index */ 12206 /* LM1 = L-1 */ 12207 /* LP = LIST pointer of a neighbor of NI */ 12208 /* LPL = Pointer to the last neighbor of NI */ 12209 /* N1 = NPTS(1) */ 12210 /* NB = Neighbor of NI and candidate for NP */ 12211 /* NI = NPTS(I) */ 12212 /* NP = Candidate for NPTS(L) */ 12213 /* X1,Y1,Z1 = Coordinates of N1 */ 12214 12215 /* Parameter adjustments */ 12216 --x; 12217 --y; 12218 --z__; 12219 --list; 12220 --lptr; 12221 --lend; 12222 --npts; 12223 12224 /* Function Body */ 12225 lm1 = *l - 1; 12226 if (lm1 < 1) { 12227 goto L6; 12228 } 12229 *ier = 0; 12230 12231 /* Store N1 = NPTS(1) and mark the elements of NPTS. */ 12232 12233 n1 = npts[1]; 12234 x1 = x[n1]; 12235 y1 = y[n1]; 12236 z1 = z__[n1]; 12237 i__1 = lm1; 12238 for (i__ = 1; i__ <= i__1; ++i__) { 12239 ni = npts[i__]; 12240 lend[ni] = -lend[ni]; 12241 /* L1: */ 12242 } 12243 12244 /* Candidates for NP = NPTS(L) are the unmarked neighbors */ 12245 /* of nodes in NPTS. DNP is initially greater than -cos(PI) */ 12246 /* (the maximum distance). */ 12247 12248 dnp = 2.; 12249 12250 /* Loop on nodes NI in NPTS. */ 12251 12252 i__1 = lm1; 12253 for (i__ = 1; i__ <= i__1; ++i__) { 12254 ni = npts[i__]; 12255 lpl = -lend[ni]; 12256 lp = lpl; 12257 12258 /* Loop on neighbors NB of NI. */ 12259 12260 L2: 12261 nb = (i__2 = list[lp], abs(i__2)); 12262 if (lend[nb] < 0) { 12263 goto L3; 12264 } 12265 12266 /* NB is an unmarked neighbor of NI. Replace NP if NB is */ 12267 /* closer to N1. */ 12268 12269 dnb = -(x[nb] * x1 + y[nb] * y1 + z__[nb] * z1); 12270 if (dnb >= dnp) { 12271 goto L3; 12272 } 12273 np = nb; 12274 dnp = dnb; 12275 L3: 12276 lp = lptr[lp]; 12277 if (lp != lpl) { 12278 goto L2; 12279 } 12280 /* L4: */ 12281 } 12282 npts[*l] = np; 12283 *df = dnp; 12284 12285 /* Unmark the elements of NPTS. */ 12286 12287 i__1 = lm1; 12288 for (i__ = 1; i__ <= i__1; ++i__) { 12289 ni = npts[i__]; 12290 lend[ni] = -lend[ni]; 12291 /* L5: */ 12292 } 12293 return 0; 12294 12295 /* L is outside its valid range. */ 12296 12297 L6: 12298 *ier = 1; 12299 return 0; 12300 } /* getnp_ */
int i_dnnt | ( | double * | x | ) |
int insert_ | ( | int * | k, | |
int * | lp, | |||
int * | list, | |||
int * | lptr, | |||
int * | lnew | |||
) |
Definition at line 12302 of file util_sparx.cpp.
Referenced by bdyadd_(), covsph_(), and intadd_().
12304 { 12305 static int lsav; 12306 12307 12308 /* *********************************************************** */ 12309 12310 /* From STRIPACK */ 12311 /* Robert J. Renka */ 12312 /* Dept. of Computer Science */ 12313 /* Univ. of North Texas */ 12314 /* renka@cs.unt.edu */ 12315 /* 07/17/96 */ 12316 12317 /* This subroutine inserts K as a neighbor of N1 following */ 12318 /* N2, where LP is the LIST pointer of N2 as a neighbor of */ 12319 /* N1. Note that, if N2 is the last neighbor of N1, K will */ 12320 /* become the first neighbor (even if N1 is a boundary node). */ 12321 12322 /* This routine is identical to the similarly named routine */ 12323 /* in TRIPACK. */ 12324 12325 12326 /* On input: */ 12327 12328 /* K = Index of the node to be inserted. */ 12329 12330 /* LP = LIST pointer of N2 as a neighbor of N1. */ 12331 12332 /* The above parameters are not altered by this routine. */ 12333 12334 /* LIST,LPTR,LNEW = Data structure defining the trian- */ 12335 /* gulation. Refer to Subroutine */ 12336 /* TRMESH. */ 12337 12338 /* On output: */ 12339 12340 /* LIST,LPTR,LNEW = Data structure updated with the */ 12341 /* addition of node K. */ 12342 12343 /* Modules required by INSERT: None */ 12344 12345 /* *********************************************************** */ 12346 12347 12348 /* Parameter adjustments */ 12349 --lptr; 12350 --list; 12351 12352 /* Function Body */ 12353 lsav = lptr[*lp]; 12354 lptr[*lp] = *lnew; 12355 list[*lnew] = *k; 12356 lptr[*lnew] = lsav; 12357 ++(*lnew); 12358 return 0; 12359 } /* insert_ */
long int inside_ | ( | double * | p, | |
int * | lv, | |||
double * | xv, | |||
double * | yv, | |||
double * | zv, | |||
int * | nv, | |||
int * | listv, | |||
int * | ier | |||
) |
Definition at line 12361 of file util_sparx.cpp.
References b, ierr, intrsc_(), q, sqrt(), and TRUE_.
12363 { 12364 /* Initialized data */ 12365 12366 static double eps = .001; 12367 12368 /* System generated locals */ 12369 int i__1; 12370 long int ret_val = 0; 12371 12372 /* Builtin functions */ 12373 //double sqrt(double); 12374 12375 /* Local variables */ 12376 static double b[3], d__; 12377 static int k, n; 12378 static double q[3]; 12379 static int i1, i2, k0; 12380 static double v1[3], v2[3], cn[3], bp, bq; 12381 static int ni; 12382 static double pn[3], qn[3], vn[3]; 12383 static int imx; 12384 static long int lft1, lft2, even; 12385 static int ierr; 12386 static long int pinr, qinr; 12387 static double qnrm, vnrm; 12388 /* Subroutine */ int intrsc_(double *, double *, 12389 double *, double *, int *); 12390 12391 12392 /* *********************************************************** */ 12393 12394 /* From STRIPACK */ 12395 /* Robert J. Renka */ 12396 /* Dept. of Computer Science */ 12397 /* Univ. of North Texas */ 12398 /* renka@cs.unt.edu */ 12399 /* 12/27/93 */ 12400 12401 /* This function locates a point P relative to a polygonal */ 12402 /* region R on the surface of the unit sphere, returning */ 12403 /* INSIDE = TRUE if and only if P is contained in R. R is */ 12404 /* defined by a cyclically ordered sequence of vertices which */ 12405 /* form a positively-oriented simple closed curve. Adjacent */ 12406 /* vertices need not be distinct but the curve must not be */ 12407 /* self-intersecting. Also, while polygon edges are by defi- */ 12408 /* nition restricted to a single hemisphere, R is not so */ 12409 /* restricted. Its interior is the region to the left as the */ 12410 /* vertices are traversed in order. */ 12411 12412 /* The algorithm consists of selecting a point Q in R and */ 12413 /* then finding all points at which the great circle defined */ 12414 /* by P and Q intersects the boundary of R. P lies inside R */ 12415 /* if and only if there is an even number of intersection */ 12416 /* points between Q and P. Q is taken to be a point immedi- */ 12417 /* ately to the left of a directed boundary edge -- the first */ 12418 /* one that results in no consistency-check failures. */ 12419 12420 /* If P is close to the polygon boundary, the problem is */ 12421 /* ill-conditioned and the decision may be incorrect. Also, */ 12422 /* an incorrect decision may result from a poor choice of Q */ 12423 /* (if, for example, a boundary edge lies on the great cir- */ 12424 /* cle defined by P and Q). A more reliable result could be */ 12425 /* obtained by a sequence of calls to INSIDE with the ver- */ 12426 /* tices cyclically permuted before each call (to alter the */ 12427 /* choice of Q). */ 12428 12429 12430 /* On input: */ 12431 12432 /* P = Array of length 3 containing the Cartesian */ 12433 /* coordinates of the point (unit vector) to be */ 12434 /* located. */ 12435 12436 /* LV = Length of arrays XV, YV, and ZV. */ 12437 12438 /* XV,YV,ZV = Arrays of length LV containing the Carte- */ 12439 /* sian coordinates of unit vectors (points */ 12440 /* on the unit sphere). These values are */ 12441 /* not tested for validity. */ 12442 12443 /* NV = Number of vertices in the polygon. 3 .LE. NV */ 12444 /* .LE. LV. */ 12445 12446 /* LISTV = Array of length NV containing the indexes */ 12447 /* (for XV, YV, and ZV) of a cyclically-ordered */ 12448 /* (and CCW-ordered) sequence of vertices that */ 12449 /* define R. The last vertex (indexed by */ 12450 /* LISTV(NV)) is followed by the first (indexed */ 12451 /* by LISTV(1)). LISTV entries must be in the */ 12452 /* range 1 to LV. */ 12453 12454 /* Input parameters are not altered by this function. */ 12455 12456 /* On output: */ 12457 12458 /* INSIDE = TRUE if and only if P lies inside R unless */ 12459 /* IER .NE. 0, in which case the value is not */ 12460 /* altered. */ 12461 12462 /* IER = Error indicator: */ 12463 /* IER = 0 if no errors were encountered. */ 12464 /* IER = 1 if LV or NV is outside its valid */ 12465 /* range. */ 12466 /* IER = 2 if a LISTV entry is outside its valid */ 12467 /* range. */ 12468 /* IER = 3 if the polygon boundary was found to */ 12469 /* be self-intersecting. This error will */ 12470 /* not necessarily be detected. */ 12471 /* IER = 4 if every choice of Q (one for each */ 12472 /* boundary edge) led to failure of some */ 12473 /* internal consistency check. The most */ 12474 /* likely cause of this error is invalid */ 12475 /* input: P = (0,0,0), a null or self- */ 12476 /* intersecting polygon, etc. */ 12477 12478 /* Module required by INSIDE: INTRSC */ 12479 12480 /* Intrinsic function called by INSIDE: SQRT */ 12481 12482 /* *********************************************************** */ 12483 12484 12485 /* Local parameters: */ 12486 12487 /* B = Intersection point between the boundary and */ 12488 /* the great circle defined by P and Q */ 12489 /* BP,BQ = <B,P> and <B,Q>, respectively, maximized over */ 12490 /* intersection points B that lie between P and */ 12491 /* Q (on the shorter arc) -- used to find the */ 12492 /* closest intersection points to P and Q */ 12493 /* CN = Q X P = normal to the plane of P and Q */ 12494 /* D = Dot product <B,P> or <B,Q> */ 12495 /* EPS = Parameter used to define Q as the point whose */ 12496 /* orthogonal distance to (the midpoint of) */ 12497 /* boundary edge V1->V2 is approximately EPS/ */ 12498 /* (2*Cos(A/2)), where <V1,V2> = Cos(A). */ 12499 /* EVEN = TRUE iff an even number of intersection points */ 12500 /* lie between P and Q (on the shorter arc) */ 12501 /* I1,I2 = Indexes (LISTV elements) of a pair of adjacent */ 12502 /* boundary vertices (endpoints of a boundary */ 12503 /* edge) */ 12504 /* IERR = Error flag for calls to INTRSC (not tested) */ 12505 /* IMX = Local copy of LV and maximum value of I1 and */ 12506 /* I2 */ 12507 /* K = DO-loop index and LISTV index */ 12508 /* K0 = LISTV index of the first endpoint of the */ 12509 /* boundary edge used to compute Q */ 12510 /* LFT1,LFT2 = long int variables associated with I1 and I2 in */ 12511 /* the boundary traversal: TRUE iff the vertex */ 12512 /* is strictly to the left of Q->P (<V,CN> > 0) */ 12513 /* N = Local copy of NV */ 12514 /* NI = Number of intersections (between the boundary */ 12515 /* curve and the great circle P-Q) encountered */ 12516 /* PINR = TRUE iff P is to the left of the directed */ 12517 /* boundary edge associated with the closest */ 12518 /* intersection point to P that lies between P */ 12519 /* and Q (a left-to-right intersection as */ 12520 /* viewed from Q), or there is no intersection */ 12521 /* between P and Q (on the shorter arc) */ 12522 /* PN,QN = P X CN and CN X Q, respectively: used to */ 12523 /* locate intersections B relative to arc Q->P */ 12524 /* Q = (V1 + V2 + EPS*VN/VNRM)/QNRM, where V1->V2 is */ 12525 /* the boundary edge indexed by LISTV(K0) -> */ 12526 /* LISTV(K0+1) */ 12527 /* QINR = TRUE iff Q is to the left of the directed */ 12528 /* boundary edge associated with the closest */ 12529 /* intersection point to Q that lies between P */ 12530 /* and Q (a right-to-left intersection as */ 12531 /* viewed from Q), or there is no intersection */ 12532 /* between P and Q (on the shorter arc) */ 12533 /* QNRM = Euclidean norm of V1+V2+EPS*VN/VNRM used to */ 12534 /* compute (normalize) Q */ 12535 /* V1,V2 = Vertices indexed by I1 and I2 in the boundary */ 12536 /* traversal */ 12537 /* VN = V1 X V2, where V1->V2 is the boundary edge */ 12538 /* indexed by LISTV(K0) -> LISTV(K0+1) */ 12539 /* VNRM = Euclidean norm of VN */ 12540 12541 /* Parameter adjustments */ 12542 --p; 12543 --zv; 12544 --yv; 12545 --xv; 12546 --listv; 12547 12548 /* Function Body */ 12549 12550 /* Store local parameters, test for error 1, and initialize */ 12551 /* K0. */ 12552 12553 imx = *lv; 12554 n = *nv; 12555 if (n < 3 || n > imx) { 12556 goto L11; 12557 } 12558 k0 = 0; 12559 i1 = listv[1]; 12560 if (i1 < 1 || i1 > imx) { 12561 goto L12; 12562 } 12563 12564 /* Increment K0 and set Q to a point immediately to the left */ 12565 /* of the midpoint of edge V1->V2 = LISTV(K0)->LISTV(K0+1): */ 12566 /* Q = (V1 + V2 + EPS*VN/VNRM)/QNRM, where VN = V1 X V2. */ 12567 12568 L1: 12569 ++k0; 12570 if (k0 > n) { 12571 goto L14; 12572 } 12573 i1 = listv[k0]; 12574 if (k0 < n) { 12575 i2 = listv[k0 + 1]; 12576 } else { 12577 i2 = listv[1]; 12578 } 12579 if (i2 < 1 || i2 > imx) { 12580 goto L12; 12581 } 12582 vn[0] = yv[i1] * zv[i2] - zv[i1] * yv[i2]; 12583 vn[1] = zv[i1] * xv[i2] - xv[i1] * zv[i2]; 12584 vn[2] = xv[i1] * yv[i2] - yv[i1] * xv[i2]; 12585 vnrm = sqrt(vn[0] * vn[0] + vn[1] * vn[1] + vn[2] * vn[2]); 12586 if (vnrm == 0.) { 12587 goto L1; 12588 } 12589 q[0] = xv[i1] + xv[i2] + eps * vn[0] / vnrm; 12590 q[1] = yv[i1] + yv[i2] + eps * vn[1] / vnrm; 12591 q[2] = zv[i1] + zv[i2] + eps * vn[2] / vnrm; 12592 qnrm = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2]); 12593 q[0] /= qnrm; 12594 q[1] /= qnrm; 12595 q[2] /= qnrm; 12596 12597 /* Compute CN = Q X P, PN = P X CN, and QN = CN X Q. */ 12598 12599 cn[0] = q[1] * p[3] - q[2] * p[2]; 12600 cn[1] = q[2] * p[1] - q[0] * p[3]; 12601 cn[2] = q[0] * p[2] - q[1] * p[1]; 12602 if (cn[0] == 0. && cn[1] == 0. && cn[2] == 0.) { 12603 goto L1; 12604 } 12605 pn[0] = p[2] * cn[2] - p[3] * cn[1]; 12606 pn[1] = p[3] * cn[0] - p[1] * cn[2]; 12607 pn[2] = p[1] * cn[1] - p[2] * cn[0]; 12608 qn[0] = cn[1] * q[2] - cn[2] * q[1]; 12609 qn[1] = cn[2] * q[0] - cn[0] * q[2]; 12610 qn[2] = cn[0] * q[1] - cn[1] * q[0]; 12611 12612 /* Initialize parameters for the boundary traversal. */ 12613 12614 ni = 0; 12615 even = TRUE_; 12616 bp = -2.; 12617 bq = -2.; 12618 pinr = TRUE_; 12619 qinr = TRUE_; 12620 i2 = listv[n]; 12621 if (i2 < 1 || i2 > imx) { 12622 goto L12; 12623 } 12624 lft2 = cn[0] * xv[i2] + cn[1] * yv[i2] + cn[2] * zv[i2] > 0.; 12625 12626 /* Loop on boundary arcs I1->I2. */ 12627 12628 i__1 = n; 12629 for (k = 1; k <= i__1; ++k) { 12630 i1 = i2; 12631 lft1 = lft2; 12632 i2 = listv[k]; 12633 if (i2 < 1 || i2 > imx) { 12634 goto L12; 12635 } 12636 lft2 = cn[0] * xv[i2] + cn[1] * yv[i2] + cn[2] * zv[i2] > 0.; 12637 if (lft1 == lft2) { 12638 goto L2; 12639 } 12640 12641 /* I1 and I2 are on opposite sides of Q->P. Compute the */ 12642 /* point of intersection B. */ 12643 12644 ++ni; 12645 v1[0] = xv[i1]; 12646 v1[1] = yv[i1]; 12647 v1[2] = zv[i1]; 12648 v2[0] = xv[i2]; 12649 v2[1] = yv[i2]; 12650 v2[2] = zv[i2]; 12651 intrsc_(v1, v2, cn, b, &ierr); 12652 12653 /* B is between Q and P (on the shorter arc) iff */ 12654 /* B Forward Q->P and B Forward P->Q iff */ 12655 /* <B,QN> > 0 and <B,PN> > 0. */ 12656 12657 if (b[0] * qn[0] + b[1] * qn[1] + b[2] * qn[2] > 0. && b[0] * pn[0] + 12658 b[1] * pn[1] + b[2] * pn[2] > 0.) { 12659 12660 /* Update EVEN, BQ, QINR, BP, and PINR. */ 12661 12662 even = ! even; 12663 d__ = b[0] * q[0] + b[1] * q[1] + b[2] * q[2]; 12664 if (d__ > bq) { 12665 bq = d__; 12666 qinr = lft2; 12667 } 12668 d__ = b[0] * p[1] + b[1] * p[2] + b[2] * p[3]; 12669 if (d__ > bp) { 12670 bp = d__; 12671 pinr = lft1; 12672 } 12673 } 12674 L2: 12675 ; 12676 } 12677 12678 /* Test for consistency: NI must be even and QINR must be */ 12679 /* TRUE. */ 12680 12681 if (ni != ni / 2 << 1 || ! qinr) { 12682 goto L1; 12683 } 12684 12685 /* Test for error 3: different values of PINR and EVEN. */ 12686 12687 if (pinr != even) { 12688 goto L13; 12689 } 12690 12691 /* No error encountered. */ 12692 12693 *ier = 0; 12694 ret_val = even; 12695 return ret_val; 12696 12697 /* LV or NV is outside its valid range. */ 12698 12699 L11: 12700 *ier = 1; 12701 return ret_val; 12702 12703 /* A LISTV entry is outside its valid range. */ 12704 12705 L12: 12706 *ier = 2; 12707 return ret_val; 12708 12709 /* The polygon boundary is self-intersecting. */ 12710 12711 L13: 12712 *ier = 3; 12713 return ret_val; 12714 12715 /* Consistency tests failed for all values of Q. */ 12716 12717 L14: 12718 *ier = 4; 12719 return ret_val; 12720 } /* inside_ */
int intadd_ | ( | int * | kk, | |
int * | i1, | |||
int * | i2, | |||
int * | i3, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | lnew | |||
) |
Definition at line 12722 of file util_sparx.cpp.
References insert_(), and lstptr_().
Referenced by addnod_().
12724 { 12725 static int k, n1, n2, n3, lp; 12726 /* Subroutine */ int insert_(int *, int *, int *, 12727 int *, int *); 12728 int lstptr_(int *, int *, int *, int *); 12729 12730 12731 /* *********************************************************** */ 12732 12733 /* From STRIPACK */ 12734 /* Robert J. Renka */ 12735 /* Dept. of Computer Science */ 12736 /* Univ. of North Texas */ 12737 /* renka@cs.unt.edu */ 12738 /* 07/17/96 */ 12739 12740 /* This subroutine adds an interior node to a triangulation */ 12741 /* of a set of points on the unit sphere. The data structure */ 12742 /* is updated with the insertion of node KK into the triangle */ 12743 /* whose vertices are I1, I2, and I3. No optimization of the */ 12744 /* triangulation is performed. */ 12745 12746 /* This routine is identical to the similarly named routine */ 12747 /* in TRIPACK. */ 12748 12749 12750 /* On input: */ 12751 12752 /* KK = Index of the node to be inserted. KK .GE. 1 */ 12753 /* and KK must not be equal to I1, I2, or I3. */ 12754 12755 /* I1,I2,I3 = Indexes of the counterclockwise-ordered */ 12756 /* sequence of vertices of a triangle which */ 12757 /* contains node KK. */ 12758 12759 /* The above parameters are not altered by this routine. */ 12760 12761 /* LIST,LPTR,LEND,LNEW = Data structure defining the */ 12762 /* triangulation. Refer to Sub- */ 12763 /* routine TRMESH. Triangle */ 12764 /* (I1,I2,I3) must be included */ 12765 /* in the triangulation. */ 12766 12767 /* On output: */ 12768 12769 /* LIST,LPTR,LEND,LNEW = Data structure updated with */ 12770 /* the addition of node KK. KK */ 12771 /* will be connected to nodes I1, */ 12772 /* I2, and I3. */ 12773 12774 /* Modules required by INTADD: INSERT, LSTPTR */ 12775 12776 /* *********************************************************** */ 12777 12778 12779 /* Local parameters: */ 12780 12781 /* K = Local copy of KK */ 12782 /* LP = LIST pointer */ 12783 /* N1,N2,N3 = Local copies of I1, I2, and I3 */ 12784 12785 /* Parameter adjustments */ 12786 --lend; 12787 --lptr; 12788 --list; 12789 12790 /* Function Body */ 12791 k = *kk; 12792 12793 /* Initialization. */ 12794 12795 n1 = *i1; 12796 n2 = *i2; 12797 n3 = *i3; 12798 12799 /* Add K as a neighbor of I1, I2, and I3. */ 12800 12801 lp = lstptr_(&lend[n1], &n2, &list[1], &lptr[1]); 12802 insert_(&k, &lp, &list[1], &lptr[1], lnew); 12803 lp = lstptr_(&lend[n2], &n3, &list[1], &lptr[1]); 12804 insert_(&k, &lp, &list[1], &lptr[1], lnew); 12805 lp = lstptr_(&lend[n3], &n1, &list[1], &lptr[1]); 12806 insert_(&k, &lp, &list[1], &lptr[1], lnew); 12807 12808 /* Add I1, I2, and I3 as neighbors of K. */ 12809 12810 list[*lnew] = n1; 12811 list[*lnew + 1] = n2; 12812 list[*lnew + 2] = n3; 12813 lptr[*lnew] = *lnew + 1; 12814 lptr[*lnew + 1] = *lnew + 2; 12815 lptr[*lnew + 2] = *lnew; 12816 lend[k] = *lnew + 2; 12817 *lnew += 3; 12818 return 0; 12819 } /* intadd_ */
int intrsc_ | ( | double * | p1, | |
double * | p2, | |||
double * | cn, | |||
double * | p, | |||
int * | ier | |||
) |
Definition at line 12821 of file util_sparx.cpp.
Referenced by inside_().
12823 { 12824 /* Builtin functions */ 12825 //double sqrt(double); 12826 12827 /* Local variables */ 12828 static int i__; 12829 static double t, d1, d2, pp[3], ppn; 12830 12831 12832 /* *********************************************************** */ 12833 12834 /* From STRIPACK */ 12835 /* Robert J. Renka */ 12836 /* Dept. of Computer Science */ 12837 /* Univ. of North Texas */ 12838 /* renka@cs.unt.edu */ 12839 /* 07/19/90 */ 12840 12841 /* Given a great circle C and points P1 and P2 defining an */ 12842 /* arc A on the surface of the unit sphere, where A is the */ 12843 /* shorter of the two portions of the great circle C12 assoc- */ 12844 /* iated with P1 and P2, this subroutine returns the point */ 12845 /* of intersection P between C and C12 that is closer to A. */ 12846 /* Thus, if P1 and P2 lie in opposite hemispheres defined by */ 12847 /* C, P is the point of intersection of C with A. */ 12848 12849 12850 /* On input: */ 12851 12852 /* P1,P2 = Arrays of length 3 containing the Cartesian */ 12853 /* coordinates of unit vectors. */ 12854 12855 /* CN = Array of length 3 containing the Cartesian */ 12856 /* coordinates of a nonzero vector which defines C */ 12857 /* as the intersection of the plane whose normal */ 12858 /* is CN with the unit sphere. Thus, if C is to */ 12859 /* be the great circle defined by P and Q, CN */ 12860 /* should be P X Q. */ 12861 12862 /* The above parameters are not altered by this routine. */ 12863 12864 /* P = Array of length 3. */ 12865 12866 /* On output: */ 12867 12868 /* P = Point of intersection defined above unless IER */ 12869 /* .NE. 0, in which case P is not altered. */ 12870 12871 /* IER = Error indicator. */ 12872 /* IER = 0 if no errors were encountered. */ 12873 /* IER = 1 if <CN,P1> = <CN,P2>. This occurs */ 12874 /* iff P1 = P2 or CN = 0 or there are */ 12875 /* two intersection points at the same */ 12876 /* distance from A. */ 12877 /* IER = 2 if P2 = -P1 and the definition of A is */ 12878 /* therefore ambiguous. */ 12879 12880 /* Modules required by INTRSC: None */ 12881 12882 /* Intrinsic function called by INTRSC: SQRT */ 12883 12884 /* *********************************************************** */ 12885 12886 12887 /* Local parameters: */ 12888 12889 /* D1 = <CN,P1> */ 12890 /* D2 = <CN,P2> */ 12891 /* I = DO-loop index */ 12892 /* PP = P1 + T*(P2-P1) = Parametric representation of the */ 12893 /* line defined by P1 and P2 */ 12894 /* PPN = Norm of PP */ 12895 /* T = D1/(D1-D2) = Parameter value chosen so that PP lies */ 12896 /* in the plane of C */ 12897 12898 /* Parameter adjustments */ 12899 --p; 12900 --cn; 12901 --p2; 12902 --p1; 12903 12904 /* Function Body */ 12905 d1 = cn[1] * p1[1] + cn[2] * p1[2] + cn[3] * p1[3]; 12906 d2 = cn[1] * p2[1] + cn[2] * p2[2] + cn[3] * p2[3]; 12907 12908 if (d1 == d2) { 12909 *ier = 1; 12910 return 0; 12911 } 12912 12913 /* Solve for T such that <PP,CN> = 0 and compute PP and PPN. */ 12914 12915 t = d1 / (d1 - d2); 12916 ppn = 0.; 12917 for (i__ = 1; i__ <= 3; ++i__) { 12918 pp[i__ - 1] = p1[i__] + t * (p2[i__] - p1[i__]); 12919 ppn += pp[i__ - 1] * pp[i__ - 1]; 12920 /* L1: */ 12921 } 12922 12923 /* PPN = 0 iff PP = 0 iff P2 = -P1 (and T = .5). */ 12924 12925 if (ppn == 0.) { 12926 *ier = 2; 12927 return 0; 12928 } 12929 ppn = sqrt(ppn); 12930 12931 /* Compute P = PP/PPN. */ 12932 12933 for (i__ = 1; i__ <= 3; ++i__) { 12934 p[i__] = pp[i__ - 1] / ppn; 12935 /* L2: */ 12936 } 12937 *ier = 0; 12938 return 0; 12939 } /* intrsc_ */
bool jiafunc | ( | int | i, | |
int | j | |||
) |
Definition at line 21521 of file util_sparx.cpp.
Referenced by EMAN::Util::branch_factor_0(), EMAN::Util::branch_factor_2(), EMAN::Util::branch_factor_3(), and EMAN::Util::branch_factor_4().
21521 { 21522 return (costlist_global[j] < costlist_global[i]) ; 21523 21524 }
int jrand_ | ( | int * | n, | |
int * | ix, | |||
int * | iy, | |||
int * | iz | |||
) |
Definition at line 12941 of file util_sparx.cpp.
Referenced by trfind_().
12942 { 12943 /* System generated locals */ 12944 int ret_val; 12945 12946 /* Local variables */ 12947 static float u, x; 12948 12949 12950 /* *********************************************************** */ 12951 12952 /* From STRIPACK */ 12953 /* Robert J. Renka */ 12954 /* Dept. of Computer Science */ 12955 /* Univ. of North Texas */ 12956 /* renka@cs.unt.edu */ 12957 /* 07/28/98 */ 12958 12959 /* This function returns a uniformly distributed pseudo- */ 12960 /* random int in the range 1 to N. */ 12961 12962 12963 /* On input: */ 12964 12965 /* N = Maximum value to be returned. */ 12966 12967 /* N is not altered by this function. */ 12968 12969 /* IX,IY,IZ = int seeds initialized to values in */ 12970 /* the range 1 to 30,000 before the first */ 12971 /* call to JRAND, and not altered between */ 12972 /* subsequent calls (unless a sequence of */ 12973 /* random numbers is to be repeated by */ 12974 /* reinitializing the seeds). */ 12975 12976 /* On output: */ 12977 12978 /* IX,IY,IZ = Updated int seeds. */ 12979 12980 /* JRAND = Random int in the range 1 to N. */ 12981 12982 /* Reference: B. A. Wichmann and I. D. Hill, "An Efficient */ 12983 /* and Portable Pseudo-random Number Generator", */ 12984 /* Applied Statistics, Vol. 31, No. 2, 1982, */ 12985 /* pp. 188-190. */ 12986 12987 /* Modules required by JRAND: None */ 12988 12989 /* Intrinsic functions called by JRAND: INT, MOD, float */ 12990 12991 /* *********************************************************** */ 12992 12993 12994 /* Local parameters: */ 12995 12996 /* U = Pseudo-random number uniformly distributed in the */ 12997 /* interval (0,1). */ 12998 /* X = Pseudo-random number in the range 0 to 3 whose frac- */ 12999 /* tional part is U. */ 13000 13001 *ix = *ix * 171 % 30269; 13002 *iy = *iy * 172 % 30307; 13003 *iz = *iz * 170 % 30323; 13004 x = (float) (*ix) / 30269.f + (float) (*iy) / 30307.f + (float) (*iz) / 13005 30323.f; 13006 u = x - (int) x; 13007 ret_val = (int) ((float) (*n) * u + 1.f); 13008 return ret_val; 13009 } /* jrand_ */
long int left_ | ( | double * | , | |
double * | , | |||
double * | , | |||
double * | , | |||
double * | , | |||
double * | , | |||
double * | , | |||
double * | , | |||
double * | ||||
) |
Definition at line 13011 of file util_sparx.cpp.
Referenced by angle_(), delnod_(), edge_(), trmesh_(), and EMAN::Util::trmsh3_().
13014 { 13015 /* System generated locals */ 13016 long int ret_val; 13017 13018 13019 /* *********************************************************** */ 13020 13021 /* From STRIPACK */ 13022 /* Robert J. Renka */ 13023 /* Dept. of Computer Science */ 13024 /* Univ. of North Texas */ 13025 /* renka@cs.unt.edu */ 13026 /* 07/15/96 */ 13027 13028 /* This function determines whether node N0 is in the */ 13029 /* (closed) left hemisphere defined by the plane containing */ 13030 /* N1, N2, and the origin, where left is defined relative to */ 13031 /* an observer at N1 facing N2. */ 13032 13033 13034 /* On input: */ 13035 13036 /* X1,Y1,Z1 = Coordinates of N1. */ 13037 13038 /* X2,Y2,Z2 = Coordinates of N2. */ 13039 13040 /* X0,Y0,Z0 = Coordinates of N0. */ 13041 13042 /* Input parameters are not altered by this function. */ 13043 13044 /* On output: */ 13045 13046 /* LEFT = TRUE if and only if N0 is in the closed */ 13047 /* left hemisphere. */ 13048 13049 /* Modules required by LEFT: None */ 13050 13051 /* *********************************************************** */ 13052 13053 /* LEFT = TRUE iff <N0,N1 X N2> = det(N0,N1,N2) .GE. 0. */ 13054 13055 ret_val = *x0 * (*y1 * *z2 - *y2 * *z1) - *y0 * (*x1 * *z2 - *x2 * *z1) + 13056 *z0 * (*x1 * *y2 - *x2 * *y1) >= -0.000001; 13057 13058 13059 return ret_val; 13060 } /* left_ */
int lstptr_ | ( | int * | lpl, | |
int * | nb, | |||
int * | list, | |||
int * | lptr | |||
) |
Definition at line 13062 of file util_sparx.cpp.
Referenced by addnod_(), crlist_(), delarc_(), delnod_(), intadd_(), nearnd_(), swap_(), and trfind_().
13063 { 13064 /* System generated locals */ 13065 int ret_val; 13066 13067 /* Local variables */ 13068 static int nd, lp; 13069 13070 13071 /* *********************************************************** */ 13072 13073 /* From STRIPACK */ 13074 /* Robert J. Renka */ 13075 /* Dept. of Computer Science */ 13076 /* Univ. of North Texas */ 13077 /* renka@cs.unt.edu */ 13078 /* 07/15/96 */ 13079 13080 /* This function returns the index (LIST pointer) of NB in */ 13081 /* the adjacency list for N0, where LPL = LEND(N0). */ 13082 13083 /* This function is identical to the similarly named */ 13084 /* function in TRIPACK. */ 13085 13086 13087 /* On input: */ 13088 13089 /* LPL = LEND(N0) */ 13090 13091 /* NB = Index of the node whose pointer is to be re- */ 13092 /* turned. NB must be connected to N0. */ 13093 13094 /* LIST,LPTR = Data structure defining the triangula- */ 13095 /* tion. Refer to Subroutine TRMESH. */ 13096 13097 /* Input parameters are not altered by this function. */ 13098 13099 /* On output: */ 13100 13101 /* LSTPTR = Pointer such that LIST(LSTPTR) = NB or */ 13102 /* LIST(LSTPTR) = -NB, unless NB is not a */ 13103 /* neighbor of N0, in which case LSTPTR = LPL. */ 13104 13105 /* Modules required by LSTPTR: None */ 13106 13107 /* *********************************************************** */ 13108 13109 13110 /* Local parameters: */ 13111 13112 /* LP = LIST pointer */ 13113 /* ND = Nodal index */ 13114 13115 /* Parameter adjustments */ 13116 --lptr; 13117 --list; 13118 13119 /* Function Body */ 13120 lp = lptr[*lpl]; 13121 L1: 13122 nd = list[lp]; 13123 if (nd == *nb) { 13124 goto L2; 13125 } 13126 lp = lptr[lp]; 13127 if (lp != *lpl) { 13128 goto L1; 13129 } 13130 13131 L2: 13132 ret_val = lp; 13133 return ret_val; 13134 } /* lstptr_ */
int nbcnt_ | ( | int * | lpl, | |
int * | lptr | |||
) |
Definition at line 13136 of file util_sparx.cpp.
Referenced by delnod_().
13137 { 13138 /* System generated locals */ 13139 int ret_val; 13140 13141 /* Local variables */ 13142 static int k, lp; 13143 13144 13145 /* *********************************************************** */ 13146 13147 /* From STRIPACK */ 13148 /* Robert J. Renka */ 13149 /* Dept. of Computer Science */ 13150 /* Univ. of North Texas */ 13151 /* renka@cs.unt.edu */ 13152 /* 07/15/96 */ 13153 13154 /* This function returns the number of neighbors of a node */ 13155 /* N0 in a triangulation created by Subroutine TRMESH. */ 13156 13157 /* This function is identical to the similarly named */ 13158 /* function in TRIPACK. */ 13159 13160 13161 /* On input: */ 13162 13163 /* LPL = LIST pointer to the last neighbor of N0 -- */ 13164 /* LPL = LEND(N0). */ 13165 13166 /* LPTR = Array of pointers associated with LIST. */ 13167 13168 /* Input parameters are not altered by this function. */ 13169 13170 /* On output: */ 13171 13172 /* NBCNT = Number of neighbors of N0. */ 13173 13174 /* Modules required by NBCNT: None */ 13175 13176 /* *********************************************************** */ 13177 13178 13179 /* Local parameters: */ 13180 13181 /* K = Counter for computing the number of neighbors */ 13182 /* LP = LIST pointer */ 13183 13184 /* Parameter adjustments */ 13185 --lptr; 13186 13187 /* Function Body */ 13188 lp = *lpl; 13189 k = 1; 13190 13191 L1: 13192 lp = lptr[lp]; 13193 if (lp == *lpl) { 13194 goto L2; 13195 } 13196 ++k; 13197 goto L1; 13198 13199 L2: 13200 ret_val = k; 13201 return ret_val; 13202 } /* nbcnt_ */
int nearnd_ | ( | double * | p, | |
int * | ist, | |||
int * | n, | |||
double * | x, | |||
double * | y, | |||
double * | z__, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
double * | al | |||
) |
Definition at line 13204 of file util_sparx.cpp.
References abs, lstptr_(), nn(), and trfind_().
13207 { 13208 /* System generated locals */ 13209 int ret_val, i__1; 13210 13211 /* Builtin functions */ 13212 //double acos(double); 13213 13214 /* Local variables */ 13215 static int l; 13216 static double b1, b2, b3; 13217 static int i1, i2, i3, n1, n2, n3, lp, nn, nr; 13218 static double ds1; 13219 static int lp1, lp2; 13220 static double dx1, dx2, dx3, dy1, dy2, dy3, dz1, dz2, dz3; 13221 static int lpl; 13222 static double dsr; 13223 static int nst, listp[25], lptrp[25]; 13224 /* Subroutine */ int trfind_(int *, double *, int *, 13225 double *, double *, double *, int *, int *, 13226 int *, double *, double *, double *, int *, 13227 int *, int *); 13228 int lstptr_(int *, int *, int *, int *); 13229 13230 13231 /* *********************************************************** */ 13232 13233 /* From STRIPACK */ 13234 /* Robert J. Renka */ 13235 /* Dept. of Computer Science */ 13236 /* Univ. of North Texas */ 13237 /* renka@cs.unt.edu */ 13238 /* 07/28/98 */ 13239 13240 /* Given a point P on the surface of the unit sphere and a */ 13241 /* Delaunay triangulation created by Subroutine TRMESH, this */ 13242 /* function returns the index of the nearest triangulation */ 13243 /* node to P. */ 13244 13245 /* The algorithm consists of implicitly adding P to the */ 13246 /* triangulation, finding the nearest neighbor to P, and */ 13247 /* implicitly deleting P from the triangulation. Thus, it */ 13248 /* is based on the fact that, if P is a node in a Delaunay */ 13249 /* triangulation, the nearest node to P is a neighbor of P. */ 13250 13251 13252 /* On input: */ 13253 13254 /* P = Array of length 3 containing the Cartesian coor- */ 13255 /* dinates of the point P to be located relative to */ 13256 /* the triangulation. It is assumed without a test */ 13257 /* that P(1)**2 + P(2)**2 + P(3)**2 = 1. */ 13258 13259 /* IST = Index of a node at which TRFIND begins the */ 13260 /* search. Search time depends on the proximity */ 13261 /* of this node to P. */ 13262 13263 /* N = Number of nodes in the triangulation. N .GE. 3. */ 13264 13265 /* X,Y,Z = Arrays of length N containing the Cartesian */ 13266 /* coordinates of the nodes. */ 13267 13268 /* LIST,LPTR,LEND = Data structure defining the trian- */ 13269 /* gulation. Refer to TRMESH. */ 13270 13271 /* Input parameters are not altered by this function. */ 13272 13273 /* On output: */ 13274 13275 /* NEARND = Nodal index of the nearest node to P, or 0 */ 13276 /* if N < 3 or the triangulation data struc- */ 13277 /* ture is invalid. */ 13278 13279 /* AL = Arc length (angular distance in radians) be- */ 13280 /* tween P and NEARND unless NEARND = 0. */ 13281 13282 /* Note that the number of candidates for NEARND */ 13283 /* (neighbors of P) is limited to LMAX defined in */ 13284 /* the PARAMETER statement below. */ 13285 13286 /* Modules required by NEARND: JRAND, LSTPTR, TRFIND, STORE */ 13287 13288 /* Intrinsic functions called by NEARND: ABS, ACOS */ 13289 13290 /* *********************************************************** */ 13291 13292 13293 /* Local parameters: */ 13294 13295 /* B1,B2,B3 = Unnormalized barycentric coordinates returned */ 13296 /* by TRFIND */ 13297 /* DS1 = (Negative cosine of the) distance from P to N1 */ 13298 /* DSR = (Negative cosine of the) distance from P to NR */ 13299 /* DX1,..DZ3 = Components of vectors used by the swap test */ 13300 /* I1,I2,I3 = Nodal indexes of a triangle containing P, or */ 13301 /* the rightmost (I1) and leftmost (I2) visible */ 13302 /* boundary nodes as viewed from P */ 13303 /* L = Length of LISTP/LPTRP and number of neighbors */ 13304 /* of P */ 13305 /* LMAX = Maximum value of L */ 13306 /* LISTP = Indexes of the neighbors of P */ 13307 /* LPTRP = Array of pointers in 1-1 correspondence with */ 13308 /* LISTP elements */ 13309 /* LP = LIST pointer to a neighbor of N1 and LISTP */ 13310 /* pointer */ 13311 /* LP1,LP2 = LISTP indexes (pointers) */ 13312 /* LPL = Pointer to the last neighbor of N1 */ 13313 /* N1 = Index of a node visible from P */ 13314 /* N2 = Index of an endpoint of an arc opposite P */ 13315 /* N3 = Index of the node opposite N1->N2 */ 13316 /* NN = Local copy of N */ 13317 /* NR = Index of a candidate for the nearest node to P */ 13318 /* NST = Index of the node at which TRFIND begins the */ 13319 /* search */ 13320 13321 13322 /* Store local parameters and test for N invalid. */ 13323 13324 /* Parameter adjustments */ 13325 --p; 13326 --lend; 13327 --z__; 13328 --y; 13329 --x; 13330 --list; 13331 --lptr; 13332 13333 /* Function Body */ 13334 nn = *n; 13335 if (nn < 3) { 13336 goto L6; 13337 } 13338 nst = *ist; 13339 if (nst < 1 || nst > nn) { 13340 nst = 1; 13341 } 13342 13343 /* Find a triangle (I1,I2,I3) containing P, or the rightmost */ 13344 /* (I1) and leftmost (I2) visible boundary nodes as viewed */ 13345 /* from P. */ 13346 13347 trfind_(&nst, &p[1], n, &x[1], &y[1], &z__[1], &list[1], &lptr[1], &lend[ 13348 1], &b1, &b2, &b3, &i1, &i2, &i3); 13349 13350 /* Test for collinear nodes. */ 13351 13352 if (i1 == 0) { 13353 goto L6; 13354 } 13355 13356 /* Store the linked list of 'neighbors' of P in LISTP and */ 13357 /* LPTRP. I1 is the first neighbor, and 0 is stored as */ 13358 /* the last neighbor if P is not contained in a triangle. */ 13359 /* L is the length of LISTP and LPTRP, and is limited to */ 13360 /* LMAX. */ 13361 13362 if (i3 != 0) { 13363 listp[0] = i1; 13364 lptrp[0] = 2; 13365 listp[1] = i2; 13366 lptrp[1] = 3; 13367 listp[2] = i3; 13368 lptrp[2] = 1; 13369 l = 3; 13370 } else { 13371 n1 = i1; 13372 l = 1; 13373 lp1 = 2; 13374 listp[l - 1] = n1; 13375 lptrp[l - 1] = lp1; 13376 13377 /* Loop on the ordered sequence of visible boundary nodes */ 13378 /* N1 from I1 to I2. */ 13379 13380 L1: 13381 lpl = lend[n1]; 13382 n1 = -list[lpl]; 13383 l = lp1; 13384 lp1 = l + 1; 13385 listp[l - 1] = n1; 13386 lptrp[l - 1] = lp1; 13387 if (n1 != i2 && lp1 < 25) { 13388 goto L1; 13389 } 13390 l = lp1; 13391 listp[l - 1] = 0; 13392 lptrp[l - 1] = 1; 13393 } 13394 13395 /* Initialize variables for a loop on arcs N1-N2 opposite P */ 13396 /* in which new 'neighbors' are 'swapped' in. N1 follows */ 13397 /* N2 as a neighbor of P, and LP1 and LP2 are the LISTP */ 13398 /* indexes of N1 and N2. */ 13399 13400 lp2 = 1; 13401 n2 = i1; 13402 lp1 = lptrp[0]; 13403 n1 = listp[lp1 - 1]; 13404 13405 /* Begin loop: find the node N3 opposite N1->N2. */ 13406 13407 L2: 13408 lp = lstptr_(&lend[n1], &n2, &list[1], &lptr[1]); 13409 if (list[lp] < 0) { 13410 goto L3; 13411 } 13412 lp = lptr[lp]; 13413 n3 = (i__1 = list[lp], abs(i__1)); 13414 13415 /* Swap test: Exit the loop if L = LMAX. */ 13416 13417 if (l == 25) { 13418 goto L4; 13419 } 13420 dx1 = x[n1] - p[1]; 13421 dy1 = y[n1] - p[2]; 13422 dz1 = z__[n1] - p[3]; 13423 13424 dx2 = x[n2] - p[1]; 13425 dy2 = y[n2] - p[2]; 13426 dz2 = z__[n2] - p[3]; 13427 13428 dx3 = x[n3] - p[1]; 13429 dy3 = y[n3] - p[2]; 13430 dz3 = z__[n3] - p[3]; 13431 if (dx3 * (dy2 * dz1 - dy1 * dz2) - dy3 * (dx2 * dz1 - dx1 * dz2) + dz3 * 13432 (dx2 * dy1 - dx1 * dy2) <= 0.) { 13433 goto L3; 13434 } 13435 13436 /* Swap: Insert N3 following N2 in the adjacency list for P. */ 13437 /* The two new arcs opposite P must be tested. */ 13438 13439 ++l; 13440 lptrp[lp2 - 1] = l; 13441 listp[l - 1] = n3; 13442 lptrp[l - 1] = lp1; 13443 lp1 = l; 13444 n1 = n3; 13445 goto L2; 13446 13447 /* No swap: Advance to the next arc and test for termination */ 13448 /* on N1 = I1 (LP1 = 1) or N1 followed by 0. */ 13449 13450 L3: 13451 if (lp1 == 1) { 13452 goto L4; 13453 } 13454 lp2 = lp1; 13455 n2 = n1; 13456 lp1 = lptrp[lp1 - 1]; 13457 n1 = listp[lp1 - 1]; 13458 if (n1 == 0) { 13459 goto L4; 13460 } 13461 goto L2; 13462 13463 /* Set NR and DSR to the index of the nearest node to P and */ 13464 /* an increasing function (negative cosine) of its distance */ 13465 /* from P, respectively. */ 13466 13467 L4: 13468 nr = i1; 13469 dsr = -(x[nr] * p[1] + y[nr] * p[2] + z__[nr] * p[3]); 13470 i__1 = l; 13471 for (lp = 2; lp <= i__1; ++lp) { 13472 n1 = listp[lp - 1]; 13473 if (n1 == 0) { 13474 goto L5; 13475 } 13476 ds1 = -(x[n1] * p[1] + y[n1] * p[2] + z__[n1] * p[3]); 13477 if (ds1 < dsr) { 13478 nr = n1; 13479 dsr = ds1; 13480 } 13481 L5: 13482 ; 13483 } 13484 dsr = -dsr; 13485 if (dsr > 1.) { 13486 dsr = 1.; 13487 } 13488 *al = acos(dsr); 13489 ret_val = nr; 13490 return ret_val; 13491 13492 /* Invalid input. */ 13493 13494 L6: 13495 ret_val = 0; 13496 return ret_val; 13497 } /* nearnd_ */
int optim_ | ( | double * | x, | |
double * | y, | |||
double * | z__, | |||
int * | na, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | nit, | |||
int * | iwk, | |||
int * | ier | |||
) |
Definition at line 13499 of file util_sparx.cpp.
References abs, FALSE_, swap_(), swptst_(), and TRUE_.
Referenced by delnod_(), and edge_().
13502 { 13503 /* System generated locals */ 13504 int i__1, i__2; 13505 13506 /* Local variables */ 13507 static int i__, n1, n2, lp, io1, io2, nna, lp21, lpl, lpp; 13508 static long int swp; 13509 static int iter; 13510 /* Subroutine */ int swap_(int *, int *, int *, 13511 int *, int *, int *, int *, int *); 13512 static int maxit; 13513 long int swptst_(int *, int *, int *, int *, 13514 double *, double *, double *); 13515 13516 13517 /* *********************************************************** */ 13518 13519 /* From STRIPACK */ 13520 /* Robert J. Renka */ 13521 /* Dept. of Computer Science */ 13522 /* Univ. of North Texas */ 13523 /* renka@cs.unt.edu */ 13524 /* 07/30/98 */ 13525 13526 /* Given a set of NA triangulation arcs, this subroutine */ 13527 /* optimizes the portion of the triangulation consisting of */ 13528 /* the quadrilaterals (pairs of adjacent triangles) which */ 13529 /* have the arcs as diagonals by applying the circumcircle */ 13530 /* test and appropriate swaps to the arcs. */ 13531 13532 /* An iteration consists of applying the swap test and */ 13533 /* swaps to all NA arcs in the order in which they are */ 13534 /* stored. The iteration is repeated until no swap occurs */ 13535 /* or NIT iterations have been performed. The bound on the */ 13536 /* number of iterations may be necessary to prevent an */ 13537 /* infinite loop caused by cycling (reversing the effect of a */ 13538 /* previous swap) due to floating point inaccuracy when four */ 13539 /* or more nodes are nearly cocircular. */ 13540 13541 13542 /* On input: */ 13543 13544 /* X,Y,Z = Arrays containing the nodal coordinates. */ 13545 13546 /* NA = Number of arcs in the set. NA .GE. 0. */ 13547 13548 /* The above parameters are not altered by this routine. */ 13549 13550 /* LIST,LPTR,LEND = Data structure defining the trian- */ 13551 /* gulation. Refer to Subroutine */ 13552 /* TRMESH. */ 13553 13554 /* NIT = Maximum number of iterations to be performed. */ 13555 /* NIT = 4*NA should be sufficient. NIT .GE. 1. */ 13556 13557 /* IWK = int array dimensioned 2 by NA containing */ 13558 /* the nodal indexes of the arc endpoints (pairs */ 13559 /* of endpoints are stored in columns). */ 13560 13561 /* On output: */ 13562 13563 /* LIST,LPTR,LEND = Updated triangulation data struc- */ 13564 /* ture reflecting the swaps. */ 13565 13566 /* NIT = Number of iterations performed. */ 13567 13568 /* IWK = Endpoint indexes of the new set of arcs */ 13569 /* reflecting the swaps. */ 13570 13571 /* IER = Error indicator: */ 13572 /* IER = 0 if no errors were encountered. */ 13573 /* IER = 1 if a swap occurred on the last of */ 13574 /* MAXIT iterations, where MAXIT is the */ 13575 /* value of NIT on input. The new set */ 13576 /* of arcs is not necessarily optimal */ 13577 /* in this case. */ 13578 /* IER = 2 if NA < 0 or NIT < 1 on input. */ 13579 /* IER = 3 if IWK(2,I) is not a neighbor of */ 13580 /* IWK(1,I) for some I in the range 1 */ 13581 /* to NA. A swap may have occurred in */ 13582 /* this case. */ 13583 /* IER = 4 if a zero pointer was returned by */ 13584 /* Subroutine SWAP. */ 13585 13586 /* Modules required by OPTIM: LSTPTR, SWAP, SWPTST */ 13587 13588 /* Intrinsic function called by OPTIM: ABS */ 13589 13590 /* *********************************************************** */ 13591 13592 13593 /* Local parameters: */ 13594 13595 /* I = Column index for IWK */ 13596 /* IO1,IO2 = Nodal indexes of the endpoints of an arc in IWK */ 13597 /* ITER = Iteration count */ 13598 /* LP = LIST pointer */ 13599 /* LP21 = Parameter returned by SWAP (not used) */ 13600 /* LPL = Pointer to the last neighbor of IO1 */ 13601 /* LPP = Pointer to the node preceding IO2 as a neighbor */ 13602 /* of IO1 */ 13603 /* MAXIT = Input value of NIT */ 13604 /* N1,N2 = Nodes opposite IO1->IO2 and IO2->IO1, */ 13605 /* respectively */ 13606 /* NNA = Local copy of NA */ 13607 /* SWP = Flag set to TRUE iff a swap occurs in the */ 13608 /* optimization loop */ 13609 13610 /* Parameter adjustments */ 13611 --x; 13612 --y; 13613 --z__; 13614 iwk -= 3; 13615 --list; 13616 --lptr; 13617 --lend; 13618 13619 /* Function Body */ 13620 nna = *na; 13621 maxit = *nit; 13622 if (nna < 0 || maxit < 1) { 13623 goto L7; 13624 } 13625 13626 /* Initialize iteration count ITER and test for NA = 0. */ 13627 13628 iter = 0; 13629 if (nna == 0) { 13630 goto L5; 13631 } 13632 13633 /* Top of loop -- */ 13634 /* SWP = TRUE iff a swap occurred in the current iteration. */ 13635 13636 L1: 13637 if (iter == maxit) { 13638 goto L6; 13639 } 13640 ++iter; 13641 swp = FALSE_; 13642 13643 /* Inner loop on arcs IO1-IO2 -- */ 13644 13645 i__1 = nna; 13646 for (i__ = 1; i__ <= i__1; ++i__) { 13647 io1 = iwk[(i__ << 1) + 1]; 13648 io2 = iwk[(i__ << 1) + 2]; 13649 13650 /* Set N1 and N2 to the nodes opposite IO1->IO2 and */ 13651 /* IO2->IO1, respectively. Determine the following: */ 13652 13653 /* LPL = pointer to the last neighbor of IO1, */ 13654 /* LP = pointer to IO2 as a neighbor of IO1, and */ 13655 /* LPP = pointer to the node N2 preceding IO2. */ 13656 13657 lpl = lend[io1]; 13658 lpp = lpl; 13659 lp = lptr[lpp]; 13660 L2: 13661 if (list[lp] == io2) { 13662 goto L3; 13663 } 13664 lpp = lp; 13665 lp = lptr[lpp]; 13666 if (lp != lpl) { 13667 goto L2; 13668 } 13669 13670 /* IO2 should be the last neighbor of IO1. Test for no */ 13671 /* arc and bypass the swap test if IO1 is a boundary */ 13672 /* node. */ 13673 13674 if ((i__2 = list[lp], abs(i__2)) != io2) { 13675 goto L8; 13676 } 13677 if (list[lp] < 0) { 13678 goto L4; 13679 } 13680 13681 /* Store N1 and N2, or bypass the swap test if IO1 is a */ 13682 /* boundary node and IO2 is its first neighbor. */ 13683 13684 L3: 13685 n2 = list[lpp]; 13686 if (n2 < 0) { 13687 goto L4; 13688 } 13689 lp = lptr[lp]; 13690 n1 = (i__2 = list[lp], abs(i__2)); 13691 13692 /* Test IO1-IO2 for a swap, and update IWK if necessary. */ 13693 13694 if (! swptst_(&n1, &n2, &io1, &io2, &x[1], &y[1], &z__[1])) { 13695 goto L4; 13696 } 13697 swap_(&n1, &n2, &io1, &io2, &list[1], &lptr[1], &lend[1], &lp21); 13698 if (lp21 == 0) { 13699 goto L9; 13700 } 13701 swp = TRUE_; 13702 iwk[(i__ << 1) + 1] = n1; 13703 iwk[(i__ << 1) + 2] = n2; 13704 L4: 13705 ; 13706 } 13707 if (swp) { 13708 goto L1; 13709 } 13710 13711 /* Successful termination. */ 13712 13713 L5: 13714 *nit = iter; 13715 *ier = 0; 13716 return 0; 13717 13718 /* MAXIT iterations performed without convergence. */ 13719 13720 L6: 13721 *nit = maxit; 13722 *ier = 1; 13723 return 0; 13724 13725 /* Invalid input parameter. */ 13726 13727 L7: 13728 *nit = 0; 13729 *ier = 2; 13730 return 0; 13731 13732 /* IO2 is not a neighbor of IO1. */ 13733 13734 L8: 13735 *nit = iter; 13736 *ier = 3; 13737 return 0; 13738 13739 /* Zero pointer returned by SWAP. */ 13740 13741 L9: 13742 *nit = iter; 13743 *ier = 4; 13744 return 0; 13745 } /* optim_ */
int projct_ | ( | double * | px, | |
double * | py, | |||
double * | pz, | |||
double * | ox, | |||
double * | oy, | |||
double * | oz, | |||
double * | ex, | |||
double * | ey, | |||
double * | ez, | |||
double * | vx, | |||
double * | vy, | |||
double * | vz, | |||
long int * | init, | |||
double * | x, | |||
double * | y, | |||
double * | z__, | |||
int * | ier | |||
) |
Definition at line 13747 of file util_sparx.cpp.
References FALSE_, and sqrt().
13752 { 13753 /* Builtin functions */ 13754 //double sqrt(double); 13755 13756 /* Local variables */ 13757 static double s, sc, xe, ye, ze, xh, yh, zh, xv, yv, zv, xw, yw, zw, 13758 oes, xoe, yoe, zoe, xep, yep, zep; 13759 13760 13761 /* *********************************************************** */ 13762 13763 /* From PLTPACK, SCRPLOT, and STRIPACK */ 13764 /* Robert J. Renka */ 13765 /* Dept. of Computer Science */ 13766 /* Univ. of North Texas */ 13767 /* renka@cs.unt.edu */ 13768 /* 07/18/90 */ 13769 13770 /* Given a projection plane and associated coordinate sys- */ 13771 /* tem defined by an origin O, eye position E, and up-vector */ 13772 /* V, this subroutine applies a perspective depth transform- */ 13773 /* ation T to a point P = (PX,PY,PZ), returning the point */ 13774 /* T(P) = (X,Y,Z), where X and Y are the projection plane */ 13775 /* coordinates of the point that lies in the projection */ 13776 /* plane and on the line defined by P and E, and Z is the */ 13777 /* depth associated with P. */ 13778 13779 /* The projection plane is defined to be the plane that */ 13780 /* contains O and has normal defined by O and E. */ 13781 13782 /* The depth Z is defined in such a way that Z < 1, T maps */ 13783 /* lines to lines (and planes to planes), and if two distinct */ 13784 /* points have the same projection plane coordinates, then */ 13785 /* the one closer to E has a smaller depth. (Z increases */ 13786 /* monotonically with orthogonal distance from P to the plane */ 13787 /* that is parallel to the projection plane and contains E.) */ 13788 /* This depth value facilitates depth sorting and depth buf- */ 13789 /* fer methods. */ 13790 13791 13792 /* On input: */ 13793 13794 /* PX,PY,PZ = Cartesian coordinates of the point P to */ 13795 /* be mapped onto the projection plane. The */ 13796 /* half line that contains P and has end- */ 13797 /* point at E must intersect the plane. */ 13798 13799 /* OX,OY,OZ = Coordinates of O (the origin of a coordi- */ 13800 /* nate system in the projection plane). A */ 13801 /* reasonable value for O is a point near */ 13802 /* the center of an object or scene to be */ 13803 /* viewed. */ 13804 13805 /* EX,EY,EZ = Coordinates of the eye-position E defin- */ 13806 /* ing the normal to the plane and the line */ 13807 /* of sight for the projection. E must not */ 13808 /* coincide with O or P, and the angle be- */ 13809 /* tween the vectors O-E and P-E must be */ 13810 /* less than 90 degrees. Note that E and P */ 13811 /* may lie on opposite sides of the projec- */ 13812 /* tion plane. */ 13813 13814 /* VX,VY,VZ = Coordinates of a point V which defines */ 13815 /* the positive Y axis of an X-Y coordinate */ 13816 /* system in the projection plane as the */ 13817 /* half-line containing O and the projection */ 13818 /* of O+V onto the plane. The positive X */ 13819 /* axis has direction defined by the cross */ 13820 /* product V X (E-O). */ 13821 13822 /* The above parameters are not altered by this routine. */ 13823 13824 /* INIT = long int switch which must be set to TRUE on */ 13825 /* the first call and when the values of O, E, */ 13826 /* or V have been altered since a previous call. */ 13827 /* If INIT = FALSE, it is assumed that only the */ 13828 /* coordinates of P have changed since a previ- */ 13829 /* ous call. Previously stored quantities are */ 13830 /* used for increased efficiency in this case. */ 13831 13832 /* On output: */ 13833 13834 /* INIT = Switch with value reset to FALSE if IER = 0. */ 13835 13836 /* X,Y = Projection plane coordinates of the point */ 13837 /* that lies in the projection plane and on the */ 13838 /* line defined by E and P. X and Y are not */ 13839 /* altered if IER .NE. 0. */ 13840 13841 /* Z = Depth value defined above unless IER .NE. 0. */ 13842 13843 /* IER = Error indicator. */ 13844 /* IER = 0 if no errors were encountered. */ 13845 /* IER = 1 if the inner product of O-E with P-E */ 13846 /* is not positive, implying that E is */ 13847 /* too close to the plane. */ 13848 /* IER = 2 if O, E, and O+V are collinear. See */ 13849 /* the description of VX,VY,VZ. */ 13850 13851 /* Modules required by PROJCT: None */ 13852 13853 /* Intrinsic function called by PROJCT: SQRT */ 13854 13855 /* *********************************************************** */ 13856 13857 13858 /* Local parameters: */ 13859 13860 /* OES = Norm squared of OE -- inner product (OE,OE) */ 13861 /* S = Scale factor for computing projections */ 13862 /* SC = Scale factor for normalizing VN and HN */ 13863 /* XE,YE,ZE = Local copies of EX, EY, EZ */ 13864 /* XEP,YEP,ZEP = Components of the vector EP from E to P */ 13865 /* XH,YH,ZH = Components of a unit vector HN defining the */ 13866 /* positive X-axis in the plane */ 13867 /* XOE,YOE,ZOE = Components of the vector OE from O to E */ 13868 /* XV,YV,ZV = Components of a unit vector VN defining the */ 13869 /* positive Y-axis in the plane */ 13870 /* XW,YW,ZW = Components of the vector W from O to the */ 13871 /* projection of P onto the plane */ 13872 13873 if (*init) { 13874 13875 /* Compute parameters defining the transformation: */ 13876 /* 17 adds, 27 multiplies, 3 divides, 2 compares, and */ 13877 /* 2 square roots. */ 13878 13879 /* Set the coordinates of E to local variables, compute */ 13880 /* OE = E-O and OES, and test for OE = 0. */ 13881 13882 xe = *ex; 13883 ye = *ey; 13884 ze = *ez; 13885 xoe = xe - *ox; 13886 yoe = ye - *oy; 13887 zoe = ze - *oz; 13888 oes = xoe * xoe + yoe * yoe + zoe * zoe; 13889 if (oes == 0.) { 13890 goto L1; 13891 } 13892 13893 /* Compute S = (OE,V)/OES and VN = V - S*OE. */ 13894 13895 s = (xoe * *vx + yoe * *vy + zoe * *vz) / oes; 13896 xv = *vx - s * xoe; 13897 yv = *vy - s * yoe; 13898 zv = *vz - s * zoe; 13899 13900 /* Normalize VN to a unit vector. */ 13901 13902 sc = xv * xv + yv * yv + zv * zv; 13903 if (sc == 0.) { 13904 goto L2; 13905 } 13906 sc = 1. / sqrt(sc); 13907 xv = sc * xv; 13908 yv = sc * yv; 13909 zv = sc * zv; 13910 13911 /* Compute HN = VN X OE (normalized). */ 13912 13913 xh = yv * zoe - yoe * zv; 13914 yh = xoe * zv - xv * zoe; 13915 zh = xv * yoe - xoe * yv; 13916 sc = sqrt(xh * xh + yh * yh + zh * zh); 13917 if (sc == 0.) { 13918 goto L2; 13919 } 13920 sc = 1. / sc; 13921 xh = sc * xh; 13922 yh = sc * yh; 13923 zh = sc * zh; 13924 } 13925 13926 /* Apply the transformation: 13 adds, 12 multiplies, */ 13927 /* 1 divide, and 1 compare. */ 13928 13929 /* Compute EP = P-E, S = OES/(OE,EP), and W = OE - S*EP. */ 13930 13931 xep = *px - xe; 13932 yep = *py - ye; 13933 zep = *pz - ze; 13934 s = xoe * xep + yoe * yep + zoe * zep; 13935 if (s >= 0.) { 13936 goto L1; 13937 } 13938 s = oes / s; 13939 xw = xoe - s * xep; 13940 yw = yoe - s * yep; 13941 zw = zoe - s * zep; 13942 13943 /* Map W into X = (W,HN), Y = (W,VN), compute Z = 1+S, and */ 13944 /* reset INIT. */ 13945 13946 *x = xw * xh + yw * yh + zw * zh; 13947 *y = xw * xv + yw * yv + zw * zv; 13948 *z__ = s + 1.; 13949 *init = FALSE_; 13950 *ier = 0; 13951 return 0; 13952 13953 /* (OE,EP) .GE. 0. */ 13954 13955 L1: 13956 *ier = 1; 13957 return 0; 13958 13959 /* O, E, and O+V are collinear. */ 13960 13961 L2: 13962 *ier = 2; 13963 return 0; 13964 } /* projct_ */
int random_ | ( | int * | ix, | |
int * | iy, | |||
int * | iz, | |||
double * | rannum | |||
) |
Definition at line 17217 of file util_sparx.cpp.
17219 { 17220 static double x; 17221 17222 17223 /* This routine returns pseudo-random numbers uniformly */ 17224 /* distributed in the interval (0,1). int seeds IX, IY, */ 17225 /* and IZ should be initialized to values in the range 1 to */ 17226 /* 30,000 before the first call to RANDOM, and should not */ 17227 /* be altered between subsequent calls (unless a sequence */ 17228 /* of random numbers is to be repeated by reinitializing the */ 17229 /* seeds). */ 17230 17231 /* Reference: B. A. Wichmann and I. D. Hill, An Efficient */ 17232 /* and Portable Pseudo-random Number Generator, */ 17233 /* Applied Statistics, Vol. 31, No. 2, 1982, */ 17234 /* pp. 188-190. */ 17235 17236 *ix = *ix * 171 % 30269; 17237 *iy = *iy * 172 % 30307; 17238 *iz = *iz * 170 % 30323; 17239 x = (double) (*ix) / 30269. + (double) (*iy) / 30307. + ( 17240 double) (*iz) / 30323.; 17241 *rannum = x - (int) x; 17242 return 0; 17243 } /* random_ */
int scoord_ | ( | double * | px, | |
double * | py, | |||
double * | pz, | |||
double * | plat, | |||
double * | plon, | |||
double * | pnrm | |||
) |
Definition at line 13966 of file util_sparx.cpp.
References sqrt().
13968 { 13969 /* Builtin functions */ 13970 //double sqrt(double), atan2(double, double), asin(double); 13971 13972 13973 /* *********************************************************** */ 13974 13975 /* From STRIPACK */ 13976 /* Robert J. Renka */ 13977 /* Dept. of Computer Science */ 13978 /* Univ. of North Texas */ 13979 /* renka@cs.unt.edu */ 13980 /* 08/27/90 */ 13981 13982 /* This subroutine converts a point P from Cartesian coor- */ 13983 /* dinates to spherical coordinates. */ 13984 13985 13986 /* On input: */ 13987 13988 /* PX,PY,PZ = Cartesian coordinates of P. */ 13989 13990 /* Input parameters are not altered by this routine. */ 13991 13992 /* On output: */ 13993 13994 /* PLAT = Latitude of P in the range -PI/2 to PI/2, or */ 13995 /* 0 if PNRM = 0. PLAT should be scaled by */ 13996 /* 180/PI to obtain the value in degrees. */ 13997 13998 /* PLON = Longitude of P in the range -PI to PI, or 0 */ 13999 /* if P lies on the Z-axis. PLON should be */ 14000 /* scaled by 180/PI to obtain the value in */ 14001 /* degrees. */ 14002 14003 /* PNRM = Magnitude (Euclidean norm) of P. */ 14004 14005 /* Modules required by SCOORD: None */ 14006 14007 /* Intrinsic functions called by SCOORD: ASIN, ATAN2, SQRT */ 14008 14009 /* *********************************************************** */ 14010 14011 *pnrm = sqrt(*px * *px + *py * *py + *pz * *pz); 14012 if (*px != 0. || *py != 0.) { 14013 *plon = atan2(*py, *px); 14014 } else { 14015 *plon = 0.; 14016 } 14017 if (*pnrm != 0.) { 14018 *plat = asin(*pz / *pnrm); 14019 } else { 14020 *plat = 0.; 14021 } 14022 return 0; 14023 } /* scoord_ */
double store_ | ( | double * | x | ) |
Definition at line 14025 of file util_sparx.cpp.
References stcom_1, and stcom_::y.
Referenced by trfind_().
14026 { 14027 /* System generated locals */ 14028 double ret_val; 14029 14030 14031 /* *********************************************************** */ 14032 14033 /* From STRIPACK */ 14034 /* Robert J. Renka */ 14035 /* Dept. of Computer Science */ 14036 /* Univ. of North Texas */ 14037 /* renka@cs.unt.edu */ 14038 /* 05/09/92 */ 14039 14040 /* This function forces its argument X to be stored in a */ 14041 /* memory location, thus providing a means of determining */ 14042 /* floating point number characteristics (such as the machine */ 14043 /* precision) when it is necessary to avoid computation in */ 14044 /* high precision registers. */ 14045 14046 14047 /* On input: */ 14048 14049 /* X = Value to be stored. */ 14050 14051 /* X is not altered by this function. */ 14052 14053 /* On output: */ 14054 14055 /* STORE = Value of X after it has been stored and */ 14056 /* possibly truncated or rounded to the single */ 14057 /* precision word length. */ 14058 14059 /* Modules required by STORE: None */ 14060 14061 /* *********************************************************** */ 14062 14063 stcom_1.y = *x; 14064 ret_val = stcom_1.y; 14065 return ret_val; 14066 } /* store_ */
int swap_ | ( | int * | in1, | |
int * | in2, | |||
int * | io1, | |||
int * | io2, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | lp21 | |||
) |
Definition at line 14068 of file util_sparx.cpp.
References abs, and lstptr_().
Referenced by addnod_(), delnod_(), edge_(), and optim_().
14070 { 14071 /* System generated locals */ 14072 int i__1; 14073 14074 /* Local variables */ 14075 static int lp, lph, lpsav; 14076 int lstptr_(int *, int *, int *, int *); 14077 14078 14079 /* *********************************************************** */ 14080 14081 /* From STRIPACK */ 14082 /* Robert J. Renka */ 14083 /* Dept. of Computer Science */ 14084 /* Univ. of North Texas */ 14085 /* renka@cs.unt.edu */ 14086 /* 06/22/98 */ 14087 14088 /* Given a triangulation of a set of points on the unit */ 14089 /* sphere, this subroutine replaces a diagonal arc in a */ 14090 /* strictly convex quadrilateral (defined by a pair of adja- */ 14091 /* cent triangles) with the other diagonal. Equivalently, a */ 14092 /* pair of adjacent triangles is replaced by another pair */ 14093 /* having the same union. */ 14094 14095 14096 /* On input: */ 14097 14098 /* IN1,IN2,IO1,IO2 = Nodal indexes of the vertices of */ 14099 /* the quadrilateral. IO1-IO2 is re- */ 14100 /* placed by IN1-IN2. (IO1,IO2,IN1) */ 14101 /* and (IO2,IO1,IN2) must be trian- */ 14102 /* gles on input. */ 14103 14104 /* The above parameters are not altered by this routine. */ 14105 14106 /* LIST,LPTR,LEND = Data structure defining the trian- */ 14107 /* gulation. Refer to Subroutine */ 14108 /* TRMESH. */ 14109 14110 /* On output: */ 14111 14112 /* LIST,LPTR,LEND = Data structure updated with the */ 14113 /* swap -- triangles (IO1,IO2,IN1) and */ 14114 /* (IO2,IO1,IN2) are replaced by */ 14115 /* (IN1,IN2,IO2) and (IN2,IN1,IO1) */ 14116 /* unless LP21 = 0. */ 14117 14118 /* LP21 = Index of IN1 as a neighbor of IN2 after the */ 14119 /* swap is performed unless IN1 and IN2 are */ 14120 /* adjacent on input, in which case LP21 = 0. */ 14121 14122 /* Module required by SWAP: LSTPTR */ 14123 14124 /* Intrinsic function called by SWAP: ABS */ 14125 14126 /* *********************************************************** */ 14127 14128 14129 /* Local parameters: */ 14130 14131 /* LP,LPH,LPSAV = LIST pointers */ 14132 14133 14134 /* Test for IN1 and IN2 adjacent. */ 14135 14136 /* Parameter adjustments */ 14137 --lend; 14138 --lptr; 14139 --list; 14140 14141 /* Function Body */ 14142 lp = lstptr_(&lend[*in1], in2, &list[1], &lptr[1]); 14143 if ((i__1 = list[lp], abs(i__1)) == *in2) { 14144 *lp21 = 0; 14145 return 0; 14146 } 14147 14148 /* Delete IO2 as a neighbor of IO1. */ 14149 14150 lp = lstptr_(&lend[*io1], in2, &list[1], &lptr[1]); 14151 lph = lptr[lp]; 14152 lptr[lp] = lptr[lph]; 14153 14154 /* If IO2 is the last neighbor of IO1, make IN2 the */ 14155 /* last neighbor. */ 14156 14157 if (lend[*io1] == lph) { 14158 lend[*io1] = lp; 14159 } 14160 14161 /* Insert IN2 as a neighbor of IN1 following IO1 */ 14162 /* using the hole created above. */ 14163 14164 lp = lstptr_(&lend[*in1], io1, &list[1], &lptr[1]); 14165 lpsav = lptr[lp]; 14166 lptr[lp] = lph; 14167 list[lph] = *in2; 14168 lptr[lph] = lpsav; 14169 14170 /* Delete IO1 as a neighbor of IO2. */ 14171 14172 lp = lstptr_(&lend[*io2], in1, &list[1], &lptr[1]); 14173 lph = lptr[lp]; 14174 lptr[lp] = lptr[lph]; 14175 14176 /* If IO1 is the last neighbor of IO2, make IN1 the */ 14177 /* last neighbor. */ 14178 14179 if (lend[*io2] == lph) { 14180 lend[*io2] = lp; 14181 } 14182 14183 /* Insert IN1 as a neighbor of IN2 following IO2. */ 14184 14185 lp = lstptr_(&lend[*in2], io2, &list[1], &lptr[1]); 14186 lpsav = lptr[lp]; 14187 lptr[lp] = lph; 14188 list[lph] = *in1; 14189 lptr[lph] = lpsav; 14190 *lp21 = lph; 14191 return 0; 14192 } /* swap_ */
long int swptst_ | ( | int * | n1, | |
int * | n2, | |||
int * | n3, | |||
int * | n4, | |||
double * | x, | |||
double * | y, | |||
double * | z__ | |||
) |
Definition at line 14194 of file util_sparx.cpp.
Referenced by addnod_(), crlist_(), and optim_().
14196 { 14197 /* System generated locals */ 14198 long int ret_val; 14199 14200 /* Local variables */ 14201 static double x4, y4, z4, dx1, dx2, dx3, dy1, dy2, dy3, dz1, dz2, dz3; 14202 14203 14204 /* *********************************************************** */ 14205 14206 /* From STRIPACK */ 14207 /* Robert J. Renka */ 14208 /* Dept. of Computer Science */ 14209 /* Univ. of North Texas */ 14210 /* renka@cs.unt.edu */ 14211 /* 03/29/91 */ 14212 14213 /* This function decides whether or not to replace a */ 14214 /* diagonal arc in a quadrilateral with the other diagonal. */ 14215 /* The decision will be to swap (SWPTST = TRUE) if and only */ 14216 /* if N4 lies above the plane (in the half-space not contain- */ 14217 /* ing the origin) defined by (N1,N2,N3), or equivalently, if */ 14218 /* the projection of N4 onto this plane is interior to the */ 14219 /* circumcircle of (N1,N2,N3). The decision will be for no */ 14220 /* swap if the quadrilateral is not strictly convex. */ 14221 14222 14223 /* On input: */ 14224 14225 /* N1,N2,N3,N4 = Indexes of the four nodes defining the */ 14226 /* quadrilateral with N1 adjacent to N2, */ 14227 /* and (N1,N2,N3) in counterclockwise */ 14228 /* order. The arc connecting N1 to N2 */ 14229 /* should be replaced by an arc connec- */ 14230 /* ting N3 to N4 if SWPTST = TRUE. Refer */ 14231 /* to Subroutine SWAP. */ 14232 14233 /* X,Y,Z = Arrays of length N containing the Cartesian */ 14234 /* coordinates of the nodes. (X(I),Y(I),Z(I)) */ 14235 /* define node I for I = N1, N2, N3, and N4. */ 14236 14237 /* Input parameters are not altered by this routine. */ 14238 14239 /* On output: */ 14240 14241 /* SWPTST = TRUE if and only if the arc connecting N1 */ 14242 /* and N2 should be swapped for an arc con- */ 14243 /* necting N3 and N4. */ 14244 14245 /* Modules required by SWPTST: None */ 14246 14247 /* *********************************************************** */ 14248 14249 14250 /* Local parameters: */ 14251 14252 /* DX1,DY1,DZ1 = Coordinates of N4->N1 */ 14253 /* DX2,DY2,DZ2 = Coordinates of N4->N2 */ 14254 /* DX3,DY3,DZ3 = Coordinates of N4->N3 */ 14255 /* X4,Y4,Z4 = Coordinates of N4 */ 14256 14257 /* Parameter adjustments */ 14258 --z__; 14259 --y; 14260 --x; 14261 14262 /* Function Body */ 14263 x4 = x[*n4]; 14264 y4 = y[*n4]; 14265 z4 = z__[*n4]; 14266 dx1 = x[*n1] - x4; 14267 dx2 = x[*n2] - x4; 14268 dx3 = x[*n3] - x4; 14269 dy1 = y[*n1] - y4; 14270 dy2 = y[*n2] - y4; 14271 dy3 = y[*n3] - y4; 14272 dz1 = z__[*n1] - z4; 14273 dz2 = z__[*n2] - z4; 14274 dz3 = z__[*n3] - z4; 14275 14276 /* N4 lies above the plane of (N1,N2,N3) iff N3 lies above */ 14277 /* the plane of (N2,N1,N4) iff Det(N3-N4,N2-N4,N1-N4) = */ 14278 /* (N3-N4,N2-N4 X N1-N4) > 0. */ 14279 14280 ret_val = dx3 * (dy2 * dz1 - dy1 * dz2) - dy3 * (dx2 * dz1 - dx1 * dz2) + 14281 dz3 * (dx2 * dy1 - dx1 * dy2) > 0.; 14282 return ret_val; 14283 } /* swptst_ */
int trans_ | ( | int * | n, | |
double * | rlat, | |||
double * | rlon, | |||
double * | x, | |||
double * | y, | |||
double * | z__ | |||
) |
Definition at line 14285 of file util_sparx.cpp.
References nn(), phi, and theta.
14287 { 14288 /* System generated locals */ 14289 int i__1; 14290 14291 /* Builtin functions */ 14292 //double cos(double), sin(double); 14293 14294 /* Local variables */ 14295 static int i__, nn; 14296 static double phi, theta, cosphi; 14297 14298 14299 /* *********************************************************** */ 14300 14301 /* From STRIPACK */ 14302 /* Robert J. Renka */ 14303 /* Dept. of Computer Science */ 14304 /* Univ. of North Texas */ 14305 /* renka@cs.unt.edu */ 14306 /* 04/08/90 */ 14307 14308 /* This subroutine transforms spherical coordinates into */ 14309 /* Cartesian coordinates on the unit sphere for input to */ 14310 /* Subroutine TRMESH. Storage for X and Y may coincide with */ 14311 /* storage for RLAT and RLON if the latter need not be saved. */ 14312 14313 14314 /* On input: */ 14315 14316 /* N = Number of nodes (points on the unit sphere) */ 14317 /* whose coordinates are to be transformed. */ 14318 14319 /* RLAT = Array of length N containing latitudinal */ 14320 /* coordinates of the nodes in radians. */ 14321 14322 /* RLON = Array of length N containing longitudinal */ 14323 /* coordinates of the nodes in radians. */ 14324 14325 /* The above parameters are not altered by this routine. */ 14326 14327 /* X,Y,Z = Arrays of length at least N. */ 14328 14329 /* On output: */ 14330 14331 /* X,Y,Z = Cartesian coordinates in the range -1 to 1. */ 14332 /* X(I)**2 + Y(I)**2 + Z(I)**2 = 1 for I = 1 */ 14333 /* to N. */ 14334 14335 /* Modules required by TRANS: None */ 14336 14337 /* Intrinsic functions called by TRANS: COS, SIN */ 14338 14339 /* *********************************************************** */ 14340 14341 14342 /* Local parameters: */ 14343 14344 /* COSPHI = cos(PHI) */ 14345 /* I = DO-loop index */ 14346 /* NN = Local copy of N */ 14347 /* PHI = Latitude */ 14348 /* THETA = Longitude */ 14349 14350 /* Parameter adjustments */ 14351 --z__; 14352 --y; 14353 --x; 14354 --rlon; 14355 --rlat; 14356 14357 /* Function Body */ 14358 nn = *n; 14359 i__1 = nn; 14360 for (i__ = 1; i__ <= i__1; ++i__) { 14361 phi = rlat[i__]; 14362 theta = rlon[i__]; 14363 cosphi = cos(phi); 14364 x[i__] = cosphi * cos(theta); 14365 y[i__] = cosphi * sin(theta); 14366 z__[i__] = sin(phi); 14367 /* L1: */ 14368 } 14369 return 0; 14370 } /* trans_ */
int trfind_ | ( | int * | nst, | |
double * | p, | |||
int * | n, | |||
double * | x, | |||
double * | y, | |||
double * | z__, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
double * | b1, | |||
double * | b2, | |||
double * | b3, | |||
int * | i1, | |||
int * | i2, | |||
int * | i3 | |||
) |
Definition at line 14372 of file util_sparx.cpp.
References abs, jrand_(), lstptr_(), q, and store_().
Referenced by addnod_(), and nearnd_().
14376 { 14377 /* Initialized data */ 14378 14379 static int ix = 1; 14380 static int iy = 2; 14381 static int iz = 3; 14382 14383 /* System generated locals */ 14384 int i__1; 14385 double d__1, d__2; 14386 14387 /* Local variables */ 14388 static double q[3]; 14389 static int n0, n1, n2, n3, n4, nf; 14390 static double s12; 14391 static int nl, lp; 14392 static double xp, yp, zp; 14393 static int n1s, n2s; 14394 static double eps, tol, ptn1, ptn2; 14395 static int next; 14396 int jrand_(int *, int *, int *, int *); 14397 double store_(double *); 14398 int lstptr_(int *, int *, int *, int *); 14399 14400 14401 /* *********************************************************** */ 14402 14403 /* From STRIPACK */ 14404 /* Robert J. Renka */ 14405 /* Dept. of Computer Science */ 14406 /* Univ. of North Texas */ 14407 /* renka@cs.unt.edu */ 14408 /* 11/30/99 */ 14409 14410 /* This subroutine locates a point P relative to a triangu- */ 14411 /* lation created by Subroutine TRMESH. If P is contained in */ 14412 /* a triangle, the three vertex indexes and barycentric coor- */ 14413 /* dinates are returned. Otherwise, the indexes of the */ 14414 /* visible boundary nodes are returned. */ 14415 14416 14417 /* On input: */ 14418 14419 /* NST = Index of a node at which TRFIND begins its */ 14420 /* search. Search time depends on the proximity */ 14421 /* of this node to P. */ 14422 14423 /* P = Array of length 3 containing the x, y, and z */ 14424 /* coordinates (in that order) of the point P to be */ 14425 /* located. */ 14426 14427 /* N = Number of nodes in the triangulation. N .GE. 3. */ 14428 14429 /* X,Y,Z = Arrays of length N containing the Cartesian */ 14430 /* coordinates of the triangulation nodes (unit */ 14431 /* vectors). (X(I),Y(I),Z(I)) defines node I */ 14432 /* for I = 1 to N. */ 14433 14434 /* LIST,LPTR,LEND = Data structure defining the trian- */ 14435 /* gulation. Refer to Subroutine */ 14436 /* TRMESH. */ 14437 14438 /* Input parameters are not altered by this routine. */ 14439 14440 /* On output: */ 14441 14442 /* B1,B2,B3 = Unnormalized barycentric coordinates of */ 14443 /* the central projection of P onto the un- */ 14444 /* derlying planar triangle if P is in the */ 14445 /* convex hull of the nodes. These parame- */ 14446 /* ters are not altered if I1 = 0. */ 14447 14448 /* I1,I2,I3 = Counterclockwise-ordered vertex indexes */ 14449 /* of a triangle containing P if P is con- */ 14450 /* tained in a triangle. If P is not in the */ 14451 /* convex hull of the nodes, I1 and I2 are */ 14452 /* the rightmost and leftmost (boundary) */ 14453 /* nodes that are visible from P, and */ 14454 /* I3 = 0. (If all boundary nodes are vis- */ 14455 /* ible from P, then I1 and I2 coincide.) */ 14456 /* I1 = I2 = I3 = 0 if P and all of the */ 14457 /* nodes are coplanar (lie on a common great */ 14458 /* circle. */ 14459 14460 /* Modules required by TRFIND: JRAND, LSTPTR, STORE */ 14461 14462 /* Intrinsic function called by TRFIND: ABS */ 14463 14464 /* *********************************************************** */ 14465 14466 14467 /* Parameter adjustments */ 14468 --p; 14469 --lend; 14470 --z__; 14471 --y; 14472 --x; 14473 --list; 14474 --lptr; 14475 14476 /* Function Body */ 14477 14478 /* Local parameters: */ 14479 14480 /* EPS = Machine precision */ 14481 /* IX,IY,IZ = int seeds for JRAND */ 14482 /* LP = LIST pointer */ 14483 /* N0,N1,N2 = Nodes in counterclockwise order defining a */ 14484 /* cone (with vertex N0) containing P, or end- */ 14485 /* points of a boundary edge such that P Right */ 14486 /* N1->N2 */ 14487 /* N1S,N2S = Initially-determined values of N1 and N2 */ 14488 /* N3,N4 = Nodes opposite N1->N2 and N2->N1, respectively */ 14489 /* NEXT = Candidate for I1 or I2 when P is exterior */ 14490 /* NF,NL = First and last neighbors of N0, or first */ 14491 /* (rightmost) and last (leftmost) nodes */ 14492 /* visible from P when P is exterior to the */ 14493 /* triangulation */ 14494 /* PTN1 = Scalar product <P,N1> */ 14495 /* PTN2 = Scalar product <P,N2> */ 14496 /* Q = (N2 X N1) X N2 or N1 X (N2 X N1) -- used in */ 14497 /* the boundary traversal when P is exterior */ 14498 /* S12 = Scalar product <N1,N2> */ 14499 /* TOL = Tolerance (multiple of EPS) defining an upper */ 14500 /* bound on the magnitude of a negative bary- */ 14501 /* centric coordinate (B1 or B2) for P in a */ 14502 /* triangle -- used to avoid an infinite number */ 14503 /* of restarts with 0 <= B3 < EPS and B1 < 0 or */ 14504 /* B2 < 0 but small in magnitude */ 14505 /* XP,YP,ZP = Local variables containing P(1), P(2), and P(3) */ 14506 /* X0,Y0,Z0 = Dummy arguments for DET */ 14507 /* X1,Y1,Z1 = Dummy arguments for DET */ 14508 /* X2,Y2,Z2 = Dummy arguments for DET */ 14509 14510 /* Statement function: */ 14511 14512 /* DET(X1,...,Z0) .GE. 0 if and only if (X0,Y0,Z0) is in the */ 14513 /* (closed) left hemisphere defined by */ 14514 /* the plane containing (0,0,0), */ 14515 /* (X1,Y1,Z1), and (X2,Y2,Z2), where */ 14516 /* left is defined relative to an ob- */ 14517 /* server at (X1,Y1,Z1) facing */ 14518 /* (X2,Y2,Z2). */ 14519 14520 14521 /* Initialize variables. */ 14522 14523 xp = p[1]; 14524 yp = p[2]; 14525 zp = p[3]; 14526 n0 = *nst; 14527 if (n0 < 1 || n0 > *n) { 14528 n0 = jrand_(n, &ix, &iy, &iz); 14529 } 14530 14531 /* Compute the relative machine precision EPS and TOL. */ 14532 14533 eps = 1.; 14534 L1: 14535 eps /= 2.; 14536 d__1 = eps + 1.; 14537 if (store_(&d__1) > 1.) { 14538 goto L1; 14539 } 14540 eps *= 2.; 14541 tol = eps * 4.; 14542 14543 /* Set NF and NL to the first and last neighbors of N0, and */ 14544 /* initialize N1 = NF. */ 14545 14546 L2: 14547 lp = lend[n0]; 14548 nl = list[lp]; 14549 lp = lptr[lp]; 14550 nf = list[lp]; 14551 n1 = nf; 14552 14553 /* Find a pair of adjacent neighbors N1,N2 of N0 that define */ 14554 /* a wedge containing P: P LEFT N0->N1 and P RIGHT N0->N2. */ 14555 14556 if (nl > 0) { 14557 14558 /* N0 is an interior node. Find N1. */ 14559 14560 L3: 14561 if (xp * (y[n0] * z__[n1] - y[n1] * z__[n0]) - yp * (x[n0] * z__[n1] 14562 - x[n1] * z__[n0]) + zp * (x[n0] * y[n1] - x[n1] * y[n0]) < 14563 -1e-10) { 14564 lp = lptr[lp]; 14565 n1 = list[lp]; 14566 if (n1 == nl) { 14567 goto L6; 14568 } 14569 goto L3; 14570 } 14571 } else { 14572 14573 /* N0 is a boundary node. Test for P exterior. */ 14574 14575 nl = -nl; 14576 if (xp * (y[n0] * z__[nf] - y[nf] * z__[n0]) - yp * (x[n0] * z__[nf] 14577 - x[nf] * z__[n0]) + zp * (x[n0] * y[nf] - x[nf] * y[n0]) < 14578 -1e-10) { 14579 14580 /* P is to the right of the boundary edge N0->NF. */ 14581 14582 n1 = n0; 14583 n2 = nf; 14584 goto L9; 14585 } 14586 if (xp * (y[nl] * z__[n0] - y[n0] * z__[nl]) - yp * (x[nl] * z__[n0] 14587 - x[n0] * z__[nl]) + zp * (x[nl] * y[n0] - x[n0] * y[nl]) < 14588 -1e-10) { 14589 14590 /* P is to the right of the boundary edge NL->N0. */ 14591 14592 n1 = nl; 14593 n2 = n0; 14594 goto L9; 14595 } 14596 } 14597 14598 /* P is to the left of arcs N0->N1 and NL->N0. Set N2 to the */ 14599 /* next neighbor of N0 (following N1). */ 14600 14601 L4: 14602 lp = lptr[lp]; 14603 n2 = (i__1 = list[lp], abs(i__1)); 14604 if (xp * (y[n0] * z__[n2] - y[n2] * z__[n0]) - yp * (x[n0] * z__[n2] - x[ 14605 n2] * z__[n0]) + zp * (x[n0] * y[n2] - x[n2] * y[n0]) < -1e-10) { 14606 goto L7; 14607 } 14608 n1 = n2; 14609 if (n1 != nl) { 14610 goto L4; 14611 } 14612 if (xp * (y[n0] * z__[nf] - y[nf] * z__[n0]) - yp * (x[n0] * z__[nf] - x[ 14613 nf] * z__[n0]) + zp * (x[n0] * y[nf] - x[nf] * y[n0]) < -1e-10) { 14614 goto L6; 14615 } 14616 14617 /* P is left of or on arcs N0->NB for all neighbors NB */ 14618 /* of N0. Test for P = +/-N0. */ 14619 14620 d__2 = (d__1 = x[n0] * xp + y[n0] * yp + z__[n0] * zp, abs(d__1)); 14621 if (store_(&d__2) < 1. - eps * 4.) { 14622 14623 /* All points are collinear iff P Left NB->N0 for all */ 14624 /* neighbors NB of N0. Search the neighbors of N0. */ 14625 /* Note: N1 = NL and LP points to NL. */ 14626 14627 L5: 14628 if (xp * (y[n1] * z__[n0] - y[n0] * z__[n1]) - yp * (x[n1] * z__[n0] 14629 - x[n0] * z__[n1]) + zp * (x[n1] * y[n0] - x[n0] * y[n1]) > 14630 -1e-10) { 14631 lp = lptr[lp]; 14632 n1 = (i__1 = list[lp], abs(i__1)); 14633 if (n1 == nl) { 14634 goto L14; 14635 } 14636 goto L5; 14637 } 14638 } 14639 14640 /* P is to the right of N1->N0, or P = +/-N0. Set N0 to N1 */ 14641 /* and start over. */ 14642 14643 n0 = n1; 14644 goto L2; 14645 14646 /* P is between arcs N0->N1 and N0->NF. */ 14647 14648 L6: 14649 n2 = nf; 14650 14651 /* P is contained in a wedge defined by geodesics N0-N1 and */ 14652 /* N0-N2, where N1 is adjacent to N2. Save N1 and N2 to */ 14653 /* test for cycling. */ 14654 14655 L7: 14656 n3 = n0; 14657 n1s = n1; 14658 n2s = n2; 14659 14660 /* Top of edge-hopping loop: */ 14661 14662 L8: 14663 14664 *b3 = xp * (y[n1] * z__[n2] - y[n2] * z__[n1]) - yp * (x[n1] * z__[n2] - 14665 x[n2] * z__[n1]) + zp * (x[n1] * y[n2] - x[n2] * y[n1]); 14666 if (*b3 < -1e-10) { 14667 14668 /* Set N4 to the first neighbor of N2 following N1 (the */ 14669 /* node opposite N2->N1) unless N1->N2 is a boundary arc. */ 14670 14671 lp = lstptr_(&lend[n2], &n1, &list[1], &lptr[1]); 14672 if (list[lp] < 0) { 14673 goto L9; 14674 } 14675 lp = lptr[lp]; 14676 n4 = (i__1 = list[lp], abs(i__1)); 14677 14678 /* Define a new arc N1->N2 which intersects the geodesic */ 14679 /* N0-P. */ 14680 if (xp * (y[n0] * z__[n4] - y[n4] * z__[n0]) - yp * (x[n0] * z__[n4] 14681 - x[n4] * z__[n0]) + zp * (x[n0] * y[n4] - x[n4] * y[n0]) < 14682 -1e-10) { 14683 n3 = n2; 14684 n2 = n4; 14685 n1s = n1; 14686 if (n2 != n2s && n2 != n0) { 14687 goto L8; 14688 } 14689 } else { 14690 n3 = n1; 14691 n1 = n4; 14692 n2s = n2; 14693 if (n1 != n1s && n1 != n0) { 14694 goto L8; 14695 } 14696 } 14697 14698 /* The starting node N0 or edge N1-N2 was encountered */ 14699 /* again, implying a cycle (infinite loop). Restart */ 14700 /* with N0 randomly selected. */ 14701 14702 n0 = jrand_(n, &ix, &iy, &iz); 14703 goto L2; 14704 } 14705 14706 /* P is in (N1,N2,N3) unless N0, N1, N2, and P are collinear */ 14707 /* or P is close to -N0. */ 14708 14709 if (*b3 >= eps) { 14710 14711 /* B3 .NE. 0. */ 14712 14713 *b1 = xp * (y[n2] * z__[n3] - y[n3] * z__[n2]) - yp * (x[n2] * z__[n3] 14714 - x[n3] * z__[n2]) + zp * (x[n2] * y[n3] - x[n3] * y[n2]); 14715 *b2 = xp * (y[n3] * z__[n1] - y[n1] * z__[n3]) - yp * (x[n3] * z__[n1] 14716 - x[n1] * z__[n3]) + zp * (x[n3] * y[n1] - x[n1] * y[n3]); 14717 if (*b1 < -tol || *b2 < -tol) { 14718 14719 /* Restart with N0 randomly selected. */ 14720 14721 n0 = jrand_(n, &ix, &iy, &iz); 14722 goto L2; 14723 } 14724 } else { 14725 14726 /* B3 = 0 and thus P lies on N1->N2. Compute */ 14727 /* B1 = Det(P,N2 X N1,N2) and B2 = Det(P,N1,N2 X N1). */ 14728 14729 *b3 = 0.; 14730 s12 = x[n1] * x[n2] + y[n1] * y[n2] + z__[n1] * z__[n2]; 14731 ptn1 = xp * x[n1] + yp * y[n1] + zp * z__[n1]; 14732 ptn2 = xp * x[n2] + yp * y[n2] + zp * z__[n2]; 14733 *b1 = ptn1 - s12 * ptn2; 14734 *b2 = ptn2 - s12 * ptn1; 14735 if (*b1 < -tol || *b2 < -tol) { 14736 14737 /* Restart with N0 randomly selected. */ 14738 14739 n0 = jrand_(n, &ix, &iy, &iz); 14740 goto L2; 14741 } 14742 } 14743 14744 /* P is in (N1,N2,N3). */ 14745 14746 *i1 = n1; 14747 *i2 = n2; 14748 *i3 = n3; 14749 if (*b1 < 0.f) { 14750 *b1 = 0.f; 14751 } 14752 if (*b2 < 0.f) { 14753 *b2 = 0.f; 14754 } 14755 return 0; 14756 14757 /* P Right N1->N2, where N1->N2 is a boundary edge. */ 14758 /* Save N1 and N2, and set NL = 0 to indicate that */ 14759 /* NL has not yet been found. */ 14760 14761 L9: 14762 n1s = n1; 14763 n2s = n2; 14764 nl = 0; 14765 14766 /* Counterclockwise Boundary Traversal: */ 14767 14768 L10: 14769 14770 lp = lend[n2]; 14771 lp = lptr[lp]; 14772 next = list[lp]; 14773 if (xp * (y[n2] * z__[next] - y[next] * z__[n2]) - yp * (x[n2] * z__[next] 14774 - x[next] * z__[n2]) + zp * (x[n2] * y[next] - x[next] * y[n2]) 14775 >= -1e-10) { 14776 14777 /* N2 is the rightmost visible node if P Forward N2->N1 */ 14778 /* or NEXT Forward N2->N1. Set Q to (N2 X N1) X N2. */ 14779 14780 s12 = x[n1] * x[n2] + y[n1] * y[n2] + z__[n1] * z__[n2]; 14781 q[0] = x[n1] - s12 * x[n2]; 14782 q[1] = y[n1] - s12 * y[n2]; 14783 q[2] = z__[n1] - s12 * z__[n2]; 14784 if (xp * q[0] + yp * q[1] + zp * q[2] >= 0.) { 14785 goto L11; 14786 } 14787 if (x[next] * q[0] + y[next] * q[1] + z__[next] * q[2] >= 0.) { 14788 goto L11; 14789 } 14790 14791 /* N1, N2, NEXT, and P are nearly collinear, and N2 is */ 14792 /* the leftmost visible node. */ 14793 14794 nl = n2; 14795 } 14796 14797 /* Bottom of counterclockwise loop: */ 14798 14799 n1 = n2; 14800 n2 = next; 14801 if (n2 != n1s) { 14802 goto L10; 14803 } 14804 14805 /* All boundary nodes are visible from P. */ 14806 14807 *i1 = n1s; 14808 *i2 = n1s; 14809 *i3 = 0; 14810 return 0; 14811 14812 /* N2 is the rightmost visible node. */ 14813 14814 L11: 14815 nf = n2; 14816 if (nl == 0) { 14817 14818 /* Restore initial values of N1 and N2, and begin the search */ 14819 /* for the leftmost visible node. */ 14820 14821 n2 = n2s; 14822 n1 = n1s; 14823 14824 /* Clockwise Boundary Traversal: */ 14825 14826 L12: 14827 lp = lend[n1]; 14828 next = -list[lp]; 14829 if (xp * (y[next] * z__[n1] - y[n1] * z__[next]) - yp * (x[next] * 14830 z__[n1] - x[n1] * z__[next]) + zp * (x[next] * y[n1] - x[n1] * 14831 y[next]) >= -1e-10) { 14832 14833 /* N1 is the leftmost visible node if P or NEXT is */ 14834 /* forward of N1->N2. Compute Q = N1 X (N2 X N1). */ 14835 14836 s12 = x[n1] * x[n2] + y[n1] * y[n2] + z__[n1] * z__[n2]; 14837 q[0] = x[n2] - s12 * x[n1]; 14838 q[1] = y[n2] - s12 * y[n1]; 14839 q[2] = z__[n2] - s12 * z__[n1]; 14840 if (xp * q[0] + yp * q[1] + zp * q[2] >= 0.) { 14841 goto L13; 14842 } 14843 if (x[next] * q[0] + y[next] * q[1] + z__[next] * q[2] >= 0.) { 14844 goto L13; 14845 } 14846 14847 /* P, NEXT, N1, and N2 are nearly collinear and N1 is the */ 14848 /* rightmost visible node. */ 14849 14850 nf = n1; 14851 } 14852 14853 /* Bottom of clockwise loop: */ 14854 14855 n2 = n1; 14856 n1 = next; 14857 if (n1 != n1s) { 14858 goto L12; 14859 } 14860 14861 /* All boundary nodes are visible from P. */ 14862 14863 *i1 = n1; 14864 *i2 = n1; 14865 *i3 = 0; 14866 return 0; 14867 14868 /* N1 is the leftmost visible node. */ 14869 14870 L13: 14871 nl = n1; 14872 } 14873 14874 /* NF and NL have been found. */ 14875 14876 *i1 = nf; 14877 *i2 = nl; 14878 *i3 = 0; 14879 return 0; 14880 14881 /* All points are collinear (coplanar). */ 14882 14883 L14: 14884 *i1 = 0; 14885 *i2 = 0; 14886 *i3 = 0; 14887 return 0; 14888 } /* trfind_ */
int trlist_ | ( | int * | n, | |
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | nrow, | |||
int * | nt, | |||
int * | ltri, | |||
int * | ier | |||
) |
Definition at line 14890 of file util_sparx.cpp.
References abs.
14893 { 14894 /* System generated locals */ 14895 int ltri_dim1, ltri_offset, i__1, i__2; 14896 14897 /* Local variables */ 14898 static int i__, j, i1, i2, i3, n1, n2, n3, ka, kn, lp, kt, nm2, lp2, 14899 lpl, isv; 14900 static long int arcs; 14901 static int lpln1; 14902 14903 14904 /* *********************************************************** */ 14905 14906 /* From STRIPACK */ 14907 /* Robert J. Renka */ 14908 /* Dept. of Computer Science */ 14909 /* Univ. of North Texas */ 14910 /* renka@cs.unt.edu */ 14911 /* 07/20/96 */ 14912 14913 /* This subroutine converts a triangulation data structure */ 14914 /* from the linked list created by Subroutine TRMESH to a */ 14915 /* triangle list. */ 14916 14917 /* On input: */ 14918 14919 /* N = Number of nodes in the triangulation. N .GE. 3. */ 14920 14921 /* LIST,LPTR,LEND = Linked list data structure defin- */ 14922 /* ing the triangulation. Refer to */ 14923 /* Subroutine TRMESH. */ 14924 14925 /* NROW = Number of rows (entries per triangle) re- */ 14926 /* served for the triangle list LTRI. The value */ 14927 /* must be 6 if only the vertex indexes and */ 14928 /* neighboring triangle indexes are to be */ 14929 /* stored, or 9 if arc indexes are also to be */ 14930 /* assigned and stored. Refer to LTRI. */ 14931 14932 /* The above parameters are not altered by this routine. */ 14933 14934 /* LTRI = int array of length at least NROW*NT, */ 14935 /* where NT is at most 2N-4. (A sufficient */ 14936 /* length is 12N if NROW=6 or 18N if NROW=9.) */ 14937 14938 /* On output: */ 14939 14940 /* NT = Number of triangles in the triangulation unless */ 14941 /* IER .NE. 0, in which case NT = 0. NT = 2N-NB-2 */ 14942 /* if NB .GE. 3 or 2N-4 if NB = 0, where NB is the */ 14943 /* number of boundary nodes. */ 14944 14945 /* LTRI = NROW by NT array whose J-th column contains */ 14946 /* the vertex nodal indexes (first three rows), */ 14947 /* neighboring triangle indexes (second three */ 14948 /* rows), and, if NROW = 9, arc indexes (last */ 14949 /* three rows) associated with triangle J for */ 14950 /* J = 1,...,NT. The vertices are ordered */ 14951 /* counterclockwise with the first vertex taken */ 14952 /* to be the one with smallest index. Thus, */ 14953 /* LTRI(2,J) and LTRI(3,J) are larger than */ 14954 /* LTRI(1,J) and index adjacent neighbors of */ 14955 /* node LTRI(1,J). For I = 1,2,3, LTRI(I+3,J) */ 14956 /* and LTRI(I+6,J) index the triangle and arc, */ 14957 /* respectively, which are opposite (not shared */ 14958 /* by) node LTRI(I,J), with LTRI(I+3,J) = 0 if */ 14959 /* LTRI(I+6,J) indexes a boundary arc. Vertex */ 14960 /* indexes range from 1 to N, triangle indexes */ 14961 /* from 0 to NT, and, if included, arc indexes */ 14962 /* from 1 to NA, where NA = 3N-NB-3 if NB .GE. 3 */ 14963 /* or 3N-6 if NB = 0. The triangles are or- */ 14964 /* dered on first (smallest) vertex indexes. */ 14965 14966 /* IER = Error indicator. */ 14967 /* IER = 0 if no errors were encountered. */ 14968 /* IER = 1 if N or NROW is outside its valid */ 14969 /* range on input. */ 14970 /* IER = 2 if the triangulation data structure */ 14971 /* (LIST,LPTR,LEND) is invalid. Note, */ 14972 /* however, that these arrays are not */ 14973 /* completely tested for validity. */ 14974 14975 /* Modules required by TRLIST: None */ 14976 14977 /* Intrinsic function called by TRLIST: ABS */ 14978 14979 /* *********************************************************** */ 14980 14981 14982 /* Local parameters: */ 14983 14984 /* ARCS = long int variable with value TRUE iff are */ 14985 /* indexes are to be stored */ 14986 /* I,J = LTRI row indexes (1 to 3) associated with */ 14987 /* triangles KT and KN, respectively */ 14988 /* I1,I2,I3 = Nodal indexes of triangle KN */ 14989 /* ISV = Variable used to permute indexes I1,I2,I3 */ 14990 /* KA = Arc index and number of currently stored arcs */ 14991 /* KN = Index of the triangle that shares arc I1-I2 */ 14992 /* with KT */ 14993 /* KT = Triangle index and number of currently stored */ 14994 /* triangles */ 14995 /* LP = LIST pointer */ 14996 /* LP2 = Pointer to N2 as a neighbor of N1 */ 14997 /* LPL = Pointer to the last neighbor of I1 */ 14998 /* LPLN1 = Pointer to the last neighbor of N1 */ 14999 /* N1,N2,N3 = Nodal indexes of triangle KT */ 15000 /* NM2 = N-2 */ 15001 15002 15003 /* Test for invalid input parameters. */ 15004 15005 /* Parameter adjustments */ 15006 --lend; 15007 --list; 15008 --lptr; 15009 ltri_dim1 = *nrow; 15010 ltri_offset = 1 + ltri_dim1; 15011 ltri -= ltri_offset; 15012 15013 /* Function Body */ 15014 if (*n < 3 || (*nrow != 6 && *nrow != 9)) { 15015 goto L11; 15016 } 15017 15018 /* Initialize parameters for loop on triangles KT = (N1,N2, */ 15019 /* N3), where N1 < N2 and N1 < N3. */ 15020 15021 /* ARCS = TRUE iff arc indexes are to be stored. */ 15022 /* KA,KT = Numbers of currently stored arcs and triangles. */ 15023 /* NM2 = Upper bound on candidates for N1. */ 15024 15025 arcs = *nrow == 9; 15026 ka = 0; 15027 kt = 0; 15028 nm2 = *n - 2; 15029 15030 /* Loop on nodes N1. */ 15031 15032 i__1 = nm2; 15033 for (n1 = 1; n1 <= i__1; ++n1) { 15034 15035 /* Loop on pairs of adjacent neighbors (N2,N3). LPLN1 points */ 15036 /* to the last neighbor of N1, and LP2 points to N2. */ 15037 15038 lpln1 = lend[n1]; 15039 lp2 = lpln1; 15040 L1: 15041 lp2 = lptr[lp2]; 15042 n2 = list[lp2]; 15043 lp = lptr[lp2]; 15044 n3 = (i__2 = list[lp], abs(i__2)); 15045 if (n2 < n1 || n3 < n1) { 15046 goto L8; 15047 } 15048 15049 /* Add a new triangle KT = (N1,N2,N3). */ 15050 15051 ++kt; 15052 ltri[kt * ltri_dim1 + 1] = n1; 15053 ltri[kt * ltri_dim1 + 2] = n2; 15054 ltri[kt * ltri_dim1 + 3] = n3; 15055 15056 /* Loop on triangle sides (I2,I1) with neighboring triangles */ 15057 /* KN = (I1,I2,I3). */ 15058 15059 for (i__ = 1; i__ <= 3; ++i__) { 15060 if (i__ == 1) { 15061 i1 = n3; 15062 i2 = n2; 15063 } else if (i__ == 2) { 15064 i1 = n1; 15065 i2 = n3; 15066 } else { 15067 i1 = n2; 15068 i2 = n1; 15069 } 15070 15071 /* Set I3 to the neighbor of I1 that follows I2 unless */ 15072 /* I2->I1 is a boundary arc. */ 15073 15074 lpl = lend[i1]; 15075 lp = lptr[lpl]; 15076 L2: 15077 if (list[lp] == i2) { 15078 goto L3; 15079 } 15080 lp = lptr[lp]; 15081 if (lp != lpl) { 15082 goto L2; 15083 } 15084 15085 /* I2 is the last neighbor of I1 unless the data structure */ 15086 /* is invalid. Bypass the search for a neighboring */ 15087 /* triangle if I2->I1 is a boundary arc. */ 15088 15089 if ((i__2 = list[lp], abs(i__2)) != i2) { 15090 goto L12; 15091 } 15092 kn = 0; 15093 if (list[lp] < 0) { 15094 goto L6; 15095 } 15096 15097 /* I2->I1 is not a boundary arc, and LP points to I2 as */ 15098 /* a neighbor of I1. */ 15099 15100 L3: 15101 lp = lptr[lp]; 15102 i3 = (i__2 = list[lp], abs(i__2)); 15103 15104 /* Find J such that LTRI(J,KN) = I3 (not used if KN > KT), */ 15105 /* and permute the vertex indexes of KN so that I1 is */ 15106 /* smallest. */ 15107 15108 if (i1 < i2 && i1 < i3) { 15109 j = 3; 15110 } else if (i2 < i3) { 15111 j = 2; 15112 isv = i1; 15113 i1 = i2; 15114 i2 = i3; 15115 i3 = isv; 15116 } else { 15117 j = 1; 15118 isv = i1; 15119 i1 = i3; 15120 i3 = i2; 15121 i2 = isv; 15122 } 15123 15124 /* Test for KN > KT (triangle index not yet assigned). */ 15125 15126 if (i1 > n1) { 15127 goto L7; 15128 } 15129 15130 /* Find KN, if it exists, by searching the triangle list in */ 15131 /* reverse order. */ 15132 15133 for (kn = kt - 1; kn >= 1; --kn) { 15134 if (ltri[kn * ltri_dim1 + 1] == i1 && ltri[kn * ltri_dim1 + 2] 15135 == i2 && ltri[kn * ltri_dim1 + 3] == i3) { 15136 goto L5; 15137 } 15138 /* L4: */ 15139 } 15140 goto L7; 15141 15142 /* Store KT as a neighbor of KN. */ 15143 15144 L5: 15145 ltri[j + 3 + kn * ltri_dim1] = kt; 15146 15147 /* Store KN as a neighbor of KT, and add a new arc KA. */ 15148 15149 L6: 15150 ltri[i__ + 3 + kt * ltri_dim1] = kn; 15151 if (arcs) { 15152 ++ka; 15153 ltri[i__ + 6 + kt * ltri_dim1] = ka; 15154 if (kn != 0) { 15155 ltri[j + 6 + kn * ltri_dim1] = ka; 15156 } 15157 } 15158 L7: 15159 ; 15160 } 15161 15162 /* Bottom of loop on triangles. */ 15163 15164 L8: 15165 if (lp2 != lpln1) { 15166 goto L1; 15167 } 15168 /* L9: */ 15169 } 15170 15171 /* No errors encountered. */ 15172 15173 *nt = kt; 15174 *ier = 0; 15175 return 0; 15176 15177 /* Invalid input parameter. */ 15178 15179 L11: 15180 *nt = 0; 15181 *ier = 1; 15182 return 0; 15183 15184 /* Invalid triangulation data structure: I1 is a neighbor of */ 15185 /* I2, but I2 is not a neighbor of I1. */ 15186 15187 L12: 15188 *nt = 0; 15189 *ier = 2; 15190 return 0; 15191 } /* trlist_ */
int trlprt_ | ( | int * | n, | |
double * | x, | |||
double * | y, | |||
double * | z__, | |||
int * | iflag, | |||
int * | nrow, | |||
int * | nt, | |||
int * | ltri, | |||
int * | lout | |||
) |
Definition at line 15193 of file util_sparx.cpp.
15196 { 15197 /* Initialized data */ 15198 15199 static int nmax = 9999; 15200 static int nlmax = 58; 15201 15202 /* System generated locals */ 15203 int ltri_dim1, ltri_offset, i__1; 15204 15205 /* Local variables */ 15206 static int i__, k, na, nb, nl, lun; 15207 15208 15209 /* *********************************************************** */ 15210 15211 /* From STRIPACK */ 15212 /* Robert J. Renka */ 15213 /* Dept. of Computer Science */ 15214 /* Univ. of North Texas */ 15215 /* renka@cs.unt.edu */ 15216 /* 07/02/98 */ 15217 15218 /* This subroutine prints the triangle list created by Sub- */ 15219 /* routine TRLIST and, optionally, the nodal coordinates */ 15220 /* (either latitude and longitude or Cartesian coordinates) */ 15221 /* on long int unit LOUT. The numbers of boundary nodes, */ 15222 /* triangles, and arcs are also printed. */ 15223 15224 15225 /* On input: */ 15226 15227 /* N = Number of nodes in the triangulation. */ 15228 /* 3 .LE. N .LE. 9999. */ 15229 15230 /* X,Y,Z = Arrays of length N containing the Cartesian */ 15231 /* coordinates of the nodes if IFLAG = 0, or */ 15232 /* (X and Y only) arrays of length N containing */ 15233 /* longitude and latitude, respectively, if */ 15234 /* IFLAG > 0, or unused dummy parameters if */ 15235 /* IFLAG < 0. */ 15236 15237 /* IFLAG = Nodal coordinate option indicator: */ 15238 /* IFLAG = 0 if X, Y, and Z (assumed to contain */ 15239 /* Cartesian coordinates) are to be */ 15240 /* printed (to 6 decimal places). */ 15241 /* IFLAG > 0 if only X and Y (assumed to con- */ 15242 /* tain longitude and latitude) are */ 15243 /* to be printed (to 6 decimal */ 15244 /* places). */ 15245 /* IFLAG < 0 if only the adjacency lists are to */ 15246 /* be printed. */ 15247 15248 /* NROW = Number of rows (entries per triangle) re- */ 15249 /* served for the triangle list LTRI. The value */ 15250 /* must be 6 if only the vertex indexes and */ 15251 /* neighboring triangle indexes are stored, or 9 */ 15252 /* if arc indexes are also stored. */ 15253 15254 /* NT = Number of triangles in the triangulation. */ 15255 /* 1 .LE. NT .LE. 9999. */ 15256 15257 /* LTRI = NROW by NT array whose J-th column contains */ 15258 /* the vertex nodal indexes (first three rows), */ 15259 /* neighboring triangle indexes (second three */ 15260 /* rows), and, if NROW = 9, arc indexes (last */ 15261 /* three rows) associated with triangle J for */ 15262 /* J = 1,...,NT. */ 15263 15264 /* LOUT = long int unit number for output. If LOUT is */ 15265 /* not in the range 0 to 99, output is written */ 15266 /* to unit 6. */ 15267 15268 /* Input parameters are not altered by this routine. */ 15269 15270 /* On output: */ 15271 15272 /* The triangle list and nodal coordinates (as specified by */ 15273 /* IFLAG) are written to unit LOUT. */ 15274 15275 /* Modules required by TRLPRT: None */ 15276 15277 /* *********************************************************** */ 15278 15279 /* Parameter adjustments */ 15280 --z__; 15281 --y; 15282 --x; 15283 ltri_dim1 = *nrow; 15284 ltri_offset = 1 + ltri_dim1; 15285 ltri -= ltri_offset; 15286 15287 /* Function Body */ 15288 15289 /* Local parameters: */ 15290 15291 /* I = DO-loop, nodal index, and row index for LTRI */ 15292 /* K = DO-loop and triangle index */ 15293 /* LUN = long int unit number for output */ 15294 /* NA = Number of triangulation arcs */ 15295 /* NB = Number of boundary nodes */ 15296 /* NL = Number of lines printed on the current page */ 15297 /* NLMAX = Maximum number of print lines per page (except */ 15298 /* for the last page which may have two addi- */ 15299 /* tional lines) */ 15300 /* NMAX = Maximum value of N and NT (4-digit format) */ 15301 15302 lun = *lout; 15303 if (lun < 0 || lun > 99) { 15304 lun = 6; 15305 } 15306 15307 /* Print a heading and test for invalid input. */ 15308 15309 /* WRITE (LUN,100) N */ 15310 nl = 3; 15311 if (*n < 3 || *n > nmax || (*nrow != 6 && *nrow != 9) || *nt < 1 || *nt > 15312 nmax) { 15313 15314 /* Print an error message and exit. */ 15315 15316 /* WRITE (LUN,110) N, NROW, NT */ 15317 return 0; 15318 } 15319 if (*iflag == 0) { 15320 15321 /* Print X, Y, and Z. */ 15322 15323 /* WRITE (LUN,101) */ 15324 nl = 6; 15325 i__1 = *n; 15326 for (i__ = 1; i__ <= i__1; ++i__) { 15327 if (nl >= nlmax) { 15328 /* WRITE (LUN,108) */ 15329 nl = 0; 15330 } 15331 /* WRITE (LUN,103) I, X(I), Y(I), Z(I) */ 15332 ++nl; 15333 /* L1: */ 15334 } 15335 } else if (*iflag > 0) { 15336 15337 /* Print X (longitude) and Y (latitude). */ 15338 15339 /* WRITE (LUN,102) */ 15340 nl = 6; 15341 i__1 = *n; 15342 for (i__ = 1; i__ <= i__1; ++i__) { 15343 if (nl >= nlmax) { 15344 /* WRITE (LUN,108) */ 15345 nl = 0; 15346 } 15347 /* WRITE (LUN,104) I, X(I), Y(I) */ 15348 ++nl; 15349 /* L2: */ 15350 } 15351 } 15352 15353 /* Print the triangulation LTRI. */ 15354 15355 if (nl > nlmax / 2) { 15356 /* WRITE (LUN,108) */ 15357 nl = 0; 15358 } 15359 if (*nrow == 6) { 15360 /* WRITE (LUN,105) */ 15361 } else { 15362 /* WRITE (LUN,106) */ 15363 } 15364 nl += 5; 15365 i__1 = *nt; 15366 for (k = 1; k <= i__1; ++k) { 15367 if (nl >= nlmax) { 15368 /* WRITE (LUN,108) */ 15369 nl = 0; 15370 } 15371 /* WRITE (LUN,107) K, (LTRI(I,K), I = 1,NROW) */ 15372 ++nl; 15373 /* L3: */ 15374 } 15375 15376 /* Print NB, NA, and NT (boundary nodes, arcs, and */ 15377 /* triangles). */ 15378 15379 nb = (*n << 1) - *nt - 2; 15380 if (nb < 3) { 15381 nb = 0; 15382 na = *n * 3 - 6; 15383 } else { 15384 na = *nt + *n - 1; 15385 } 15386 /* WRITE (LUN,109) NB, NA, NT */ 15387 return 0; 15388 15389 /* Print formats: */ 15390 15391 /* 100 FORMAT (///18X,'STRIPACK (TRLIST) Output, N = ',I4) */ 15392 /* 101 FORMAT (//8X,'Node',10X,'X(Node)',10X,'Y(Node)',10X, */ 15393 /* . 'Z(Node)'//) */ 15394 /* 102 FORMAT (//16X,'Node',8X,'Longitude',9X,'Latitude'//) */ 15395 /* 103 FORMAT (8X,I4,3D17.6) */ 15396 /* 104 FORMAT (16X,I4,2D17.6) */ 15397 /* 105 FORMAT (//1X,'Triangle',8X,'Vertices',12X,'Neighbors'/ */ 15398 /* . 4X,'KT',7X,'N1',5X,'N2',5X,'N3',4X,'KT1',4X, */ 15399 /* . 'KT2',4X,'KT3'/) */ 15400 /* 106 FORMAT (//1X,'Triangle',8X,'Vertices',12X,'Neighbors', */ 15401 /* . 14X,'Arcs'/ */ 15402 /* . 4X,'KT',7X,'N1',5X,'N2',5X,'N3',4X,'KT1',4X, */ 15403 /* . 'KT2',4X,'KT3',4X,'KA1',4X,'KA2',4X,'KA3'/) */ 15404 /* 107 FORMAT (2X,I4,2X,6(3X,I4),3(2X,I5)) */ 15405 /* 108 FORMAT (///) */ 15406 /* 109 FORMAT (/1X,'NB = ',I4,' Boundary Nodes',5X, */ 15407 /* . 'NA = ',I5,' Arcs',5X,'NT = ',I5, */ 15408 /* . ' Triangles') */ 15409 /* 110 FORMAT (//1X,10X,'*** Invalid Parameter: N =',I5, */ 15410 /* . ', NROW =',I5,', NT =',I5,' ***') */ 15411 } /* trlprt_ */
int trmesh_ | ( | int * | n, | |
double * | x, | |||
double * | y, | |||
double * | z__, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | lnew, | |||
int * | near__, | |||
int * | next, | |||
double * | dist, | |||
int * | ier | |||
) |
Definition at line 15413 of file util_sparx.cpp.
References abs, addnod_(), left_(), and nn().
15416 { 15417 /* System generated locals */ 15418 int i__1, i__2; 15419 15420 /* Local variables */ 15421 static double d__; 15422 static int i__, j, k; 15423 static double d1, d2, d3; 15424 static int i0, lp, nn, lpl; 15425 long int left_(double *, double *, double *, double 15426 *, double *, double *, double *, double *, 15427 double *); 15428 static int nexti; 15429 15430 15431 /* *********************************************************** */ 15432 15433 /* From STRIPACK */ 15434 /* Robert J. Renka */ 15435 /* Dept. of Computer Science */ 15436 /* Univ. of North Texas */ 15437 /* renka@cs.unt.edu */ 15438 /* 03/04/03 */ 15439 15440 /* This subroutine creates a Delaunay triangulation of a */ 15441 /* set of N arbitrarily distributed points, referred to as */ 15442 /* nodes, on the surface of the unit sphere. The Delaunay */ 15443 /* triangulation is defined as a set of (spherical) triangles */ 15444 /* with the following five properties: */ 15445 15446 /* 1) The triangle vertices are nodes. */ 15447 /* 2) No triangle contains a node other than its vertices. */ 15448 /* 3) The interiors of the triangles are pairwise disjoint. */ 15449 /* 4) The union of triangles is the convex hull of the set */ 15450 /* of nodes (the smallest convex set that contains */ 15451 /* the nodes). If the nodes are not contained in a */ 15452 /* single hemisphere, their convex hull is the en- */ 15453 /* tire sphere and there are no boundary nodes. */ 15454 /* Otherwise, there are at least three boundary nodes. */ 15455 /* 5) The interior of the circumcircle of each triangle */ 15456 /* contains no node. */ 15457 15458 /* The first four properties define a triangulation, and the */ 15459 /* last property results in a triangulation which is as close */ 15460 /* as possible to equiangular in a certain sense and which is */ 15461 /* uniquely defined unless four or more nodes lie in a common */ 15462 /* plane. This property makes the triangulation well-suited */ 15463 /* for solving closest-point problems and for triangle-based */ 15464 /* interpolation. */ 15465 15466 /* The algorithm has expected time complexity O(N*log(N)) */ 15467 /* for most nodal distributions. */ 15468 15469 /* Spherical coordinates (latitude and longitude) may be */ 15470 /* converted to Cartesian coordinates by Subroutine TRANS. */ 15471 15472 /* The following is a list of the software package modules */ 15473 /* which a user may wish to call directly: */ 15474 15475 /* ADDNOD - Updates the triangulation by appending a new */ 15476 /* node. */ 15477 15478 /* AREAS - Returns the area of a spherical triangle. */ 15479 15480 /* AREAV - Returns the area of a Voronoi region associated */ 15481 /* with an interior node without requiring that the */ 15482 /* entire Voronoi diagram be computed and stored. */ 15483 15484 /* BNODES - Returns an array containing the indexes of the */ 15485 /* boundary nodes (if any) in counterclockwise */ 15486 /* order. Counts of boundary nodes, triangles, */ 15487 /* and arcs are also returned. */ 15488 15489 /* CIRCLE - Computes the coordinates of a sequence of uni- */ 15490 /* formly spaced points on the unit circle centered */ 15491 /* at (0,0). */ 15492 15493 /* CIRCUM - Returns the circumcenter of a spherical trian- */ 15494 /* gle. */ 15495 15496 /* CRLIST - Returns the set of triangle circumcenters */ 15497 /* (Voronoi vertices) and circumradii associated */ 15498 /* with a triangulation. */ 15499 15500 /* DELARC - Deletes a boundary arc from a triangulation. */ 15501 15502 /* DELNOD - Updates the triangulation with a nodal deletion. */ 15503 15504 /* EDGE - Forces an arbitrary pair of nodes to be connec- */ 15505 /* ted by an arc in the triangulation. */ 15506 15507 /* GETNP - Determines the ordered sequence of L closest */ 15508 /* nodes to a given node, along with the associ- */ 15509 /* ated distances. */ 15510 15511 /* INSIDE - Locates a point relative to a polygon on the */ 15512 /* surface of the sphere. */ 15513 15514 /* INTRSC - Returns the point of intersection between a */ 15515 /* pair of great circle arcs. */ 15516 15517 /* JRAND - Generates a uniformly distributed pseudo-random */ 15518 /* int. */ 15519 15520 /* LEFT - Locates a point relative to a great circle. */ 15521 15522 /* NEARND - Returns the index of the nearest node to an */ 15523 /* arbitrary point, along with its squared */ 15524 /* distance. */ 15525 15526 /* PROJCT - Applies a perspective-depth projection to a */ 15527 /* point in 3-space. */ 15528 15529 /* SCOORD - Converts a point from Cartesian coordinates to */ 15530 /* spherical coordinates. */ 15531 15532 /* STORE - Forces a value to be stored in main memory so */ 15533 /* that the precision of floating point numbers */ 15534 /* in memory locations rather than registers is */ 15535 /* computed. */ 15536 15537 /* TRANS - Transforms spherical coordinates into Cartesian */ 15538 /* coordinates on the unit sphere for input to */ 15539 /* Subroutine TRMESH. */ 15540 15541 /* TRLIST - Converts the triangulation data structure to a */ 15542 /* triangle list more suitable for use in a fin- */ 15543 /* ite element code. */ 15544 15545 /* TRLPRT - Prints the triangle list created by Subroutine */ 15546 /* TRLIST. */ 15547 15548 /* TRMESH - Creates a Delaunay triangulation of a set of */ 15549 /* nodes. */ 15550 15551 /* TRPLOT - Creates a level-2 Encapsulated Postscript (EPS) */ 15552 /* file containing a triangulation plot. */ 15553 15554 /* TRPRNT - Prints the triangulation data structure and, */ 15555 /* optionally, the nodal coordinates. */ 15556 15557 /* VRPLOT - Creates a level-2 Encapsulated Postscript (EPS) */ 15558 /* file containing a Voronoi diagram plot. */ 15559 15560 15561 /* On input: */ 15562 15563 /* N = Number of nodes in the triangulation. N .GE. 3. */ 15564 15565 /* X,Y,Z = Arrays of length N containing the Cartesian */ 15566 /* coordinates of distinct nodes. (X(K),Y(K), */ 15567 /* Z(K)) is referred to as node K, and K is re- */ 15568 /* ferred to as a nodal index. It is required */ 15569 /* that X(K)**2 + Y(K)**2 + Z(K)**2 = 1 for all */ 15570 /* K. The first three nodes must not be col- */ 15571 /* linear (lie on a common great circle). */ 15572 15573 /* The above parameters are not altered by this routine. */ 15574 15575 /* LIST,LPTR = Arrays of length at least 6N-12. */ 15576 15577 /* LEND = Array of length at least N. */ 15578 15579 /* NEAR,NEXT,DIST = Work space arrays of length at */ 15580 /* least N. The space is used to */ 15581 /* efficiently determine the nearest */ 15582 /* triangulation node to each un- */ 15583 /* processed node for use by ADDNOD. */ 15584 15585 /* On output: */ 15586 15587 /* LIST = Set of nodal indexes which, along with LPTR, */ 15588 /* LEND, and LNEW, define the triangulation as a */ 15589 /* set of N adjacency lists -- counterclockwise- */ 15590 /* ordered sequences of neighboring nodes such */ 15591 /* that the first and last neighbors of a bound- */ 15592 /* ary node are boundary nodes (the first neigh- */ 15593 /* bor of an interior node is arbitrary). In */ 15594 /* order to distinguish between interior and */ 15595 /* boundary nodes, the last neighbor of each */ 15596 /* boundary node is represented by the negative */ 15597 /* of its index. */ 15598 15599 /* LPTR = Set of pointers (LIST indexes) in one-to-one */ 15600 /* correspondence with the elements of LIST. */ 15601 /* LIST(LPTR(I)) indexes the node which follows */ 15602 /* LIST(I) in cyclical counterclockwise order */ 15603 /* (the first neighbor follows the last neigh- */ 15604 /* bor). */ 15605 15606 /* LEND = Set of pointers to adjacency lists. LEND(K) */ 15607 /* points to the last neighbor of node K for */ 15608 /* K = 1,...,N. Thus, LIST(LEND(K)) < 0 if and */ 15609 /* only if K is a boundary node. */ 15610 15611 /* LNEW = Pointer to the first empty location in LIST */ 15612 /* and LPTR (list length plus one). LIST, LPTR, */ 15613 /* LEND, and LNEW are not altered if IER < 0, */ 15614 /* and are incomplete if IER > 0. */ 15615 15616 /* NEAR,NEXT,DIST = Garbage. */ 15617 15618 /* IER = Error indicator: */ 15619 /* IER = 0 if no errors were encountered. */ 15620 /* IER = -1 if N < 3 on input. */ 15621 /* IER = -2 if the first three nodes are */ 15622 /* collinear. */ 15623 /* IER = L if nodes L and M coincide for some */ 15624 /* M > L. The data structure represents */ 15625 /* a triangulation of nodes 1 to M-1 in */ 15626 /* this case. */ 15627 15628 /* Modules required by TRMESH: ADDNOD, BDYADD, COVSPH, */ 15629 /* INSERT, INTADD, JRAND, */ 15630 /* LEFT, LSTPTR, STORE, SWAP, */ 15631 /* SWPTST, TRFIND */ 15632 15633 /* Intrinsic function called by TRMESH: ABS */ 15634 15635 /* *********************************************************** */ 15636 15637 15638 /* Local parameters: */ 15639 15640 /* D = (Negative cosine of) distance from node K to */ 15641 /* node I */ 15642 /* D1,D2,D3 = Distances from node K to nodes 1, 2, and 3, */ 15643 /* respectively */ 15644 /* I,J = Nodal indexes */ 15645 /* I0 = Index of the node preceding I in a sequence of */ 15646 /* unprocessed nodes: I = NEXT(I0) */ 15647 /* K = Index of node to be added and DO-loop index: */ 15648 /* K > 3 */ 15649 /* LP = LIST index (pointer) of a neighbor of K */ 15650 /* LPL = Pointer to the last neighbor of K */ 15651 /* NEXTI = NEXT(I) */ 15652 /* NN = Local copy of N */ 15653 15654 /* Parameter adjustments */ 15655 --dist; 15656 --next; 15657 --near__; 15658 --lend; 15659 --z__; 15660 --y; 15661 --x; 15662 --list; 15663 --lptr; 15664 15665 /* Function Body */ 15666 nn = *n; 15667 if (nn < 3) { 15668 *ier = -1; 15669 return 0; 15670 } 15671 15672 /* Store the first triangle in the linked list. */ 15673 15674 if (! left_(&x[1], &y[1], &z__[1], &x[2], &y[2], &z__[2], &x[3], &y[3], & 15675 z__[3])) { 15676 15677 /* The first triangle is (3,2,1) = (2,1,3) = (1,3,2). */ 15678 15679 list[1] = 3; 15680 lptr[1] = 2; 15681 list[2] = -2; 15682 lptr[2] = 1; 15683 lend[1] = 2; 15684 15685 list[3] = 1; 15686 lptr[3] = 4; 15687 list[4] = -3; 15688 lptr[4] = 3; 15689 lend[2] = 4; 15690 15691 list[5] = 2; 15692 lptr[5] = 6; 15693 list[6] = -1; 15694 lptr[6] = 5; 15695 lend[3] = 6; 15696 15697 } else if (! left_(&x[2], &y[2], &z__[2], &x[1], &y[1], &z__[1], &x[3], & 15698 y[3], &z__[3])) { 15699 15700 /* The first triangle is (1,2,3): 3 Strictly Left 1->2, */ 15701 /* i.e., node 3 lies in the left hemisphere defined by */ 15702 /* arc 1->2. */ 15703 15704 list[1] = 2; 15705 lptr[1] = 2; 15706 list[2] = -3; 15707 lptr[2] = 1; 15708 lend[1] = 2; 15709 15710 list[3] = 3; 15711 lptr[3] = 4; 15712 list[4] = -1; 15713 lptr[4] = 3; 15714 lend[2] = 4; 15715 15716 list[5] = 1; 15717 lptr[5] = 6; 15718 list[6] = -2; 15719 lptr[6] = 5; 15720 lend[3] = 6; 15721 15722 } else { 15723 15724 /* The first three nodes are collinear. */ 15725 15726 *ier = -2; 15727 return 0; 15728 } 15729 15730 /* Initialize LNEW and test for N = 3. */ 15731 15732 *lnew = 7; 15733 if (nn == 3) { 15734 *ier = 0; 15735 return 0; 15736 } 15737 15738 /* A nearest-node data structure (NEAR, NEXT, and DIST) is */ 15739 /* used to obtain an expected-time (N*log(N)) incremental */ 15740 /* algorithm by enabling constant search time for locating */ 15741 /* each new node in the triangulation. */ 15742 15743 /* For each unprocessed node K, NEAR(K) is the index of the */ 15744 /* triangulation node closest to K (used as the starting */ 15745 /* point for the search in Subroutine TRFIND) and DIST(K) */ 15746 /* is an increasing function of the arc length (angular */ 15747 /* distance) between nodes K and NEAR(K): -Cos(a) for arc */ 15748 /* length a. */ 15749 15750 /* Since it is necessary to efficiently find the subset of */ 15751 /* unprocessed nodes associated with each triangulation */ 15752 /* node J (those that have J as their NEAR entries), the */ 15753 /* subsets are stored in NEAR and NEXT as follows: for */ 15754 /* each node J in the triangulation, I = NEAR(J) is the */ 15755 /* first unprocessed node in J's set (with I = 0 if the */ 15756 /* set is empty), L = NEXT(I) (if I > 0) is the second, */ 15757 /* NEXT(L) (if L > 0) is the third, etc. The nodes in each */ 15758 /* set are initially ordered by increasing indexes (which */ 15759 /* maximizes efficiency) but that ordering is not main- */ 15760 /* tained as the data structure is updated. */ 15761 15762 /* Initialize the data structure for the single triangle. */ 15763 15764 near__[1] = 0; 15765 near__[2] = 0; 15766 near__[3] = 0; 15767 for (k = nn; k >= 4; --k) { 15768 d1 = -(x[k] * x[1] + y[k] * y[1] + z__[k] * z__[1]); 15769 d2 = -(x[k] * x[2] + y[k] * y[2] + z__[k] * z__[2]); 15770 d3 = -(x[k] * x[3] + y[k] * y[3] + z__[k] * z__[3]); 15771 if (d1 <= d2 && d1 <= d3) { 15772 near__[k] = 1; 15773 dist[k] = d1; 15774 next[k] = near__[1]; 15775 near__[1] = k; 15776 } else if (d2 <= d1 && d2 <= d3) { 15777 near__[k] = 2; 15778 dist[k] = d2; 15779 next[k] = near__[2]; 15780 near__[2] = k; 15781 } else { 15782 near__[k] = 3; 15783 dist[k] = d3; 15784 next[k] = near__[3]; 15785 near__[3] = k; 15786 } 15787 /* L1: */ 15788 } 15789 15790 /* Add the remaining nodes */ 15791 15792 i__1 = nn; 15793 for (k = 4; k <= i__1; ++k) { 15794 addnod_(&near__[k], &k, &x[1], &y[1], &z__[1], &list[1], &lptr[1], & 15795 lend[1], lnew, ier); 15796 if (*ier != 0) { 15797 return 0; 15798 } 15799 15800 /* Remove K from the set of unprocessed nodes associated */ 15801 /* with NEAR(K). */ 15802 15803 i__ = near__[k]; 15804 if (near__[i__] == k) { 15805 near__[i__] = next[k]; 15806 } else { 15807 i__ = near__[i__]; 15808 L2: 15809 i0 = i__; 15810 i__ = next[i0]; 15811 if (i__ != k) { 15812 goto L2; 15813 } 15814 next[i0] = next[k]; 15815 } 15816 near__[k] = 0; 15817 15818 /* Loop on neighbors J of node K. */ 15819 15820 lpl = lend[k]; 15821 lp = lpl; 15822 L3: 15823 lp = lptr[lp]; 15824 j = (i__2 = list[lp], abs(i__2)); 15825 15826 /* Loop on elements I in the sequence of unprocessed nodes */ 15827 /* associated with J: K is a candidate for replacing J */ 15828 /* as the nearest triangulation node to I. The next value */ 15829 /* of I in the sequence, NEXT(I), must be saved before I */ 15830 /* is moved because it is altered by adding I to K's set. */ 15831 15832 i__ = near__[j]; 15833 L4: 15834 if (i__ == 0) { 15835 goto L5; 15836 } 15837 nexti = next[i__]; 15838 15839 /* Test for the distance from I to K less than the distance */ 15840 /* from I to J. */ 15841 15842 d__ = -(x[i__] * x[k] + y[i__] * y[k] + z__[i__] * z__[k]); 15843 if (d__ < dist[i__]) { 15844 15845 /* Replace J by K as the nearest triangulation node to I: */ 15846 /* update NEAR(I) and DIST(I), and remove I from J's set */ 15847 /* of unprocessed nodes and add it to K's set. */ 15848 15849 near__[i__] = k; 15850 dist[i__] = d__; 15851 if (i__ == near__[j]) { 15852 near__[j] = nexti; 15853 } else { 15854 next[i0] = nexti; 15855 } 15856 next[i__] = near__[k]; 15857 near__[k] = i__; 15858 } else { 15859 i0 = i__; 15860 } 15861 15862 /* Bottom of loop on I. */ 15863 15864 i__ = nexti; 15865 goto L4; 15866 15867 /* Bottom of loop on neighbors J. */ 15868 15869 L5: 15870 if (lp != lpl) { 15871 goto L3; 15872 } 15873 /* L6: */ 15874 } 15875 return 0; 15876 } /* trmesh_ */
int trplot_ | ( | int * | lun, | |
double * | pltsiz, | |||
double * | elat, | |||
double * | elon, | |||
double * | a, | |||
int * | n, | |||
double * | x, | |||
double * | y, | |||
double * | z__, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
char * | , | |||
long int * | numbr, | |||
int * | ier, | |||
short | ||||
) |
Definition at line 15878 of file util_sparx.cpp.
References abs, drwarc_(), i_dnnt(), sqrt(), t, TRUE_, and wr.
15882 { 15883 /* Initialized data */ 15884 15885 static long int annot = TRUE_; 15886 static double fsizn = 10.; 15887 static double fsizt = 16.; 15888 static double tol = .5; 15889 15890 /* System generated locals */ 15891 int i__1, i__2; 15892 double d__1; 15893 15894 /* Builtin functions */ 15895 //double atan(double), sin(double); 15896 //int i_dnnt(double *); 15897 //double cos(double), sqrt(double); 15898 15899 /* Local variables */ 15900 static double t; 15901 static int n0, n1; 15902 static double p0[3], p1[3], cf, r11, r12, r21, ct, r22, r23, sf; 15903 static int ir, lp; 15904 static double ex, ey, ez, wr, tx, ty; 15905 static int lpl; 15906 static double wrs; 15907 static int ipx1, ipx2, ipy1, ipy2, nseg; 15908 /* Subroutine */ int drwarc_(int *, double *, double *, 15909 double *, int *); 15910 15911 15912 /* *********************************************************** */ 15913 15914 /* From STRIPACK */ 15915 /* Robert J. Renka */ 15916 /* Dept. of Computer Science */ 15917 /* Univ. of North Texas */ 15918 /* renka@cs.unt.edu */ 15919 /* 03/04/03 */ 15920 15921 /* This subroutine creates a level-2 Encapsulated Post- */ 15922 /* script (EPS) file containing a graphical display of a */ 15923 /* triangulation of a set of nodes on the surface of the unit */ 15924 /* sphere. The visible portion of the triangulation is */ 15925 /* projected onto the plane that contains the origin and has */ 15926 /* normal defined by a user-specified eye-position. */ 15927 15928 15929 /* On input: */ 15930 15931 /* LUN = long int unit number in the range 0 to 99. */ 15932 /* The unit should be opened with an appropriate */ 15933 /* file name before the call to this routine. */ 15934 15935 /* PLTSIZ = Plot size in inches. A circular window in */ 15936 /* the projection plane is mapped to a circu- */ 15937 /* lar viewport with diameter equal to .88* */ 15938 /* PLTSIZ (leaving room for labels outside the */ 15939 /* viewport). The viewport is centered on the */ 15940 /* 8.5 by 11 inch page, and its boundary is */ 15941 /* drawn. 1.0 .LE. PLTSIZ .LE. 8.5. */ 15942 15943 /* ELAT,ELON = Latitude and longitude (in degrees) of */ 15944 /* the center of projection E (the center */ 15945 /* of the plot). The projection plane is */ 15946 /* the plane that contains the origin and */ 15947 /* has E as unit normal. In a rotated */ 15948 /* coordinate system for which E is the */ 15949 /* north pole, the projection plane con- */ 15950 /* tains the equator, and only northern */ 15951 /* hemisphere nodes are visible (from the */ 15952 /* point at infinity in the direction E). */ 15953 /* These are projected orthogonally onto */ 15954 /* the projection plane (by zeroing the z- */ 15955 /* component in the rotated coordinate */ 15956 /* system). ELAT and ELON must be in the */ 15957 /* range -90 to 90 and -180 to 180, respec- */ 15958 /* tively. */ 15959 15960 /* A = Angular distance in degrees from E to the boun- */ 15961 /* dary of a circular window against which the */ 15962 /* triangulation is clipped. The projected window */ 15963 /* is a disk of radius r = Sin(A) centered at the */ 15964 /* origin, and only visible nodes whose projections */ 15965 /* are within distance r of the origin are included */ 15966 /* in the plot. Thus, if A = 90, the plot includes */ 15967 /* the entire hemisphere centered at E. 0 .LT. A */ 15968 /* .LE. 90. */ 15969 15970 /* N = Number of nodes in the triangulation. N .GE. 3. */ 15971 15972 /* X,Y,Z = Arrays of length N containing the Cartesian */ 15973 /* coordinates of the nodes (unit vectors). */ 15974 15975 /* LIST,LPTR,LEND = Data structure defining the trian- */ 15976 /* gulation. Refer to Subroutine */ 15977 /* TRMESH. */ 15978 15979 /* TITLE = Type CHARACTER variable or constant contain- */ 15980 /* ing a string to be centered above the plot. */ 15981 /* The string must be enclosed in parentheses; */ 15982 /* i.e., the first and last characters must be */ 15983 /* '(' and ')', respectively, but these are not */ 15984 /* displayed. TITLE may have at most 80 char- */ 15985 /* acters including the parentheses. */ 15986 15987 /* NUMBR = Option indicator: If NUMBR = TRUE, the */ 15988 /* nodal indexes are plotted next to the nodes. */ 15989 15990 /* Input parameters are not altered by this routine. */ 15991 15992 /* On output: */ 15993 15994 /* IER = Error indicator: */ 15995 /* IER = 0 if no errors were encountered. */ 15996 /* IER = 1 if LUN, PLTSIZ, or N is outside its */ 15997 /* valid range. */ 15998 /* IER = 2 if ELAT, ELON, or A is outside its */ 15999 /* valid range. */ 16000 /* IER = 3 if an error was encountered in writing */ 16001 /* to unit LUN. */ 16002 16003 /* The values in the data statement below may be altered */ 16004 /* in order to modify various plotting options. */ 16005 16006 /* Module required by TRPLOT: DRWARC */ 16007 16008 /* Intrinsic functions called by TRPLOT: ABS, ATAN, COS, */ 16009 /* DBLE, NINT, SIN, */ 16010 /* SQRT */ 16011 16012 /* *********************************************************** */ 16013 16014 16015 /* Parameter adjustments */ 16016 --lend; 16017 --z__; 16018 --y; 16019 --x; 16020 --list; 16021 --lptr; 16022 16023 /* Function Body */ 16024 16025 /* Local parameters: */ 16026 16027 /* ANNOT = long int variable with value TRUE iff the plot */ 16028 /* is to be annotated with the values of ELAT, */ 16029 /* ELON, and A */ 16030 /* CF = Conversion factor for degrees to radians */ 16031 /* CT = Cos(ELAT) */ 16032 /* EX,EY,EZ = Cartesian coordinates of the eye-position E */ 16033 /* FSIZN = Font size in points for labeling nodes with */ 16034 /* their indexes if NUMBR = TRUE */ 16035 /* FSIZT = Font size in points for the title (and */ 16036 /* annotation if ANNOT = TRUE) */ 16037 /* IPX1,IPY1 = X and y coordinates (in points) of the lower */ 16038 /* left corner of the bounding box or viewport */ 16039 /* box */ 16040 /* IPX2,IPY2 = X and y coordinates (in points) of the upper */ 16041 /* right corner of the bounding box or viewport */ 16042 /* box */ 16043 /* IR = Half the width (height) of the bounding box or */ 16044 /* viewport box in points -- viewport radius */ 16045 /* LP = LIST index (pointer) */ 16046 /* LPL = Pointer to the last neighbor of N0 */ 16047 /* N0 = Index of a node whose incident arcs are to be */ 16048 /* drawn */ 16049 /* N1 = Neighbor of N0 */ 16050 /* NSEG = Number of line segments used by DRWARC in a */ 16051 /* polygonal approximation to a projected edge */ 16052 /* P0 = Coordinates of N0 in the rotated coordinate */ 16053 /* system or label location (first two */ 16054 /* components) */ 16055 /* P1 = Coordinates of N1 in the rotated coordinate */ 16056 /* system or intersection of edge N0-N1 with */ 16057 /* the equator (in the rotated coordinate */ 16058 /* system) */ 16059 /* R11...R23 = Components of the first two rows of a rotation */ 16060 /* that maps E to the north pole (0,0,1) */ 16061 /* SF = Scale factor for mapping world coordinates */ 16062 /* (window coordinates in [-WR,WR] X [-WR,WR]) */ 16063 /* to viewport coordinates in [IPX1,IPX2] X */ 16064 /* [IPY1,IPY2] */ 16065 /* T = Temporary variable */ 16066 /* TOL = Maximum distance in points between a projected */ 16067 /* triangulation edge and its approximation by */ 16068 /* a polygonal curve */ 16069 /* TX,TY = Translation vector for mapping world coordi- */ 16070 /* nates to viewport coordinates */ 16071 /* WR = Window radius r = Sin(A) */ 16072 /* WRS = WR**2 */ 16073 16074 16075 /* Test for invalid parameters. */ 16076 16077 if (*lun < 0 || *lun > 99 || *pltsiz < 1. || *pltsiz > 8.5 || *n < 3) { 16078 goto L11; 16079 } 16080 if (abs(*elat) > 90. || abs(*elon) > 180. || *a > 90.) { 16081 goto L12; 16082 } 16083 16084 /* Compute a conversion factor CF for degrees to radians */ 16085 /* and compute the window radius WR. */ 16086 16087 cf = atan(1.) / 45.; 16088 wr = sin(cf * *a); 16089 wrs = wr * wr; 16090 16091 /* Compute the lower left (IPX1,IPY1) and upper right */ 16092 /* (IPX2,IPY2) corner coordinates of the bounding box. */ 16093 /* The coordinates, specified in default user space units */ 16094 /* (points, at 72 points/inch with origin at the lower */ 16095 /* left corner of the page), are chosen to preserve the */ 16096 /* square aspect ratio, and to center the plot on the 8.5 */ 16097 /* by 11 inch page. The center of the page is (306,396), */ 16098 /* and IR = PLTSIZ/2 in points. */ 16099 16100 d__1 = *pltsiz * 36.; 16101 ir = i_dnnt(&d__1); 16102 ipx1 = 306 - ir; 16103 ipx2 = ir + 306; 16104 ipy1 = 396 - ir; 16105 ipy2 = ir + 396; 16106 16107 /* Output header comments. */ 16108 16109 /* WRITE (LUN,100,ERR=13) IPX1, IPY1, IPX2, IPY2 */ 16110 /* 100 FORMAT ('%!PS-Adobe-3.0 EPSF-3.0'/ */ 16111 /* . '%%BoundingBox:',4I4/ */ 16112 /* . '%%Title: Triangulation'/ */ 16113 /* . '%%Creator: STRIPACK'/ */ 16114 /* . '%%EndComments') */ 16115 16116 /* Set (IPX1,IPY1) and (IPX2,IPY2) to the corner coordinates */ 16117 /* of a viewport box obtained by shrinking the bounding box */ 16118 /* by 12% in each dimension. */ 16119 16120 d__1 = (double) ir * .88; 16121 ir = i_dnnt(&d__1); 16122 ipx1 = 306 - ir; 16123 ipx2 = ir + 306; 16124 ipy1 = 396 - ir; 16125 ipy2 = ir + 396; 16126 16127 /* Set the line thickness to 2 points, and draw the */ 16128 /* viewport boundary. */ 16129 16130 t = 2.; 16131 /* WRITE (LUN,110,ERR=13) T */ 16132 /* WRITE (LUN,120,ERR=13) IR */ 16133 /* WRITE (LUN,130,ERR=13) */ 16134 /* 110 FORMAT (F12.6,' setlinewidth') */ 16135 /* 120 FORMAT ('306 396 ',I3,' 0 360 arc') */ 16136 /* 130 FORMAT ('stroke') */ 16137 16138 /* Set up an affine mapping from the window box [-WR,WR] X */ 16139 /* [-WR,WR] to the viewport box. */ 16140 16141 sf = (double) ir / wr; 16142 tx = ipx1 + sf * wr; 16143 ty = ipy1 + sf * wr; 16144 /* WRITE (LUN,140,ERR=13) TX, TY, SF, SF */ 16145 /* 140 FORMAT (2F12.6,' translate'/ */ 16146 /* . 2F12.6,' scale') */ 16147 16148 /* The line thickness must be changed to reflect the new */ 16149 /* scaling which is applied to all subsequent output. */ 16150 /* Set it to 1.0 point. */ 16151 16152 t = 1. / sf; 16153 /* WRITE (LUN,110,ERR=13) T */ 16154 16155 /* Save the current graphics state, and set the clip path to */ 16156 /* the boundary of the window. */ 16157 16158 /* WRITE (LUN,150,ERR=13) */ 16159 /* WRITE (LUN,160,ERR=13) WR */ 16160 /* WRITE (LUN,170,ERR=13) */ 16161 /* 150 FORMAT ('gsave') */ 16162 /* 160 FORMAT ('0 0 ',F12.6,' 0 360 arc') */ 16163 /* 170 FORMAT ('clip newpath') */ 16164 16165 /* Compute the Cartesian coordinates of E and the components */ 16166 /* of a rotation R which maps E to the north pole (0,0,1). */ 16167 /* R is taken to be a rotation about the z-axis (into the */ 16168 /* yz-plane) followed by a rotation about the x-axis chosen */ 16169 /* so that the view-up direction is (0,0,1), or (-1,0,0) if */ 16170 /* E is the north or south pole. */ 16171 16172 /* ( R11 R12 0 ) */ 16173 /* R = ( R21 R22 R23 ) */ 16174 /* ( EX EY EZ ) */ 16175 16176 t = cf * *elon; 16177 ct = cos(cf * *elat); 16178 ex = ct * cos(t); 16179 ey = ct * sin(t); 16180 ez = sin(cf * *elat); 16181 if (ct != 0.) { 16182 r11 = -ey / ct; 16183 r12 = ex / ct; 16184 } else { 16185 r11 = 0.; 16186 r12 = 1.; 16187 } 16188 r21 = -ez * r12; 16189 r22 = ez * r11; 16190 r23 = ct; 16191 16192 /* Loop on visible nodes N0 that project to points */ 16193 /* (P0(1),P0(2)) in the window. */ 16194 16195 i__1 = *n; 16196 for (n0 = 1; n0 <= i__1; ++n0) { 16197 p0[2] = ex * x[n0] + ey * y[n0] + ez * z__[n0]; 16198 if (p0[2] < 0.) { 16199 goto L3; 16200 } 16201 p0[0] = r11 * x[n0] + r12 * y[n0]; 16202 p0[1] = r21 * x[n0] + r22 * y[n0] + r23 * z__[n0]; 16203 if (p0[0] * p0[0] + p0[1] * p0[1] > wrs) { 16204 goto L3; 16205 } 16206 lpl = lend[n0]; 16207 lp = lpl; 16208 16209 /* Loop on neighbors N1 of N0. LPL points to the last */ 16210 /* neighbor of N0. Copy the components of N1 into P. */ 16211 16212 L1: 16213 lp = lptr[lp]; 16214 n1 = (i__2 = list[lp], abs(i__2)); 16215 p1[0] = r11 * x[n1] + r12 * y[n1]; 16216 p1[1] = r21 * x[n1] + r22 * y[n1] + r23 * z__[n1]; 16217 p1[2] = ex * x[n1] + ey * y[n1] + ez * z__[n1]; 16218 if (p1[2] < 0.) { 16219 16220 /* N1 is a 'southern hemisphere' point. Move it to the */ 16221 /* intersection of edge N0-N1 with the equator so that */ 16222 /* the edge is clipped properly. P1(3) is set to 0. */ 16223 16224 p1[0] = p0[2] * p1[0] - p1[2] * p0[0]; 16225 p1[1] = p0[2] * p1[1] - p1[2] * p0[1]; 16226 t = sqrt(p1[0] * p1[0] + p1[1] * p1[1]); 16227 p1[0] /= t; 16228 p1[1] /= t; 16229 } 16230 16231 /* If node N1 is in the window and N1 < N0, bypass edge */ 16232 /* N0->N1 (since edge N1->N0 has already been drawn). */ 16233 16234 if (p1[2] >= 0. && p1[0] * p1[0] + p1[1] * p1[1] <= wrs && n1 < n0) { 16235 goto L2; 16236 } 16237 16238 /* Add the edge to the path. (TOL is converted to world */ 16239 /* coordinates.) */ 16240 16241 if (p1[2] < 0.) { 16242 p1[2] = 0.; 16243 } 16244 d__1 = tol / sf; 16245 drwarc_(lun, p0, p1, &d__1, &nseg); 16246 16247 /* Bottom of loops. */ 16248 16249 L2: 16250 if (lp != lpl) { 16251 goto L1; 16252 } 16253 L3: 16254 ; 16255 } 16256 16257 /* Paint the path and restore the saved graphics state (with */ 16258 /* no clip path). */ 16259 16260 /* WRITE (LUN,130,ERR=13) */ 16261 /* WRITE (LUN,190,ERR=13) */ 16262 /* 190 FORMAT ('grestore') */ 16263 if (*numbr) { 16264 16265 /* Nodes in the window are to be labeled with their indexes. */ 16266 /* Convert FSIZN from points to world coordinates, and */ 16267 /* output the commands to select a font and scale it. */ 16268 16269 t = fsizn / sf; 16270 /* WRITE (LUN,200,ERR=13) T */ 16271 /* 200 FORMAT ('/Helvetica findfont'/ */ 16272 /* . F12.6,' scalefont setfont') */ 16273 16274 /* Loop on visible nodes N0 that project to points */ 16275 /* P0 = (P0(1),P0(2)) in the window. */ 16276 16277 i__1 = *n; 16278 for (n0 = 1; n0 <= i__1; ++n0) { 16279 if (ex * x[n0] + ey * y[n0] + ez * z__[n0] < 0.) { 16280 goto L4; 16281 } 16282 p0[0] = r11 * x[n0] + r12 * y[n0]; 16283 p0[1] = r21 * x[n0] + r22 * y[n0] + r23 * z__[n0]; 16284 if (p0[0] * p0[0] + p0[1] * p0[1] > wrs) { 16285 goto L4; 16286 } 16287 16288 /* Move to P0 and draw the label N0. The first character */ 16289 /* will will have its lower left corner about one */ 16290 /* character width to the right of the nodal position. */ 16291 16292 /* WRITE (LUN,210,ERR=13) P0(1), P0(2) */ 16293 /* WRITE (LUN,220,ERR=13) N0 */ 16294 /* 210 FORMAT (2F12.6,' moveto') */ 16295 /* 220 FORMAT ('(',I3,') show') */ 16296 L4: 16297 ; 16298 } 16299 } 16300 16301 /* Convert FSIZT from points to world coordinates, and output */ 16302 /* the commands to select a font and scale it. */ 16303 16304 t = fsizt / sf; 16305 /* WRITE (LUN,200,ERR=13) T */ 16306 16307 /* Display TITLE centered above the plot: */ 16308 16309 p0[1] = wr + t * 3.; 16310 /* WRITE (LUN,230,ERR=13) TITLE, P0(2) */ 16311 /* 230 FORMAT (A80/' stringwidth pop 2 div neg ',F12.6, */ 16312 /* . ' moveto') */ 16313 /* WRITE (LUN,240,ERR=13) TITLE */ 16314 /* 240 FORMAT (A80/' show') */ 16315 if (annot) { 16316 16317 /* Display the window center and radius below the plot. */ 16318 16319 p0[0] = -wr; 16320 p0[1] = -wr - 50. / sf; 16321 /* WRITE (LUN,210,ERR=13) P0(1), P0(2) */ 16322 /* WRITE (LUN,250,ERR=13) ELAT, ELON */ 16323 p0[1] -= t * 2.; 16324 /* WRITE (LUN,210,ERR=13) P0(1), P0(2) */ 16325 /* WRITE (LUN,260,ERR=13) A */ 16326 /* 250 FORMAT ('(Window center: ELAT = ',F7.2, */ 16327 /* . ', ELON = ',F8.2,') show') */ 16328 /* 260 FORMAT ('(Angular extent: A = ',F5.2,') show') */ 16329 } 16330 16331 /* Paint the path and output the showpage command and */ 16332 /* end-of-file indicator. */ 16333 16334 /* WRITE (LUN,270,ERR=13) */ 16335 /* 270 FORMAT ('stroke'/ */ 16336 /* . 'showpage'/ */ 16337 /* . '%%EOF') */ 16338 16339 /* HP's interpreters require a one-byte End-of-PostScript-Job */ 16340 /* indicator (to eliminate a timeout error message): */ 16341 /* ASCII 4. */ 16342 16343 /* WRITE (LUN,280,ERR=13) CHAR(4) */ 16344 /* 280 FORMAT (A1) */ 16345 16346 /* No error encountered. */ 16347 16348 *ier = 0; 16349 return 0; 16350 16351 /* Invalid input parameter LUN, PLTSIZ, or N. */ 16352 16353 L11: 16354 *ier = 1; 16355 return 0; 16356 16357 /* Invalid input parameter ELAT, ELON, or A. */ 16358 16359 L12: 16360 *ier = 2; 16361 return 0; 16362 16363 /* Error writing to unit LUN. */ 16364 16365 /* L13: */ 16366 *ier = 3; 16367 return 0; 16368 } /* trplot_ */
int trprnt_ | ( | int * | n, | |
double * | x, | |||
double * | y, | |||
double * | z__, | |||
int * | iflag, | |||
int * | list, | |||
int * | lptr, | |||
int * | lend, | |||
int * | lout | |||
) |
Definition at line 16370 of file util_sparx.cpp.
References nn().
16373 { 16374 /* Initialized data */ 16375 16376 static int nmax = 9999; 16377 static int nlmax = 58; 16378 16379 /* System generated locals */ 16380 int i__1; 16381 16382 /* Local variables */ 16383 static int k, na, nb, nd, nl, lp, nn, nt, inc, lpl, lun, node, nabor[ 16384 400]; 16385 16386 16387 /* *********************************************************** */ 16388 16389 /* From STRIPACK */ 16390 /* Robert J. Renka */ 16391 /* Dept. of Computer Science */ 16392 /* Univ. of North Texas */ 16393 /* renka@cs.unt.edu */ 16394 /* 07/25/98 */ 16395 16396 /* This subroutine prints the triangulation adjacency lists */ 16397 /* created by Subroutine TRMESH and, optionally, the nodal */ 16398 /* coordinates (either latitude and longitude or Cartesian */ 16399 /* coordinates) on long int unit LOUT. The list of neighbors */ 16400 /* of a boundary node is followed by index 0. The numbers of */ 16401 /* boundary nodes, triangles, and arcs are also printed. */ 16402 16403 16404 /* On input: */ 16405 16406 /* N = Number of nodes in the triangulation. N .GE. 3 */ 16407 /* and N .LE. 9999. */ 16408 16409 /* X,Y,Z = Arrays of length N containing the Cartesian */ 16410 /* coordinates of the nodes if IFLAG = 0, or */ 16411 /* (X and Y only) arrays of length N containing */ 16412 /* longitude and latitude, respectively, if */ 16413 /* IFLAG > 0, or unused dummy parameters if */ 16414 /* IFLAG < 0. */ 16415 16416 /* IFLAG = Nodal coordinate option indicator: */ 16417 /* IFLAG = 0 if X, Y, and Z (assumed to contain */ 16418 /* Cartesian coordinates) are to be */ 16419 /* printed (to 6 decimal places). */ 16420 /* IFLAG > 0 if only X and Y (assumed to con- */ 16421 /* tain longitude and latitude) are */ 16422 /* to be printed (to 6 decimal */ 16423 /* places). */ 16424 /* IFLAG < 0 if only the adjacency lists are to */ 16425 /* be printed. */ 16426 16427 /* LIST,LPTR,LEND = Data structure defining the trian- */ 16428 /* gulation. Refer to Subroutine */ 16429 /* TRMESH. */ 16430 16431 /* LOUT = long int unit for output. If LOUT is not in */ 16432 /* the range 0 to 99, output is written to */ 16433 /* long int unit 6. */ 16434 16435 /* Input parameters are not altered by this routine. */ 16436 16437 /* On output: */ 16438 16439 /* The adjacency lists and nodal coordinates (as specified */ 16440 /* by IFLAG) are written to unit LOUT. */ 16441 16442 /* Modules required by TRPRNT: None */ 16443 16444 /* *********************************************************** */ 16445 16446 /* Parameter adjustments */ 16447 --lend; 16448 --z__; 16449 --y; 16450 --x; 16451 --list; 16452 --lptr; 16453 16454 /* Function Body */ 16455 16456 /* Local parameters: */ 16457 16458 /* I = NABOR index (1 to K) */ 16459 /* INC = Increment for NL associated with an adjacency list */ 16460 /* K = Counter and number of neighbors of NODE */ 16461 /* LP = LIST pointer of a neighbor of NODE */ 16462 /* LPL = Pointer to the last neighbor of NODE */ 16463 /* LUN = long int unit for output (copy of LOUT) */ 16464 /* NA = Number of arcs in the triangulation */ 16465 /* NABOR = Array containing the adjacency list associated */ 16466 /* with NODE, with zero appended if NODE is a */ 16467 /* boundary node */ 16468 /* NB = Number of boundary nodes encountered */ 16469 /* ND = Index of a neighbor of NODE (or negative index) */ 16470 /* NL = Number of lines that have been printed on the */ 16471 /* current page */ 16472 /* NLMAX = Maximum number of print lines per page (except */ 16473 /* for the last page which may have two addi- */ 16474 /* tional lines) */ 16475 /* NMAX = Upper bound on N (allows 4-digit indexes) */ 16476 /* NODE = Index of a node and DO-loop index (1 to N) */ 16477 /* NN = Local copy of N */ 16478 /* NT = Number of triangles in the triangulation */ 16479 16480 nn = *n; 16481 lun = *lout; 16482 if (lun < 0 || lun > 99) { 16483 lun = 6; 16484 } 16485 16486 /* Print a heading and test the range of N. */ 16487 16488 /* WRITE (LUN,100) NN */ 16489 if (nn < 3 || nn > nmax) { 16490 16491 /* N is outside its valid range. */ 16492 16493 /* WRITE (LUN,110) */ 16494 return 0; 16495 } 16496 16497 /* Initialize NL (the number of lines printed on the current */ 16498 /* page) and NB (the number of boundary nodes encountered). */ 16499 16500 nl = 6; 16501 nb = 0; 16502 if (*iflag < 0) { 16503 16504 /* Print LIST only. K is the number of neighbors of NODE */ 16505 /* that have been stored in NABOR. */ 16506 16507 /* WRITE (LUN,101) */ 16508 i__1 = nn; 16509 for (node = 1; node <= i__1; ++node) { 16510 lpl = lend[node]; 16511 lp = lpl; 16512 k = 0; 16513 16514 L1: 16515 ++k; 16516 lp = lptr[lp]; 16517 nd = list[lp]; 16518 nabor[k - 1] = nd; 16519 if (lp != lpl) { 16520 goto L1; 16521 } 16522 if (nd <= 0) { 16523 16524 /* NODE is a boundary node. Correct the sign of the last */ 16525 /* neighbor, add 0 to the end of the list, and increment */ 16526 /* NB. */ 16527 16528 nabor[k - 1] = -nd; 16529 ++k; 16530 nabor[k - 1] = 0; 16531 ++nb; 16532 } 16533 16534 /* Increment NL and print the list of neighbors. */ 16535 16536 inc = (k - 1) / 14 + 2; 16537 nl += inc; 16538 if (nl > nlmax) { 16539 /* WRITE (LUN,108) */ 16540 nl = inc; 16541 } 16542 /* WRITE (LUN,104) NODE, (NABOR(I), I = 1,K) */ 16543 /* IF (K .NE. 14) */ 16544 /* WRITE (LUN,107) */ 16545 /* L2: */ 16546 } 16547 } else if (*iflag > 0) { 16548 16549 /* Print X (longitude), Y (latitude), and LIST. */ 16550 16551 /* WRITE (LUN,102) */ 16552 i__1 = nn; 16553 for (node = 1; node <= i__1; ++node) { 16554 lpl = lend[node]; 16555 lp = lpl; 16556 k = 0; 16557 16558 L3: 16559 ++k; 16560 lp = lptr[lp]; 16561 nd = list[lp]; 16562 nabor[k - 1] = nd; 16563 if (lp != lpl) { 16564 goto L3; 16565 } 16566 if (nd <= 0) { 16567 16568 /* NODE is a boundary node. */ 16569 16570 nabor[k - 1] = -nd; 16571 ++k; 16572 nabor[k - 1] = 0; 16573 ++nb; 16574 } 16575 16576 /* Increment NL and print X, Y, and NABOR. */ 16577 16578 inc = (k - 1) / 8 + 2; 16579 nl += inc; 16580 if (nl > nlmax) { 16581 /* WRITE (LUN,108) */ 16582 nl = inc; 16583 } 16584 /* WRITE (LUN,105) NODE, X(NODE), Y(NODE), (NABOR(I), I = 1,K) */ 16585 /* IF (K .NE. 8) */ 16586 /* PRINT *,K */ 16587 /* WRITE (LUN,107) */ 16588 /* L4: */ 16589 } 16590 } else { 16591 16592 /* Print X, Y, Z, and LIST. */ 16593 16594 /* WRITE (LUN,103) */ 16595 i__1 = nn; 16596 for (node = 1; node <= i__1; ++node) { 16597 lpl = lend[node]; 16598 lp = lpl; 16599 k = 0; 16600 16601 L5: 16602 ++k; 16603 lp = lptr[lp]; 16604 nd = list[lp]; 16605 nabor[k - 1] = nd; 16606 if (lp != lpl) { 16607 goto L5; 16608 } 16609 if (nd <= 0) { 16610 16611 /* NODE is a boundary node. */ 16612 16613 nabor[k - 1] = -nd; 16614 ++k; 16615 nabor[k - 1] = 0; 16616 ++nb; 16617 } 16618 16619 /* Increment NL and print X, Y, Z, and NABOR. */ 16620 16621 inc = (k - 1) / 5 + 2; 16622 nl += inc; 16623 if (nl > nlmax) { 16624 /* WRITE (LUN,108) */ 16625 nl = inc; 16626 } 16627 /* WRITE (LUN,106) NODE, X(NODE), Y(NODE),Z(NODE), (NABOR(I), I = 1,K) */ 16628 /* IF (K .NE. 5) */ 16629 /* print *,K */ 16630 /* WRITE (LUN,107) */ 16631 /* L6: */ 16632 } 16633 } 16634 16635 /* Print NB, NA, and NT (boundary nodes, arcs, and */ 16636 /* triangles). */ 16637 16638 if (nb != 0) { 16639 na = nn * 3 - nb - 3; 16640 nt = (nn << 1) - nb - 2; 16641 } else { 16642 na = nn * 3 - 6; 16643 nt = (nn << 1) - 4; 16644 } 16645 /* WRITE (LUN,109) NB, NA, NT */ 16646 return 0; 16647 16648 /* Print formats: */ 16649 16650 /* 100 FORMAT (///15X,'STRIPACK Triangulation Data ', */ 16651 /* . 'Structure, N = ',I5//) */ 16652 /* 101 FORMAT (1X,'Node',31X,'Neighbors of Node'//) */ 16653 /* 102 FORMAT (1X,'Node',5X,'Longitude',6X,'Latitude', */ 16654 /* . 18X,'Neighbors of Node'//) */ 16655 /* 103 FORMAT (1X,'Node',5X,'X(Node)',8X,'Y(Node)',8X, */ 16656 /* . 'Z(Node)',11X,'Neighbors of Node'//) */ 16657 /* 104 FORMAT (1X,I4,4X,14I5/(1X,8X,14I5)) */ 16658 /* 105 FORMAT (1X,I4,2D15.6,4X,8I5/(1X,38X,8I5)) */ 16659 /* 106 FORMAT (1X,I4,3D15.6,4X,5I5/(1X,53X,5I5)) */ 16660 /* 107 FORMAT (1X) */ 16661 /* 108 FORMAT (///) */ 16662 /* 109 FORMAT (/1X,'NB = ',I4,' Boundary Nodes',5X, */ 16663 /* . 'NA = ',I5,' Arcs',5X,'NT = ',I5, */ 16664 /* . ' Triangles') */ 16665 /* 110 FORMAT (1X,10X,'*** N is outside its valid', */ 16666 /* . ' range ***') */ 16667 } /* trprnt_ */
int vrplot_ | ( | int * | lun, | |
double * | pltsiz, | |||
double * | elat, | |||
double * | elon, | |||
double * | a, | |||
int * | n, | |||
double * | x, | |||
double * | y, | |||
double * | z__, | |||
int * | nt, | |||
int * | listc, | |||
int * | lptr, | |||
int * | lend, | |||
double * | xc, | |||
double * | yc, | |||
double * | zc, | |||
char * | , | |||
long int * | numbr, | |||
int * | ier, | |||
short | ||||
) |
Definition at line 16669 of file util_sparx.cpp.
References abs, drwarc_(), i_dnnt(), sqrt(), t, TRUE_, and wr.
16674 { 16675 /* Initialized data */ 16676 16677 static long int annot = TRUE_; 16678 static double fsizn = 10.; 16679 static double fsizt = 16.; 16680 static double tol = .5; 16681 16682 /* System generated locals */ 16683 int i__1; 16684 double d__1; 16685 16686 /* Builtin functions */ 16687 //double atan(double), sin(double); 16688 //int i_dnnt(double *); 16689 //double cos(double), sqrt(double); 16690 16691 /* Local variables */ 16692 static double t; 16693 static int n0; 16694 static double p1[3], p2[3], x0, y0, cf, r11, r12, r21, ct, r22, r23, 16695 sf; 16696 static int ir, lp; 16697 static double ex, ey, ez, wr, tx, ty; 16698 static long int in1, in2; 16699 static int kv1, kv2, lpl; 16700 static double wrs; 16701 static int ipx1, ipx2, ipy1, ipy2, nseg; 16702 /* Subroutine */ int drwarc_(int *, double *, double *, 16703 double *, int *); 16704 16705 16706 /* *********************************************************** */ 16707 16708 /* From STRIPACK */ 16709 /* Robert J. Renka */ 16710 /* Dept. of Computer Science */ 16711 /* Univ. of North Texas */ 16712 /* renka@cs.unt.edu */ 16713 /* 03/04/03 */ 16714 16715 /* This subroutine creates a level-2 Encapsulated Post- */ 16716 /* script (EPS) file containing a graphical depiction of a */ 16717 /* Voronoi diagram of a set of nodes on the unit sphere. */ 16718 /* The visible portion of the diagram is projected orthog- */ 16719 /* onally onto the plane that contains the origin and has */ 16720 /* normal defined by a user-specified eye-position. */ 16721 16722 /* The parameters defining the Voronoi diagram may be com- */ 16723 /* puted by Subroutine CRLIST. */ 16724 16725 16726 /* On input: */ 16727 16728 /* LUN = long int unit number in the range 0 to 99. */ 16729 /* The unit should be opened with an appropriate */ 16730 /* file name before the call to this routine. */ 16731 16732 /* PLTSIZ = Plot size in inches. A circular window in */ 16733 /* the projection plane is mapped to a circu- */ 16734 /* lar viewport with diameter equal to .88* */ 16735 /* PLTSIZ (leaving room for labels outside the */ 16736 /* viewport). The viewport is centered on the */ 16737 /* 8.5 by 11 inch page, and its boundary is */ 16738 /* drawn. 1.0 .LE. PLTSIZ .LE. 8.5. */ 16739 16740 /* ELAT,ELON = Latitude and longitude (in degrees) of */ 16741 /* the center of projection E (the center */ 16742 /* of the plot). The projection plane is */ 16743 /* the plane that contains the origin and */ 16744 /* has E as unit normal. In a rotated */ 16745 /* coordinate system for which E is the */ 16746 /* north pole, the projection plane con- */ 16747 /* tains the equator, and only northern */ 16748 /* hemisphere points are visible (from the */ 16749 /* point at infinity in the direction E). */ 16750 /* These are projected orthogonally onto */ 16751 /* the projection plane (by zeroing the z- */ 16752 /* component in the rotated coordinate */ 16753 /* system). ELAT and ELON must be in the */ 16754 /* range -90 to 90 and -180 to 180, respec- */ 16755 /* tively. */ 16756 16757 /* A = Angular distance in degrees from E to the boun- */ 16758 /* dary of a circular window against which the */ 16759 /* Voronoi diagram is clipped. The projected win- */ 16760 /* dow is a disk of radius r = Sin(A) centered at */ 16761 /* the origin, and only visible vertices whose */ 16762 /* projections are within distance r of the origin */ 16763 /* are included in the plot. Thus, if A = 90, the */ 16764 /* plot includes the entire hemisphere centered at */ 16765 /* E. 0 .LT. A .LE. 90. */ 16766 16767 /* N = Number of nodes (Voronoi centers) and Voronoi */ 16768 /* regions. N .GE. 3. */ 16769 16770 /* X,Y,Z = Arrays of length N containing the Cartesian */ 16771 /* coordinates of the nodes (unit vectors). */ 16772 16773 /* NT = Number of Voronoi region vertices (triangles, */ 16774 /* including those in the extended triangulation */ 16775 /* if the number of boundary nodes NB is nonzero): */ 16776 /* NT = 2*N-4. */ 16777 16778 /* LISTC = Array of length 3*NT containing triangle */ 16779 /* indexes (indexes to XC, YC, and ZC) stored */ 16780 /* in 1-1 correspondence with LIST/LPTR entries */ 16781 /* (or entries that would be stored in LIST for */ 16782 /* the extended triangulation): the index of */ 16783 /* triangle (N1,N2,N3) is stored in LISTC(K), */ 16784 /* LISTC(L), and LISTC(M), where LIST(K), */ 16785 /* LIST(L), and LIST(M) are the indexes of N2 */ 16786 /* as a neighbor of N1, N3 as a neighbor of N2, */ 16787 /* and N1 as a neighbor of N3. The Voronoi */ 16788 /* region associated with a node is defined by */ 16789 /* the CCW-ordered sequence of circumcenters in */ 16790 /* one-to-one correspondence with its adjacency */ 16791 /* list (in the extended triangulation). */ 16792 16793 /* LPTR = Array of length 3*NT = 6*N-12 containing a */ 16794 /* set of pointers (LISTC indexes) in one-to-one */ 16795 /* correspondence with the elements of LISTC. */ 16796 /* LISTC(LPTR(I)) indexes the triangle which */ 16797 /* follows LISTC(I) in cyclical counterclockwise */ 16798 /* order (the first neighbor follows the last */ 16799 /* neighbor). */ 16800 16801 /* LEND = Array of length N containing a set of */ 16802 /* pointers to triangle lists. LP = LEND(K) */ 16803 /* points to a triangle (indexed by LISTC(LP)) */ 16804 /* containing node K for K = 1 to N. */ 16805 16806 /* XC,YC,ZC = Arrays of length NT containing the */ 16807 /* Cartesian coordinates of the triangle */ 16808 /* circumcenters (Voronoi vertices). */ 16809 /* XC(I)**2 + YC(I)**2 + ZC(I)**2 = 1. */ 16810 16811 /* TITLE = Type CHARACTER variable or constant contain- */ 16812 /* ing a string to be centered above the plot. */ 16813 /* The string must be enclosed in parentheses; */ 16814 /* i.e., the first and last characters must be */ 16815 /* '(' and ')', respectively, but these are not */ 16816 /* displayed. TITLE may have at most 80 char- */ 16817 /* acters including the parentheses. */ 16818 16819 /* NUMBR = Option indicator: If NUMBR = TRUE, the */ 16820 /* nodal indexes are plotted at the Voronoi */ 16821 /* region centers. */ 16822 16823 /* Input parameters are not altered by this routine. */ 16824 16825 /* On output: */ 16826 16827 /* IER = Error indicator: */ 16828 /* IER = 0 if no errors were encountered. */ 16829 /* IER = 1 if LUN, PLTSIZ, N, or NT is outside */ 16830 /* its valid range. */ 16831 /* IER = 2 if ELAT, ELON, or A is outside its */ 16832 /* valid range. */ 16833 /* IER = 3 if an error was encountered in writing */ 16834 /* to unit LUN. */ 16835 16836 /* Module required by VRPLOT: DRWARC */ 16837 16838 /* Intrinsic functions called by VRPLOT: ABS, ATAN, COS, */ 16839 /* DBLE, NINT, SIN, */ 16840 /* SQRT */ 16841 16842 /* *********************************************************** */ 16843 16844 16845 /* Parameter adjustments */ 16846 --lend; 16847 --z__; 16848 --y; 16849 --x; 16850 --zc; 16851 --yc; 16852 --xc; 16853 --listc; 16854 --lptr; 16855 16856 /* Function Body */ 16857 16858 /* Local parameters: */ 16859 16860 /* ANNOT = long int variable with value TRUE iff the plot */ 16861 /* is to be annotated with the values of ELAT, */ 16862 /* ELON, and A */ 16863 /* CF = Conversion factor for degrees to radians */ 16864 /* CT = Cos(ELAT) */ 16865 /* EX,EY,EZ = Cartesian coordinates of the eye-position E */ 16866 /* FSIZN = Font size in points for labeling nodes with */ 16867 /* their indexes if NUMBR = TRUE */ 16868 /* FSIZT = Font size in points for the title (and */ 16869 /* annotation if ANNOT = TRUE) */ 16870 /* IN1,IN2 = long int variables with value TRUE iff the */ 16871 /* projections of vertices KV1 and KV2, respec- */ 16872 /* tively, are inside the window */ 16873 /* IPX1,IPY1 = X and y coordinates (in points) of the lower */ 16874 /* left corner of the bounding box or viewport */ 16875 /* box */ 16876 /* IPX2,IPY2 = X and y coordinates (in points) of the upper */ 16877 /* right corner of the bounding box or viewport */ 16878 /* box */ 16879 /* IR = Half the width (height) of the bounding box or */ 16880 /* viewport box in points -- viewport radius */ 16881 /* KV1,KV2 = Endpoint indexes of a Voronoi edge */ 16882 /* LP = LIST index (pointer) */ 16883 /* LPL = Pointer to the last neighbor of N0 */ 16884 /* N0 = Index of a node */ 16885 /* NSEG = Number of line segments used by DRWARC in a */ 16886 /* polygonal approximation to a projected edge */ 16887 /* P1 = Coordinates of vertex KV1 in the rotated */ 16888 /* coordinate system */ 16889 /* P2 = Coordinates of vertex KV2 in the rotated */ 16890 /* coordinate system or intersection of edge */ 16891 /* KV1-KV2 with the equator (in the rotated */ 16892 /* coordinate system) */ 16893 /* R11...R23 = Components of the first two rows of a rotation */ 16894 /* that maps E to the north pole (0,0,1) */ 16895 /* SF = Scale factor for mapping world coordinates */ 16896 /* (window coordinates in [-WR,WR] X [-WR,WR]) */ 16897 /* to viewport coordinates in [IPX1,IPX2] X */ 16898 /* [IPY1,IPY2] */ 16899 /* T = Temporary variable */ 16900 /* TOL = Maximum distance in points between a projected */ 16901 /* Voronoi edge and its approximation by a */ 16902 /* polygonal curve */ 16903 /* TX,TY = Translation vector for mapping world coordi- */ 16904 /* nates to viewport coordinates */ 16905 /* WR = Window radius r = Sin(A) */ 16906 /* WRS = WR**2 */ 16907 /* X0,Y0 = Projection plane coordinates of node N0 or */ 16908 /* label location */ 16909 16910 16911 /* Test for invalid parameters. */ 16912 16913 if (*lun < 0 || *lun > 99 || *pltsiz < 1. || *pltsiz > 8.5 || *n < 3 || * 16914 nt != 2 * *n - 4) { 16915 goto L11; 16916 } 16917 if (abs(*elat) > 90. || abs(*elon) > 180. || *a > 90.) { 16918 goto L12; 16919 } 16920 16921 /* Compute a conversion factor CF for degrees to radians */ 16922 /* and compute the window radius WR. */ 16923 16924 cf = atan(1.) / 45.; 16925 wr = sin(cf * *a); 16926 wrs = wr * wr; 16927 16928 /* Compute the lower left (IPX1,IPY1) and upper right */ 16929 /* (IPX2,IPY2) corner coordinates of the bounding box. */ 16930 /* The coordinates, specified in default user space units */ 16931 /* (points, at 72 points/inch with origin at the lower */ 16932 /* left corner of the page), are chosen to preserve the */ 16933 /* square aspect ratio, and to center the plot on the 8.5 */ 16934 /* by 11 inch page. The center of the page is (306,396), */ 16935 /* and IR = PLTSIZ/2 in points. */ 16936 16937 d__1 = *pltsiz * 36.; 16938 ir = i_dnnt(&d__1); 16939 ipx1 = 306 - ir; 16940 ipx2 = ir + 306; 16941 ipy1 = 396 - ir; 16942 ipy2 = ir + 396; 16943 16944 /* Output header comments. */ 16945 16946 /* WRITE (LUN,100,ERR=13) IPX1, IPY1, IPX2, IPY2 */ 16947 /* 100 FORMAT ('%!PS-Adobe-3.0 EPSF-3.0'/ */ 16948 /* . '%%BoundingBox:',4I4/ */ 16949 /* . '%%Title: Voronoi diagram'/ */ 16950 /* . '%%Creator: STRIPACK'/ */ 16951 /* . '%%EndComments') */ 16952 /* Set (IPX1,IPY1) and (IPX2,IPY2) to the corner coordinates */ 16953 /* of a viewport box obtained by shrinking the bounding box */ 16954 /* by 12% in each dimension. */ 16955 16956 d__1 = (double) ir * .88; 16957 ir = i_dnnt(&d__1); 16958 ipx1 = 306 - ir; 16959 ipx2 = ir + 306; 16960 ipy1 = 396 - ir; 16961 ipy2 = ir + 396; 16962 16963 /* Set the line thickness to 2 points, and draw the */ 16964 /* viewport boundary. */ 16965 16966 t = 2.; 16967 /* WRITE (LUN,110,ERR=13) T */ 16968 /* WRITE (LUN,120,ERR=13) IR */ 16969 /* WRITE (LUN,130,ERR=13) */ 16970 /* 110 FORMAT (F12.6,' setlinewidth') */ 16971 /* 120 FORMAT ('306 396 ',I3,' 0 360 arc') */ 16972 /* 130 FORMAT ('stroke') */ 16973 16974 /* Set up an affine mapping from the window box [-WR,WR] X */ 16975 /* [-WR,WR] to the viewport box. */ 16976 16977 sf = (double) ir / wr; 16978 tx = ipx1 + sf * wr; 16979 ty = ipy1 + sf * wr; 16980 /* WRITE (LUN,140,ERR=13) TX, TY, SF, SF */ 16981 /* 140 FORMAT (2F12.6,' translate'/ */ 16982 /* . 2F12.6,' scale') */ 16983 16984 /* The line thickness must be changed to reflect the new */ 16985 /* scaling which is applied to all subsequent output. */ 16986 /* Set it to 1.0 point. */ 16987 16988 t = 1. / sf; 16989 /* WRITE (LUN,110,ERR=13) T */ 16990 16991 /* Save the current graphics state, and set the clip path to */ 16992 /* the boundary of the window. */ 16993 16994 /* WRITE (LUN,150,ERR=13) */ 16995 /* WRITE (LUN,160,ERR=13) WR */ 16996 /* WRITE (LUN,170,ERR=13) */ 16997 /* 150 FORMAT ('gsave') */ 16998 /* 160 FORMAT ('0 0 ',F12.6,' 0 360 arc') */ 16999 /* 170 FORMAT ('clip newpath') */ 17000 17001 /* Compute the Cartesian coordinates of E and the components */ 17002 /* of a rotation R which maps E to the north pole (0,0,1). */ 17003 /* R is taken to be a rotation about the z-axis (into the */ 17004 /* yz-plane) followed by a rotation about the x-axis chosen */ 17005 /* so that the view-up direction is (0,0,1), or (-1,0,0) if */ 17006 /* E is the north or south pole. */ 17007 17008 /* ( R11 R12 0 ) */ 17009 /* R = ( R21 R22 R23 ) */ 17010 /* ( EX EY EZ ) */ 17011 17012 t = cf * *elon; 17013 ct = cos(cf * *elat); 17014 ex = ct * cos(t); 17015 ey = ct * sin(t); 17016 ez = sin(cf * *elat); 17017 if (ct != 0.) { 17018 r11 = -ey / ct; 17019 r12 = ex / ct; 17020 } else { 17021 r11 = 0.; 17022 r12 = 1.; 17023 } 17024 r21 = -ez * r12; 17025 r22 = ez * r11; 17026 r23 = ct; 17027 17028 /* Loop on nodes (Voronoi centers) N0. */ 17029 /* LPL indexes the last neighbor of N0. */ 17030 17031 i__1 = *n; 17032 for (n0 = 1; n0 <= i__1; ++n0) { 17033 lpl = lend[n0]; 17034 17035 /* Set KV2 to the first (and last) vertex index and compute */ 17036 /* its coordinates P2 in the rotated coordinate system. */ 17037 17038 kv2 = listc[lpl]; 17039 p2[0] = r11 * xc[kv2] + r12 * yc[kv2]; 17040 p2[1] = r21 * xc[kv2] + r22 * yc[kv2] + r23 * zc[kv2]; 17041 p2[2] = ex * xc[kv2] + ey * yc[kv2] + ez * zc[kv2]; 17042 17043 /* IN2 = TRUE iff KV2 is in the window. */ 17044 17045 in2 = p2[2] >= 0. && p2[0] * p2[0] + p2[1] * p2[1] <= wrs; 17046 17047 /* Loop on neighbors N1 of N0. For each triangulation edge */ 17048 /* N0-N1, KV1-KV2 is the corresponding Voronoi edge. */ 17049 17050 lp = lpl; 17051 L1: 17052 lp = lptr[lp]; 17053 kv1 = kv2; 17054 p1[0] = p2[0]; 17055 p1[1] = p2[1]; 17056 p1[2] = p2[2]; 17057 in1 = in2; 17058 kv2 = listc[lp]; 17059 17060 /* Compute the new values of P2 and IN2. */ 17061 17062 p2[0] = r11 * xc[kv2] + r12 * yc[kv2]; 17063 p2[1] = r21 * xc[kv2] + r22 * yc[kv2] + r23 * zc[kv2]; 17064 p2[2] = ex * xc[kv2] + ey * yc[kv2] + ez * zc[kv2]; 17065 in2 = p2[2] >= 0. && p2[0] * p2[0] + p2[1] * p2[1] <= wrs; 17066 17067 /* Add edge KV1-KV2 to the path iff both endpoints are inside */ 17068 /* the window and KV2 > KV1, or KV1 is inside and KV2 is */ 17069 /* outside (so that the edge is drawn only once). */ 17070 17071 if (! in1 || (in2 && kv2 <= kv1)) { 17072 goto L2; 17073 } 17074 if (p2[2] < 0.) { 17075 17076 /* KV2 is a 'southern hemisphere' point. Move it to the */ 17077 /* intersection of edge KV1-KV2 with the equator so that */ 17078 /* the edge is clipped properly. P2(3) is set to 0. */ 17079 17080 p2[0] = p1[2] * p2[0] - p2[2] * p1[0]; 17081 p2[1] = p1[2] * p2[1] - p2[2] * p1[1]; 17082 t = sqrt(p2[0] * p2[0] + p2[1] * p2[1]); 17083 p2[0] /= t; 17084 p2[1] /= t; 17085 } 17086 17087 /* Add the edge to the path. (TOL is converted to world */ 17088 /* coordinates.) */ 17089 17090 if (p2[2] < 0.) { 17091 p2[2] = 0.f; 17092 } 17093 d__1 = tol / sf; 17094 drwarc_(lun, p1, p2, &d__1, &nseg); 17095 17096 /* Bottom of loops. */ 17097 17098 L2: 17099 if (lp != lpl) { 17100 goto L1; 17101 } 17102 /* L3: */ 17103 } 17104 17105 /* Paint the path and restore the saved graphics state (with */ 17106 /* no clip path). */ 17107 17108 /* WRITE (LUN,130,ERR=13) */ 17109 /* WRITE (LUN,190,ERR=13) */ 17110 /* 190 FORMAT ('grestore') */ 17111 if (*numbr) { 17112 17113 /* Nodes in the window are to be labeled with their indexes. */ 17114 /* Convert FSIZN from points to world coordinates, and */ 17115 /* output the commands to select a font and scale it. */ 17116 17117 t = fsizn / sf; 17118 /* WRITE (LUN,200,ERR=13) T */ 17119 /* 200 FORMAT ('/Helvetica findfont'/ */ 17120 /* . F12.6,' scalefont setfont') */ 17121 17122 /* Loop on visible nodes N0 that project to points (X0,Y0) in */ 17123 /* the window. */ 17124 17125 i__1 = *n; 17126 for (n0 = 1; n0 <= i__1; ++n0) { 17127 if (ex * x[n0] + ey * y[n0] + ez * z__[n0] < 0.) { 17128 goto L4; 17129 } 17130 x0 = r11 * x[n0] + r12 * y[n0]; 17131 y0 = r21 * x[n0] + r22 * y[n0] + r23 * z__[n0]; 17132 if (x0 * x0 + y0 * y0 > wrs) { 17133 goto L4; 17134 } 17135 17136 /* Move to (X0,Y0), and draw the label N0 with the origin */ 17137 /* of the first character at (X0,Y0). */ 17138 17139 /* WRITE (LUN,210,ERR=13) X0, Y0 */ 17140 /* WRITE (LUN,220,ERR=13) N0 */ 17141 /* 210 FORMAT (2F12.6,' moveto') */ 17142 /* 220 FORMAT ('(',I3,') show') */ 17143 L4: 17144 ; 17145 } 17146 } 17147 17148 /* Convert FSIZT from points to world coordinates, and output */ 17149 /* the commands to select a font and scale it. */ 17150 17151 t = fsizt / sf; 17152 /* WRITE (LUN,200,ERR=13) T */ 17153 17154 /* Display TITLE centered above the plot: */ 17155 17156 y0 = wr + t * 3.; 17157 /* WRITE (LUN,230,ERR=13) TITLE, Y0 */ 17158 /* 230 FORMAT (A80/' stringwidth pop 2 div neg ',F12.6, */ 17159 /* . ' moveto') */ 17160 /* WRITE (LUN,240,ERR=13) TITLE */ 17161 /* 240 FORMAT (A80/' show') */ 17162 if (annot) { 17163 17164 /* Display the window center and radius below the plot. */ 17165 17166 x0 = -wr; 17167 y0 = -wr - 50. / sf; 17168 /* WRITE (LUN,210,ERR=13) X0, Y0 */ 17169 /* WRITE (LUN,250,ERR=13) ELAT, ELON */ 17170 y0 -= t * 2.; 17171 /* WRITE (LUN,210,ERR=13) X0, Y0 */ 17172 /* WRITE (LUN,260,ERR=13) A */ 17173 /* 250 FORMAT ('(Window center: ELAT = ',F7.2, */ 17174 /* . ', ELON = ',F8.2,') show') */ 17175 /* 260 FORMAT ('(Angular extent: A = ',F5.2,') show') */ 17176 } 17177 17178 /* Paint the path and output the showpage command and */ 17179 /* end-of-file indicator. */ 17180 17181 /* WRITE (LUN,270,ERR=13) */ 17182 /* 270 FORMAT ('stroke'/ */ 17183 /* . 'showpage'/ */ 17184 /* . '%%EOF') */ 17185 17186 /* HP's interpreters require a one-byte End-of-PostScript-Job */ 17187 /* indicator (to eliminate a timeout error message): */ 17188 /* ASCII 4. */ 17189 17190 /* WRITE (LUN,280,ERR=13) CHAR(4) */ 17191 /* 280 FORMAT (A1) */ 17192 17193 /* No error encountered. */ 17194 17195 *ier = 0; 17196 return 0; 17197 17198 /* Invalid input parameter LUN, PLTSIZ, N, or NT. */ 17199 17200 L11: 17201 *ier = 1; 17202 return 0; 17203 17204 /* Invalid input parameter ELAT, ELON, or A. */ 17205 17206 L12: 17207 *ier = 2; 17208 return 0; 17209 17210 /* Error writing to unit LUN. */ 17211 17212 /* L13: */ 17213 *ier = 3; 17214 return 0; 17215 } /* vrplot_ */
int branch_all = 0 |
Definition at line 21363 of file util_sparx.cpp.
int* costlist_global |
Definition at line 21519 of file util_sparx.cpp.