├── MANIFEST.in ├── lib └── mpl_toolkits │ ├── __init__.py │ └── natgrid │ └── __init__.py ├── Changelog ├── setupegg.py ├── test.py ├── src ├── nntpvrs.h ├── nnexver.h ├── nnuheadd.h ├── nncheads.h ├── nnuheads.h ├── nngheads.h ├── nngheadd.h ├── nncheadd.h ├── nntypes.h ├── nnuhead.h ├── natgrid.c ├── nnghead.h ├── nnchead.h ├── _natgrid.pyx ├── nnmhead.h ├── ncarg │ └── ngmath.h ├── nnusers.c ├── nnuserd.c ├── nnculls.c ├── nnculld.c ├── nnuser.c ├── nnerror.c ├── natgrids.c ├── natgridd.c ├── nncrunchd.c ├── nncrunchs.c └── nncrunch.c ├── setup.py ├── README └── Copyright.txt /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include MANIFEST.in 2 | include Copyright.txt 3 | include setupegg.py 4 | include test.py 5 | include src/*.h 6 | include src/ncarg/*h 7 | -------------------------------------------------------------------------------- /lib/mpl_toolkits/__init__.py: -------------------------------------------------------------------------------- 1 | try: 2 | __import__('pkg_resources').declare_namespace(__name__) 3 | except ImportError: 4 | pass # must not have setuptools 5 | -------------------------------------------------------------------------------- /Changelog: -------------------------------------------------------------------------------- 1 | version 0.2: 2 | * updated c code from NCL 5.2.0. Now automatically removes duplicate points. 3 | version 0.1: 4 | * initial release. c source code from NCL 5.0.0. 5 | 6 | -------------------------------------------------------------------------------- /setupegg.py: -------------------------------------------------------------------------------- 1 | """ 2 | Poor man's setuptools script... 3 | """ 4 | 5 | from setuptools import setup 6 | execfile('setup.py', 7 | {'additional_params' : 8 | {'namespace_packages' : ['mpl_toolkits']}}) 9 | -------------------------------------------------------------------------------- /lib/mpl_toolkits/natgrid/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = '0.2' 2 | __doc__ = """ 3 | Python interface to NCAR natgrid library. If installed, used 4 | by matplotlib griddata function. Not intended to be accessed directly by users.""" 5 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | from matplotlib.mlab import griddata 2 | import numpy as np 3 | # test case that scikits.delaunay fails on, but natgrid passes.. 4 | data = np.array([[-1, -1], [-1, 0], [-1, 1], 5 | [ 0, -1], [ 0, 0], [ 0, 1], 6 | [ 1, -1 - np.finfo(np.float_).eps], [ 1, 0], [ 1, 1], 7 | ]) 8 | x = data[:,0] 9 | y = data[:,1] 10 | z = x*np.exp(-x**2-y**2) 11 | # define grid. 12 | xi = np.linspace(-1.1,1.1,100) 13 | yi = np.linspace(-1.1,1.1,100) 14 | # grid the data. 15 | zi = griddata(x,y,z,xi,yi) 16 | -------------------------------------------------------------------------------- /src/nntpvrs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nntpvrs.h,v 1.4 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | struct datum *rootdat, *curdat, *holddat; 15 | struct simp *rootsimp, *cursimp, *holdsimp, *lastsimp, *prevsimp; 16 | struct temp *roottemp, *curtemp, *lasttemp, *prevtemp; 17 | struct neig *rootneig, *curneig, *lastneig; 18 | struct asinfo curas; 19 | -------------------------------------------------------------------------------- /src/nnexver.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nnexver.h,v 1.4 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | extern struct datum *rootdat, *curdat, *holddat; 15 | extern struct simp *rootsimp, *cursimp, *holdsimp, *lastsimp, *prevsimp; 16 | extern struct temp *roottemp, *curtemp, *lasttemp, *prevtemp; 17 | extern struct neig *rootneig, *curneig, *lastneig; 18 | extern struct asinfo curas; 19 | -------------------------------------------------------------------------------- /src/nnuheadd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nnuheadd.h,v 1.11 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include 15 | 16 | extern void c_nngetsloped(int, int, double *, int *); 17 | extern void c_nngetaspectd(int, int, double *, int *); 18 | extern void c_nnpntinitd(int, double *, double *, double *); 19 | extern void c_nnpntd(double, double, double *); 20 | extern void c_nnpntendd(); 21 | -------------------------------------------------------------------------------- /src/nncheads.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nncheads.h,v 1.7 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include 15 | extern double armin(int, float *); 16 | extern double armax(int, float *); 17 | 18 | extern void Initialize(int, float [], float [], int, int, 19 | float [], float []); 20 | int ReadData(int, float *, float *, float *); 21 | float **MakeGrid(int, int, float *, float *); 22 | -------------------------------------------------------------------------------- /src/nnuheads.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nnuheads.h,v 1.12 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include 15 | 16 | extern void c_nngetslopes(int, int, float *, int *); 17 | extern void c_nngetaspects(int, int, float *, int *); 18 | extern void c_nnpntinits(int, float *, float *, float *); 19 | extern void c_nnpnts(float, float, float *); 20 | extern void c_nnpntend(); 21 | extern void c_nngetwts(int *, int *, float *, float *, float *, float *); 22 | extern void c_nngetwtsd(int *, int *, double *, double *, double *, double *); 23 | -------------------------------------------------------------------------------- /src/nngheads.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nngheads.h,v 1.6 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | void Initialize(int, float [], float [], int, int, 15 | float [], float []); 16 | 17 | double armin(int, float *); 18 | double armax(int, float *); 19 | 20 | extern int ReadData(); 21 | extern float **MakeGrid(int, int, float *, float *); 22 | 23 | extern void c_nnsetr(char *, float); 24 | extern void c_nngetr(char *, float *); 25 | 26 | extern void Terminate(); 27 | 28 | extern int cull_striples(int, float *); 29 | extern int comp_striples(const void *, const void *); 30 | -------------------------------------------------------------------------------- /src/nngheadd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nngheadd.h,v 1.6 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | void Initialized(int, double [], double [], int, int, 15 | double [], double []); 16 | 17 | double armind(int, double *); 18 | double armaxd(int, double *); 19 | 20 | extern int ReadDatad(); 21 | extern double **MakeGridd(int, int, double *, double *); 22 | 23 | extern void c_nnsetrd(char *, double); 24 | extern void c_nngetrd(char *, double *); 25 | 26 | extern void Terminate(); 27 | 28 | extern int cull_dtriples(int, double *); 29 | extern int comp_dtriples(const void *, const void *); 30 | -------------------------------------------------------------------------------- /src/nncheadd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nncheadd.h,v 1.6 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include 15 | 16 | struct asinfod 17 | { int crows; 18 | int ccols; 19 | double **aspect_outd; 20 | double **slope_outd; 21 | }; 22 | struct asinfod curasd; 23 | 24 | extern double armind(int, double *); 25 | extern double armaxd(int, double *); 26 | 27 | extern void Initialized(int, double [], double [], int, int, 28 | double [], double []); 29 | 30 | int ReadDatad(int, double *, double *, double *); 31 | double **MakeGridd(int, int, double *, double *); 32 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import glob 2 | from distutils.core import setup, Extension 3 | deps = glob.glob('src/*.c') 4 | packages = ['mpl_toolkits','mpl_toolkits.natgrid'] 5 | package_dirs = {'':'lib'} 6 | extensions = [Extension("mpl_toolkits.natgrid._natgrid",deps,include_dirs = ['src'],)] 7 | setup( 8 | name = "natgrid", 9 | version = "0.2.1", 10 | description = "Python interface to NCAR natgrid library", 11 | url = "http://matplotlib.sourceforge.net/toolkits.html", 12 | download_url = "http://sourceforge.net/projects/matplotlib", 13 | author = "Jeff Whitaker", 14 | author_email = "jeffrey.s.whitaker@noaa.gov", 15 | platforms = ["any"], 16 | license = "Restricted", 17 | keywords = ["python","plotting","plots","graphs","charts","GIS","mapping","map projections","maps"], 18 | classifiers = ["Development Status :: 4 - Beta", 19 | "Intended Audience :: Science/Research", 20 | "License :: OSI Approved", 21 | "Topic :: Scientific/Engineering :: Visualization", 22 | "Topic :: Software Development :: Libraries :: Python Modules", 23 | "Operating System :: OS Independent"], 24 | packages = packages, 25 | package_dir = package_dirs, 26 | ext_modules = extensions, 27 | ) 28 | -------------------------------------------------------------------------------- /src/nntypes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nntypes.h,v 1.4 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | struct datum 15 | { double values[3]; 16 | struct datum *nextdat; 17 | }; 18 | 19 | struct simp 20 | { int vert[3]; 21 | double cent[3]; 22 | struct simp *nextsimp; 23 | }; 24 | 25 | struct temp 26 | { int end[2]; 27 | struct temp *nexttemp; 28 | }; 29 | 30 | struct neig 31 | { int neinum; 32 | double narea; 33 | double coord; 34 | struct neig *nextneig; 35 | }; 36 | 37 | struct asinfo 38 | { int crows; 39 | int ccols; 40 | float **aspect_out; 41 | float **slope_out; 42 | }; 43 | -------------------------------------------------------------------------------- /src/nnuhead.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nnuhead.h,v 1.12 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include 15 | 16 | #define EQ == 17 | #define NE != 18 | #define AND && 19 | #define OR || 20 | 21 | extern int igrad, densi, non_neg, sdip, rads, 22 | optim, extrap, southhemi, updir, auto_scale, 23 | adf, nndup, single_point, maxmsg; 24 | 25 | extern double bI, bJ, magx, magy, 26 | magz, horilap, vertlap, nuldat, 27 | magx_auto, magy_auto, magz_auto, horilap_save, 28 | vertlap_save; 29 | 30 | extern char tri_file[], error_file[], emsg[]; 31 | 32 | extern void ErrorHnd(int, char *, FILE *, char *); 33 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Python interface to NCAR natgrid library 2 | (http://www.ncarg.ucar.edu//ngmath/natgrid/nnhome.html). 3 | 4 | When installed, will be used by the matplotlib.mlab griddata function. 5 | 6 | Not otherwise intended for public consumption. 7 | 8 | *LICENSE* 9 | 10 | NCAR natgrid source code licensed under the terms given in Copyright.txt, 11 | except for code in the file src/nncrunch.c, which is based on code written and 12 | copyrighted (C) by Dave Watson. Dr. Watson retains the copyright to his 13 | original code. 14 | 15 | The Python interface (src/_natgrid.pyx and src/_natgrid.c) are made available 16 | under the following license: 17 | 18 | copyright (c) 2007 by Jeffrey Whitaker. 19 | 20 | Permission to use, copy, modify, and distribute this software and its 21 | documentation for any purpose and without fee is hereby granted, 22 | provided that the above copyright notices appear in all copies and that 23 | both the copyright notices and this permission notice appear in 24 | supporting documentation. 25 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 26 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 27 | EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR 28 | CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 29 | USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 30 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 31 | PERFORMANCE OF THIS SOFTWARE. 32 | 33 | *Contact* 34 | 35 | Jeff Whitaker 36 | -------------------------------------------------------------------------------- /Copyright.txt: -------------------------------------------------------------------------------- 1 | NCL - UNIX Version 5.0.0 2 | Copyright (C) 2007 3 | University Corporation for Atmospheric Research 4 | 5 | NCL Source Code License 6 | 7 | Copyright (c) 2007 University Corporation for Atmospheric Research 8 | (UCAR). All rights reserved. Developed by NCAR's Computational and 9 | Information Systems Laboratory, UCAR, www.cisl.ucar.edu, with the 10 | following contributions: 11 | 12 | Redistribution and use in source and binary forms, with or without 13 | modification, are permitted provided that the following conditions are 14 | met: 15 | 16 | Neither the names of NCAR's Computational and Information Systems 17 | Laboratory, the University Corporation for Atmospheric Research, nor 18 | the names of its contributors may be used to endorse or promote 19 | products derived from this Software without specific prior written 20 | permission. 21 | 22 | Redistributions of source code must retain the above copyright 23 | notice, this list of conditions, and the disclaimer below. 24 | 25 | Redistributions in binary form must reproduce the above copyright 26 | notice, this list of conditions, and the disclaimer below in the 27 | documentation and/or other materials provided with the distribution. 28 | 29 | THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 30 | EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF 31 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 32 | NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT 33 | HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL, 34 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN 35 | ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 36 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE 37 | SOFTWARE. 38 | -------------------------------------------------------------------------------- /src/natgrid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: natgrid.c,v 1.7 2008/07/27 03:10:12 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | /* 15 | * This file contains the settings for most of the 16 | * global variables by way of including nnmhead.h . 17 | */ 18 | 19 | #include "nnmhead.h" 20 | #include "nnghead.h" 21 | #include "nntypes.h" 22 | #include "nntpvrs.h" 23 | #include "nnexver.h" 24 | 25 | void Terminate() 26 | { 27 | struct simp *tmp,*tmp0; 28 | struct datum *dtmp,*dtmp0; 29 | struct neig *ntmp,*ntmp0; 30 | struct temp *ttmp,*ttmp0; 31 | tmp = rootsimp; 32 | while(tmp!=NULL) { 33 | tmp0 =tmp->nextsimp; 34 | free(tmp); 35 | tmp = tmp0; 36 | } 37 | rootsimp = cursimp = holdsimp = lastsimp = prevsimp = NULL; 38 | dtmp = rootdat; 39 | while(dtmp!=NULL) { 40 | dtmp0 =dtmp->nextdat; 41 | free(dtmp); 42 | dtmp = dtmp0; 43 | } 44 | rootdat = curdat = holddat = NULL; 45 | ntmp = rootneig; 46 | while(ntmp!=NULL) { 47 | ntmp0 =ntmp->nextneig; 48 | free(ntmp); 49 | ntmp = ntmp0; 50 | } 51 | rootneig = curneig = lastneig = NULL; 52 | ttmp = roottemp; 53 | while(ttmp!=NULL) { 54 | ttmp0 =ttmp->nexttemp; 55 | free(ttmp); 56 | ttmp = ttmp0; 57 | } 58 | roottemp = curtemp = lasttemp= prevtemp= NULL; 59 | 60 | if(points!=NULL) { 61 | FreeMatrixd(points); 62 | points = NULL; 63 | } 64 | if(joints!=NULL) { 65 | FreeMatrixd(joints); 66 | joints = NULL; 67 | } 68 | if(jndx != NULL) { 69 | FreeVecti(jndx); 70 | jndx = NULL; 71 | } 72 | if(wts != NULL) { 73 | free(wts); 74 | } 75 | if(nbrs != NULL) { 76 | free(nbrs); 77 | } 78 | 79 | magx = magx_orig; 80 | magy = magy_orig; 81 | magz = magz_orig; 82 | } 83 | -------------------------------------------------------------------------------- /src/nnghead.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nnghead.h,v 1.10 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #define RANSEED 367367 20 | #define BIGNUM 1E37 21 | #define EPSILON 0.00001 22 | #define EQ == 23 | #define NE != 24 | #define AND && 25 | #define OR || 26 | 27 | extern double **points, **joints, wbit, 28 | horilap, vertlap, bI, bJ, nuldat, 29 | xstart, ystart, xend, yend, 30 | maxhoriz, aaa, bbb, ccc, det, 31 | work3[3][3], xx, sumx, sumy, sumz, 32 | sumx2, sumy2, sumxy, sumxz, sumyz, 33 | asum, nn_pi, piby2, piby32, rad2deg, 34 | bigtri[3][3], horilap_save, vertlap_save; 35 | 36 | extern double magx, magy, magz, magx_orig, magy_orig, magz_orig, 37 | maxxy[2][3], magx_auto, magy_auto, magz_auto, *wts; 38 | 39 | extern int igrad, non_neg, densi, sdip, rads, southhemi, 40 | extrap, adf, nndup, maxmsg; 41 | 42 | extern int datcnt, datcnt3, numtri, imag, numnei, iscale, 43 | ext, *jndx, neicnt, optim, goodflag, updir, 44 | scor[3][2], auto_scale, 45 | single_point, first_single, asflag, 46 | error_status, *nbrs, jwts, num_wts; 47 | 48 | extern char tri_file[256], error_file[256], emsg[256]; 49 | 50 | extern void Gradient(); 51 | extern void ErrorHnd(int, char *, FILE *, char *); 52 | extern void CircOut(); 53 | 54 | extern void c_nnsetc(char *, char *); 55 | extern void c_nngetc(char *, char *); 56 | extern void c_nnseti(char *, int); 57 | extern void c_nngeti(char *, int *); 58 | -------------------------------------------------------------------------------- /src/nnchead.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nnchead.h,v 1.11 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #define SQ(x) (x) * (x) 19 | #define BIGNUM 1E37 20 | #define EPSILON 0.00001 21 | #define RANGE 10 22 | #define EQ == 23 | #define NE != 24 | #define AND && 25 | #define OR || 26 | 27 | extern double **points, **joints, wbit, 28 | horilap, vertlap, bI, bJ, nuldat, 29 | xstart, ystart, xend, yend, 30 | maxhoriz, aaa, bbb, ccc, det, 31 | work3[3][3], xx, sumx, sumy, sumz, 32 | sumx2, sumy2, sumxy, sumxz, sumyz, 33 | asum, nn_pi, piby2, piby32, rad2deg, 34 | bigtri[3][3], horilap_save, vertlap_save; 35 | 36 | extern double magx, magy, magz, magx_orig, magy_orig, magz_orig, 37 | maxxy[2][3], magx_auto, magy_auto, magz_auto, *wts; 38 | 39 | extern int igrad, non_neg, densi, sdip, rads, southhemi, 40 | extrap, adf, nndup, maxmsg; 41 | 42 | extern int datcnt, datcnt3, numtri, imag, numnei, iscale, 43 | ext, *jndx, neicnt, optim, goodflag, updir, 44 | scor[3][2], auto_scale, 45 | single_point, first_single, asflag, 46 | error_status, *nbrs, jwts, num_wts; 47 | 48 | extern char tri_file[256], error_file[256], emsg[256]; 49 | 50 | extern void Terminate(); 51 | extern void ErrorHnd(int, char *, FILE *, char *); 52 | 53 | void FindNeigh(); 54 | void TriNeigh(); 55 | void Gradient(); 56 | void FindProp(); 57 | double Surface(); 58 | double Meld(); 59 | void TooSteep(); 60 | void TooShallow(); 61 | void TooNarrow(); 62 | struct datum *IMakeDatum(); 63 | struct simp *IMakeSimp(); 64 | struct temp *IMakeTemp(); 65 | struct neig *IMakeNeig(); 66 | int *IntVect(); 67 | void FreeVecti(); 68 | double *DoubleVect(); 69 | void FreeVectd(); 70 | int **IntMatrix(); 71 | void FreeMatrixi(); 72 | float **FloatMatrix(); 73 | void FreeMatrixf(); 74 | double **DoubleMatrix(); 75 | void FreeMatrixd(); 76 | -------------------------------------------------------------------------------- /src/_natgrid.pyx: -------------------------------------------------------------------------------- 1 | """ 2 | Pyrex wrapper for NCAR natgrid library for interpolation 3 | of irregularly spaced data to a grid. 4 | 5 | copyright (c) 2007 by Jeffrey Whitaker. 6 | 7 | Permission to use, copy, modify, and distribute this software and its 8 | documentation for any purpose and without fee is hereby granted, 9 | provided that the above copyright notices appear in all copies and that 10 | both the copyright notices and this permission notice appear in 11 | supporting documentation. 12 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 13 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO 14 | EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR 15 | CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 16 | USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 17 | OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 18 | PERFORMANCE OF THIS SOFTWARE. 19 | """ 20 | 21 | # Pyrex generates nnint.c from this file, so make changes here 22 | # and re-create nnint.c with "pyrexc nnint.pyx". 23 | 24 | cdef extern void c_nnseti(char *pnam, int ival) 25 | cdef extern double *c_natgridd(int n, double *x, double *y, double *z, int numxout, int numyout, double *xo, double *yo, int *ier) 26 | cdef extern void c_nnsetr(char *pnam, float fval) 27 | 28 | cdef extern from "Python.h": 29 | int PyObject_AsWriteBuffer(object, void **rbuf, Py_ssize_t *len) 30 | char *PyString_AsString(object) 31 | 32 | def seti(name, value): 33 | cdef char *pnam 34 | cdef int ival 35 | pnam = name; ival = value 36 | c_nnseti(pnam, ival) 37 | 38 | def setr(name, value): 39 | cdef char *pnam 40 | cdef float fval 41 | pnam = name; fval = value 42 | c_nnsetr(pnam, fval) 43 | 44 | def natgridd(x, y, z, xo, yo, zo): 45 | cdef int npnts, numxout, numyout, ier 46 | cdef Py_ssize_t buflenx, bufleny, buflenz, buflenxo, buflenyo, buflenzo 47 | cdef void *xp, *yp, *zp, *xop, *yop, *zop 48 | cdef double *xd, *yd, *zd, *xod, *yod, *zod, *out 49 | npnts = len(x) 50 | numxout = len(xo) 51 | numyout = len(yo) 52 | if PyObject_AsWriteBuffer(x, &xp, &buflenx) <> 0: 53 | raise RuntimeError('error getting buffer for x') 54 | if PyObject_AsWriteBuffer(y, &yp, &bufleny) <> 0: 55 | raise RuntimeError('error getting buffer for y') 56 | if PyObject_AsWriteBuffer(z, &zp, &buflenz) <> 0: 57 | raise RuntimeError('error getting buffer for z') 58 | xd = xp 59 | yd = yp 60 | zd = zp 61 | if PyObject_AsWriteBuffer(xo, &xop, &buflenxo) <> 0: 62 | raise RuntimeError('error getting buffer for x') 63 | if PyObject_AsWriteBuffer(yo, &yop, &buflenyo) <> 0: 64 | raise RuntimeError('error getting buffer for y') 65 | if PyObject_AsWriteBuffer(zo, &zop, &buflenzo) <> 0: 66 | raise RuntimeError('error getting buffer for z') 67 | xod = xop 68 | yod = yop 69 | zod = zop 70 | # output overwrites zo. 71 | out = c_natgridd(npnts, yd, xd, zd, numyout, numxout, yod, xod, &ier) 72 | for i from 0 <= i < buflenzo/8: 73 | zod[i] = out[i] 74 | if ier != 0: 75 | raise RuntimeError('error in natgridd - ier ='%ier) 76 | -------------------------------------------------------------------------------- /src/nnmhead.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nnmhead.h,v 1.13 2008/07/27 04:02:37 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #define SQ(x) (x) * (x) 19 | #define RANSEED 367367 20 | #define BIGNUM 1E37 21 | #define EPSILON 0.00001 22 | #define EQ == 23 | #define NE != 24 | #define AND && 25 | #define OR || 26 | 27 | double **points, **joints, wbit, 28 | horilap = -1., vertlap = -1., bI = 1.5, bJ = 7.0, nuldat = 0.0, 29 | xstart, ystart, xend, yend, 30 | maxhoriz, aaa, bbb, ccc, det, 31 | work3[3][3], xx, sumx, sumy, sumz, 32 | sumx2, sumy2, sumxy, sumxz, sumyz, 33 | asum, nn_pi, piby2, piby32, rad2deg, 34 | bigtri[3][3], horilap_save, vertlap_save; 35 | 36 | double magx = 1, magy = 1, magz = 1, magx_orig, magy_orig, magz_orig, 37 | maxxy[2][3], magx_auto, magy_auto, magz_auto, *wts; 38 | 39 | int igrad = 0, non_neg = 0, densi, sdip = 0, rads = 0, southhemi = 0, 40 | extrap = 1, adf = 0, nndup = 1, maxmsg = 10; 41 | 42 | int datcnt, datcnt3, numtri, imag, numnei, iscale, 43 | ext, *jndx, neicnt, optim = 1, goodflag, updir = 1, 44 | scor[3][2] = {{1,2}, {2,0}, {0,1}}, auto_scale = 1, 45 | single_point = 0, first_single = 1, asflag = 1, 46 | error_status = 0, *nbrs, jwts = 0, num_wts; 47 | 48 | char tri_file[256] = {"nnalg.dat"}, error_file[256] = {"stderr"}, 49 | emsg[256]; 50 | 51 | extern void Gradient(); 52 | extern void ErrorHnd(int, char *, FILE *, char *); 53 | extern void CircOut(); 54 | 55 | extern void c_nnsetc(char *, char *); 56 | extern void c_nngetc(char *, char *); 57 | extern void c_nnseti(char *, int); 58 | extern void c_nngeti(char *, int *); 59 | 60 | extern void Terminate(); 61 | extern void ErrorHnd(int, char *, FILE *, char *); 62 | 63 | void FindNeigh(); 64 | void TriNeigh(); 65 | void Gradient(); 66 | void FindProp(); 67 | double Surface(); 68 | double Meld(); 69 | void TooSteep(); 70 | void TooShallow(); 71 | void TooNarrow(); 72 | struct datum *IMakeDatum(); 73 | struct simp *IMakeSimp(); 74 | struct temp *IMakeTemp(); 75 | struct neig *IMakeNeig(); 76 | int *IntVect(); 77 | void FreeVecti(); 78 | double *DoubleVect(); 79 | void FreeVectd(); 80 | int **IntMatrix(); 81 | void FreeMatrixi(); 82 | float **FloatMatrix(); 83 | void FreeMatrixf(); 84 | double **DoubleMatrix(); 85 | void FreeMatrixd(); 86 | -------------------------------------------------------------------------------- /src/ncarg/ngmath.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: ngmath.h.sed,v 1.3 2008/07/27 04:02:35 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | 15 | /* 16 | * This file contains some system includes used by Ngmath functions, 17 | * a source for the NGCALLF macro, the function prototypes for all 18 | * user entry points in the Ngmath library, and some specific defines. 19 | */ 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | /* 27 | * Fortran function macro. This macro is used to provide the appropriate 28 | * system-specific C function name for it to be Fortran callable. 29 | */ 30 | 31 | /* 32 | * Function prototypes for the natgrid package. 33 | */ 34 | 35 | /* was duplicated in nnuhead.h */ 36 | void c_nnseti(char *, int); 37 | void c_nngeti(char *, int *); 38 | void c_nnsetr(char *, float); 39 | void c_nngetr(char *, float *); 40 | 41 | /* was duplicated in nnuheads.h */ 42 | void c_nnsetc(char *, char *); 43 | void c_nngetc(char *, char *); 44 | float *c_natgrids(int, float [], float [], float [], 45 | int, int, float [], float [], int *); 46 | 47 | /* was duplicated in nncheads.h */ 48 | void c_nngetslopes(int, int, float *, int *); 49 | void c_nngetaspects(int, int, float *, int *); 50 | void c_nnpntinits(int, float [], float [], float []); 51 | void c_nnpnts(float, float, float *); 52 | void c_nnpntend(); 53 | void c_nngetwts(int *, int *, float *, float *, float *, float *); 54 | 55 | /* was duplicated in nnuheadd.h */ 56 | void c_nnsetrd(char *, double); 57 | void c_nngetrd(char *, double *); 58 | double *c_natgridd(int, double [], double [], double [], 59 | int, int, double [], double [], int *); 60 | 61 | /* was duplicated in nncheadd.h */ 62 | void c_nngetsloped(int, int, double *, int *); 63 | void c_nngetaspectd(int, int, double *, int *); 64 | void c_nnpntinitd(int, double [], double [], double []); 65 | void c_nnpntd(double, double, double *); 66 | void c_nnpntendd(); 67 | void c_nngetwtsd(int *, int *, double *, double *, double *, double *); 68 | 69 | #ifdef UNICOS 70 | #include 71 | #define NGstring _fcd 72 | #define NGCstrToFstr(cstr,len) ((cstr)?_cptofcd((char *)cstr,len):_cptofcd("",0) 73 | ) 74 | #define NGFstrToCstr(fstr) (_fcdtocp(fstr)) 75 | #define NGFlgclToClgcl(flog) (_ltob(&flog)) 76 | #define NGClgclToFlgcl(clog) (_btol(clog)) 77 | float *c_natgrids(int, float [], float [], float [], 78 | float *c_natgrids(int, float [], float [], float [], 79 | float *c_natgrids(int, float [], float [], float [], 80 | float *c_natgrids(int, float [], float [], float [], 81 | int, int, float [], float [], int *); 82 | int, int, float [], float [], int *); 83 | int, int, float [], float [], int *); 84 | int, int, float [], float [], int *); 85 | #else 86 | #define NGstring char * 87 | #define NGCstrToFstr(cstr,len) (char *)cstr 88 | #define NGFstrToCstr(fstr) fstr 89 | #define NGFlgclToClgcl(flog) flog 90 | #define NGClgclToFlgcl(clog) clog 91 | #endif 92 | 93 | #define NGSTRLEN(cstr) ((cstr)?strlen(cstr):0) 94 | 95 | -------------------------------------------------------------------------------- /src/nnusers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nnusers.c,v 1.9 2008/07/27 03:10:13 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include "nnuheads.h" 15 | #include "nnuhead.h" 16 | 17 | 18 | /* 19 | * Get values for float parameters. 20 | */ 21 | void c_nngetr(char *pnam, float *dval) 22 | { 23 | if (!strncmp(pnam,"bi",2) OR !strncmp(pnam,"BI",2) OR 24 | !strncmp(pnam,"bI",2) OR !strncmp(pnam,"Bi",2)) { 25 | *dval = bI; 26 | } 27 | else if (!strncmp(pnam,"bj",2) OR !strncmp(pnam,"BJ",2) OR 28 | !strncmp(pnam,"bJ",2) OR !strncmp(pnam,"Bj",2)) { 29 | *dval = bJ; 30 | } 31 | else if (!strncmp(pnam,"magx",4) OR !strncmp(pnam,"MAGX",4)) { 32 | *dval = magx; 33 | } 34 | else if (!strncmp(pnam,"magy",4) OR !strncmp(pnam,"MAGY",4)) { 35 | *dval = magy; 36 | } 37 | else if (!strncmp(pnam,"magz",4) OR !strncmp(pnam,"MAGZ",4)) { 38 | *dval = magz; 39 | } 40 | else if (!strncmp(pnam,"hor",3) OR !strncmp(pnam,"HOR",3)) { 41 | *dval = horilap; 42 | } 43 | else if (!strncmp(pnam,"ver",3) OR !strncmp(pnam,"VER",3)) { 44 | *dval = vertlap; 45 | } 46 | else if (!strncmp(pnam,"nul",3) OR !strncmp(pnam,"NUL",3)) { 47 | *dval = nuldat; 48 | } 49 | else if (!strncmp(pnam,"xas",3) OR !strncmp(pnam,"XAS",3)) { 50 | *dval = magx_auto; 51 | } 52 | else if (!strncmp(pnam,"yas",3) OR !strncmp(pnam,"YAS",3)) { 53 | *dval = magy_auto; 54 | } 55 | else if (!strncmp(pnam,"zas",3) OR !strncmp(pnam,"ZAS",3)) { 56 | *dval = magz_auto; 57 | } 58 | else { 59 | sprintf(emsg,"\n Parameter name supplied is: %s\n",pnam); 60 | ErrorHnd(23, "c_nngetr", stderr, emsg); 61 | } 62 | } 63 | 64 | /* 65 | * Set values for float parameters. 66 | */ 67 | void c_nnsetr(char *pnam, float dval) 68 | { 69 | if (!strncmp(pnam,"bi",2) OR !strncmp(pnam,"BI",2) OR 70 | !strncmp(pnam,"bI",2) OR !strncmp(pnam,"Bi",2)) { 71 | if (dval < 1.) { 72 | bI = 1.; 73 | } 74 | else if (dval > 3.) { 75 | bI = 3.; 76 | } 77 | else { 78 | bI = dval; 79 | } 80 | } 81 | else if (!strncmp(pnam,"bj",2) OR !strncmp(pnam,"BJ",2) OR 82 | !strncmp(pnam,"bJ",2) OR !strncmp(pnam,"Bj",2)) { 83 | if (dval < 3.) { 84 | bJ = 3.; 85 | } 86 | else if (dval > 9.) { 87 | bJ = 9.; 88 | } 89 | else { 90 | bJ = dval; 91 | } 92 | } 93 | else if (!strncmp(pnam,"magx",4) OR !strncmp(pnam,"MAGX",4)) { 94 | magx = dval; 95 | } 96 | else if (!strncmp(pnam,"magy",4) OR !strncmp(pnam,"MAGY",4)) { 97 | magy = dval; 98 | } 99 | else if (!strncmp(pnam,"magz",4) OR !strncmp(pnam,"MAGZ",4)) { 100 | magz = dval; 101 | } 102 | else if (!strncmp(pnam,"hor",3) OR !strncmp(pnam,"HOR",3)) { 103 | horilap = dval; 104 | } 105 | else if (!strncmp(pnam,"ver",3) OR !strncmp(pnam,"VER",3)) { 106 | vertlap = dval; 107 | } 108 | else if (!strncmp(pnam,"nul",3) OR !strncmp(pnam,"NUL",3)) { 109 | nuldat = dval; 110 | } 111 | else { 112 | sprintf(emsg,"\n Parameter name supplied is: %s\n",pnam); 113 | ErrorHnd(23, "c_nnsetr", stderr, emsg); 114 | } 115 | } 116 | 117 | -------------------------------------------------------------------------------- /src/nnuserd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nnuserd.c,v 1.9 2008/07/27 03:10:13 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include "nnuheadd.h" 15 | #include "nnuhead.h" 16 | 17 | extern int error_status; 18 | 19 | /* 20 | * Get values for double parameters. 21 | */ 22 | void c_nngetrd(char *pnam, double *dval) 23 | { 24 | if (!strncmp(pnam,"bi",2) OR !strncmp(pnam,"BI",2) OR 25 | !strncmp(pnam,"bI",2) OR !strncmp(pnam,"Bi",2)) { 26 | *dval = bI; 27 | } 28 | else if (!strncmp(pnam,"bj",2) OR !strncmp(pnam,"BJ",2) OR 29 | !strncmp(pnam,"bJ",2) OR !strncmp(pnam,"Bj",2)) { 30 | *dval = bJ; 31 | } 32 | else if (!strncmp(pnam,"magx",4) OR !strncmp(pnam,"MAGX",4)) { 33 | *dval = magx; 34 | } 35 | else if (!strncmp(pnam,"magy",4) OR !strncmp(pnam,"MAGY",4)) { 36 | *dval = magy; 37 | } 38 | else if (!strncmp(pnam,"magz",4) OR !strncmp(pnam,"MAGZ",4)) { 39 | *dval = magz; 40 | } 41 | else if (!strncmp(pnam,"hor",3) OR !strncmp(pnam,"HOR",3)) { 42 | *dval = horilap; 43 | } 44 | else if (!strncmp(pnam,"ver",3) OR !strncmp(pnam,"VER",3)) { 45 | *dval = vertlap; 46 | } 47 | else if (!strncmp(pnam,"nul",3) OR !strncmp(pnam,"NUL",3)) { 48 | *dval = nuldat; 49 | } 50 | else if (!strncmp(pnam,"xas",3) OR !strncmp(pnam,"XAS",3)) { 51 | *dval = magx_auto; 52 | } 53 | else if (!strncmp(pnam,"yas",3) OR !strncmp(pnam,"YAS",3)) { 54 | *dval = magy_auto; 55 | } 56 | else if (!strncmp(pnam,"zas",3) OR !strncmp(pnam,"ZAS",3)) { 57 | *dval = magz_auto; 58 | } 59 | else { 60 | sprintf(emsg,"\n Parameter name supplied is: %s\n",pnam); 61 | ErrorHnd(23, "c_nngetrd", stderr, emsg); 62 | } 63 | } 64 | 65 | /* 66 | * Set values for double parameters. 67 | */ 68 | void c_nnsetrd(char *pnam, double dval) 69 | { 70 | if (!strncmp(pnam,"bi",2) OR !strncmp(pnam,"BI",2) OR 71 | !strncmp(pnam,"bI",2) OR !strncmp(pnam,"Bi",2)) { 72 | if (dval < 1.) { 73 | bI = 1.; 74 | } 75 | else if (dval > 3.) { 76 | bI = 3.; 77 | } 78 | else { 79 | bI = dval; 80 | } 81 | } 82 | else if (!strncmp(pnam,"bj",2) OR !strncmp(pnam,"BJ",2) OR 83 | !strncmp(pnam,"bJ",2) OR !strncmp(pnam,"Bj",2)) { 84 | if (dval < 3.) { 85 | bJ = 3.; 86 | } 87 | else if (dval > 9.) { 88 | bJ = 9.; 89 | } 90 | else { 91 | bJ = dval; 92 | } 93 | } 94 | else if (!strncmp(pnam,"magx",4) OR !strncmp(pnam,"MAGX",4)) { 95 | magx = dval; 96 | } 97 | else if (!strncmp(pnam,"magy",4) OR !strncmp(pnam,"MAGY",4)) { 98 | magy = dval; 99 | } 100 | else if (!strncmp(pnam,"magz",4) OR !strncmp(pnam,"MAGZ",4)) { 101 | magz = dval; 102 | } 103 | else if (!strncmp(pnam,"hor",3) OR !strncmp(pnam,"HOR",3)) { 104 | horilap = dval; 105 | } 106 | else if (!strncmp(pnam,"ver",3) OR !strncmp(pnam,"VER",3)) { 107 | vertlap = dval; 108 | } 109 | else if (!strncmp(pnam,"nul",3) OR !strncmp(pnam,"NUL",3)) { 110 | nuldat = dval; 111 | } 112 | else { 113 | sprintf(emsg,"\n Parameter name supplied is: %s\n",pnam); 114 | ErrorHnd(23, "c_nnsetrd", stderr, emsg); 115 | } 116 | } 117 | 118 | -------------------------------------------------------------------------------- /src/nnculls.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | extern int maxmsg; 6 | 7 | /* 8 | * Comparison function for qsort to sort single precision triples. 9 | */ 10 | int comp_striples(const void *q1, const void *q2) 11 | { 12 | float *p1, *p2; 13 | 14 | p1 = (float *) q1; 15 | p2 = (float *) q2; 16 | 17 | if (p1[0] < p2[0]) { 18 | return (-1); 19 | } 20 | else if (p1[0] > p2[0]) { 21 | return (1); 22 | } 23 | else { 24 | if (p1[1] < p2[1]) { 25 | return (-1); 26 | } 27 | else if (p1[1] > p2[1]) { 28 | return (1); 29 | } 30 | else { 31 | if (p1[2] != p2[2]) { 32 | printf("\n Natgrid - two input triples have the same x/y coordinates"); 33 | printf("\n but different data values: \n\n"); 34 | printf(" First triple: %f %f %f\n",p1[0],p1[1],p1[2]); 35 | printf(" Second triple: %f %f %f\n",p2[0],p2[1],p2[2]); 36 | printf("\n\n"); 37 | exit(1); 38 | } 39 | } 40 | } 41 | } 42 | 43 | /* 44 | * This function culls duplicate single precision triples 45 | * from an array of "tnum" such in "data". The triples 46 | * in "data" are assumed to have been sorted into 47 | * ascending order. The number of distinct triples 48 | * is returned and the distinct triples themselves 49 | * are stored back in data. 50 | */ 51 | int cull_striples(int tnum, float *data) { 52 | int i,ic,icm1,kout=0,msgmx=0,fmsg=0; 53 | float *out,*xtmp; 54 | 55 | ic = 3*sizeof(float); 56 | icm1 = 2*sizeof(float); 57 | out = (float *) malloc(tnum*ic); 58 | 59 | /* 60 | * Copy over the first data triple. 61 | */ 62 | kout++; 63 | memcpy( (void *) out, (void *) data, ic); 64 | 65 | /* 66 | * Test for duplicate points and copy non-duplicates to out. All 67 | * full duplicates (coordinates plus data values) will be culled, 68 | * but duplicate coordinates having different data values will 69 | * produce a fatal error. 70 | */ 71 | for (i = 1; i < tnum; i++) { 72 | /* 73 | * Test for duplicate triples - do not copy them to "out". 74 | */ 75 | if (memcmp((void *)(data+3*(i-1)), (void *)(data+3*i), ic) == 0) { 76 | if (msgmx >= maxmsg && fmsg == 0 && maxmsg > 0) { 77 | printf("Natgrid - maximum number of messages about duplicate input coordinates \n"); 78 | printf(" has been reached - no more such messages will be issued\n"); 79 | printf(" for this Natgrid call.\n"); 80 | fmsg = 1; 81 | } 82 | else if (msgmx < maxmsg && fmsg == 0) { 83 | printf("Natgrid info message - duplicate coordinate found, and culled,\n"); 84 | printf(" in the input data for coordinate (%f,%f)\n", 85 | data[3*(i-1)], data[3*(i-1)+1]); 86 | msgmx++; 87 | } 88 | } 89 | 90 | /* 91 | * In the case of Natgrid the test for duplicate coordinates with 92 | * different data values has already been done in the call to 93 | * qsort_triples. If this were not the case, the following 94 | * commented lines would be appropriate to uncomment. 95 | * 96 | * else if ( (memcmp((void *)(data+3*(i-1)), 97 | * (void *)(data+3*i), 98 | * 2*sizeof(float);) == 0) && 99 | * (memcmp((void *)(data+3*(i-1)), 100 | * (void *)(data+3*i), 101 | * ic ) != 0) ) { 102 | * printf("Error: duplicate coordinates found in the input data, at \ 103 | * coordinate (%f,%f), having different data values.", \ 104 | * data[i*ic],data[i*ic+1]); 105 | * } 106 | */ 107 | 108 | /* 109 | * Copy non-duplicate value to output. 110 | */ 111 | else { 112 | memcpy((void *)(out+3*kout), (void *)(data+3*i), ic); 113 | kout++; 114 | } 115 | } 116 | 117 | /* 118 | * Copy unique values back to the input array and free memory. 119 | */ 120 | memcpy((void *)data, (void *)out, kout*ic); 121 | free (out); 122 | return kout; 123 | } 124 | -------------------------------------------------------------------------------- /src/nnculld.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | extern int maxmsg; 6 | 7 | /* 8 | * Comparison function for qsort to sort double precision triples. 9 | */ 10 | int comp_dtriples(const void *q1, const void *q2) 11 | { 12 | double *p1, *p2; 13 | 14 | p1 = (double *) q1; 15 | p2 = (double *) q2; 16 | 17 | if (p1[0] < p2[0]) { 18 | return (-1); 19 | } 20 | else if (p1[0] > p2[0]) { 21 | return (1); 22 | } 23 | else { 24 | if (p1[1] < p2[1]) { 25 | return (-1); 26 | } 27 | else if (p1[1] > p2[1]) { 28 | return (1); 29 | } 30 | else { 31 | if (p1[2] != p2[2]) { 32 | printf("\n Natgrid - two input triples have the same x/y coordinates"); 33 | printf("\n but different data values: \n\n"); 34 | printf(" First triple: %f %f %f\n",p1[0],p1[1],p1[2]); 35 | printf(" Second triple: %f %f %f\n",p2[0],p2[1],p2[2]); 36 | printf("\n\n"); 37 | exit(1); 38 | } 39 | } 40 | } 41 | } 42 | 43 | /* 44 | * This function culls duplicate double precision triples 45 | * from an array of "tnum" such in "data". The triples 46 | * in "data" are assumed to have been sorted into 47 | * ascending order. The number of distinct triples 48 | * is returned and the distinct triples themselves 49 | * are stored back in data. 50 | */ 51 | int cull_dtriples(int tnum, double *data) { 52 | int i, ic, icm1, kout=0, msgmx=0, fmsg=0; 53 | double *out,*xtmp; 54 | 55 | ic = 3*sizeof(double); 56 | icm1 = 2*sizeof(double); 57 | out = (double *) malloc(tnum*ic); 58 | 59 | /* 60 | * Copy over the first data triple. 61 | */ 62 | kout++; 63 | memcpy( (void *) out, (void *) data, ic); 64 | 65 | /* 66 | * Test for duplicate points and copy non-duplicates to out. All 67 | * full duplicates (coordinates plus data values) will be culled, 68 | * but duplicate coordinates having different data values will 69 | * produce a fatal error. 70 | */ 71 | for (i = 1; i < tnum; i++) { 72 | /* 73 | * Test for duplicate triples - do not copy them to "out". 74 | */ 75 | if (memcmp((void *)(data+3*(i-1)), (void *)(data+3*i), ic) == 0) { 76 | if (msgmx >= maxmsg && fmsg == 0 && maxmsg > 0) { 77 | printf("Natgrid - maximum number of messages about duplicate input coordinates \n"); 78 | printf(" has been reached - no more such messages will be issued\n"); 79 | printf(" for this Natgrid call.\n"); 80 | fmsg = 1; 81 | } 82 | else if (msgmx < maxmsg && fmsg == 0) { 83 | printf("Natgrid info message - duplicate coordinate found, and culled,\n"); 84 | printf(" in the input data for coordinate (%f,%f)\n", 85 | data[3*(i-1)], data[3*(i-1)+1]); 86 | msgmx++; 87 | } 88 | } 89 | 90 | /* 91 | * In the case of Natgrid the test for duplicate coordinates with 92 | * different data values has already been done in the call to 93 | * qsort using the compare function comp_triples. If this were 94 | * not the case, the following commented lines would be appropriate 95 | * to uncomment. 96 | * 97 | * else if ( (memcmp((void *)(data+3*(i-1)), 98 | * (void *)(data+3*i), 99 | * 2*sizeof(double);) == 0) && 100 | * (memcmp((void *)(data+3*(i-1)), 101 | * (void *)(data+3*i), 102 | * ic ) != 0) ) { 103 | * printf("Error: duplicate coordinates found in the input data, at \ 104 | * coordinate (%f,%f), having different data values.", \ 105 | * data[i*ic],data[i*ic+1]); 106 | * } 107 | */ 108 | 109 | /* 110 | * Copy non-duplicate value to output. 111 | */ 112 | else { 113 | memcpy((void *)(out+3*kout), (void *)(data+3*i), ic); 114 | kout++; 115 | } 116 | } 117 | 118 | /* 119 | * Copy unique values back to the input array and free memory. 120 | */ 121 | memcpy((void *)data, (void *)out, kout*ic); 122 | free (out); 123 | return kout; 124 | } 125 | -------------------------------------------------------------------------------- /src/nnuser.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nnuser.c,v 1.9 2008/07/27 03:10:13 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include "nnuheads.h" 15 | #include "nnuhead.h" 16 | 17 | /* 18 | * Get values for character parameters. 19 | */ 20 | void c_nngetc(char *pnam, char *vnam) 21 | { 22 | char *s; 23 | if (!strncmp(pnam,"alg",3) OR !strncmp(pnam,"ALG",3)) { 24 | s = tri_file; 25 | } 26 | else if (!strncmp(pnam,"erf",3) OR !strncmp(pnam,"ERF",3)) { 27 | s = error_file; 28 | } 29 | else { 30 | sprintf(emsg,"\n Parameter name supplied is: %s\n",pnam); 31 | ErrorHnd(23, "c_nngetc", stderr, emsg); 32 | return; 33 | } 34 | for ( ; *s != '\0'; ++s, ++vnam) { 35 | *vnam = *s; 36 | } 37 | *vnam = '\0'; 38 | } 39 | 40 | /* 41 | * Get values for integer parameters. 42 | */ 43 | void c_nngeti(char *pnam, int *ival) 44 | { 45 | if (!strncmp(pnam,"asc",3) OR !strncmp(pnam,"ASC",3)) { 46 | *ival = auto_scale; 47 | } 48 | else if (!strncmp(pnam,"igr",3) OR !strncmp(pnam,"IGR",3)) { 49 | *ival = igrad; 50 | } 51 | else if (!strncmp(pnam,"upd",3) OR !strncmp(pnam,"UPD",3)) { 52 | *ival = updir; 53 | } 54 | else if (!strncmp(pnam,"non",3) OR !strncmp(pnam,"NON",3)) { 55 | *ival = non_neg; 56 | } 57 | else if (!strncmp(pnam,"sdi",3) OR !strncmp(pnam,"SDI",3)) { 58 | *ival = sdip; 59 | } 60 | else if (!strncmp(pnam,"rad",3) OR !strncmp(pnam,"RAD",3)) { 61 | *ival = rads; 62 | } 63 | else if (!strncmp(pnam,"opt",3) OR !strncmp(pnam,"OPT",3)) { 64 | *ival = optim; 65 | } 66 | else if (!strncmp(pnam,"ext",3) OR !strncmp(pnam,"EXT",3)) { 67 | *ival = extrap; 68 | } 69 | else if (!strncmp(pnam,"adf",3) OR !strncmp(pnam,"ADF",3)) { 70 | *ival = adf; 71 | } 72 | else if (!strncmp(pnam,"mdm",3) OR !strncmp(pnam,"MDM",3)) { 73 | *ival = maxmsg; 74 | } 75 | else if (!strncmp(pnam,"dup",3) OR !strncmp(pnam,"DUP",3)) { 76 | printf("\n Natgrid info: parameter 'dup' is no longer supported; duplicate\n points are now culled automatically\n"); 77 | } 78 | else { 79 | sprintf(emsg,"\n Parameter name supplied is: %s\n",pnam); 80 | ErrorHnd(23, "c_nngeti", stderr, emsg); 81 | } 82 | } 83 | 84 | 85 | /* 86 | * Set values for character parameters. 87 | */ 88 | void c_nnsetc(char *pnam, char *vnam) 89 | { 90 | int i; 91 | char *s; 92 | if (!strncmp(pnam,"alg",3) OR !strncmp(pnam,"ALG",3)) { 93 | s = tri_file; 94 | for ( ; *vnam != '\0'; ++s, ++vnam) { 95 | *s = *vnam; 96 | } 97 | *s = '\0'; 98 | } 99 | else { 100 | sprintf(emsg,"\n Parameter name supplied is: %s\n",pnam); 101 | ErrorHnd(23, "c_nnsetc", stderr, emsg); 102 | } 103 | } 104 | 105 | /* 106 | * Set values for integer parameters. 107 | */ 108 | void c_nnseti(char *pnam, int ival) 109 | { 110 | if (!strncmp(pnam,"asc",3) OR !strncmp(pnam,"ASC",3)) { 111 | auto_scale = ival; 112 | } 113 | else if (!strncmp(pnam,"igr",3) OR !strncmp(pnam,"IGR",3)) { 114 | igrad = ival; 115 | } 116 | else if (!strncmp(pnam,"upd",3) OR !strncmp(pnam,"UPD",3)) { 117 | updir = ival; 118 | } 119 | else if (!strncmp(pnam,"non",3) OR !strncmp(pnam,"NON",3)) { 120 | non_neg = ival; 121 | } 122 | else if (!strncmp(pnam,"sdi",3) OR !strncmp(pnam,"SDI",3)) { 123 | sdip = ival; 124 | } 125 | else if (!strncmp(pnam,"rad",3) OR !strncmp(pnam,"RAD",3)) { 126 | rads = ival; 127 | } 128 | else if (!strncmp(pnam,"opt",3) OR !strncmp(pnam,"OPT",3)) { 129 | optim = ival; 130 | } 131 | else if (!strncmp(pnam,"ext",3) OR !strncmp(pnam,"EXT",3)) { 132 | extrap = ival; 133 | } 134 | else if (!strncmp(pnam,"adf",3) OR !strncmp(pnam,"ADF",3)) { 135 | adf = ival; 136 | } 137 | else if (!strncmp(pnam,"mdm",3) OR !strncmp(pnam,"MDM",3)) { 138 | maxmsg = ival; 139 | } 140 | else if (!strncmp(pnam,"dup",3) OR !strncmp(pnam,"DUP",3)) { 141 | nndup = ival; 142 | printf("\n Natgrid info: parameter 'dup' is no longer supported; duplicate\n points are now culled automatically\n"); 143 | } 144 | else { 145 | sprintf(emsg,"\n Parameter name supplied is: %s\n",pnam); 146 | ErrorHnd(23, "c_nnseti", stderr, emsg); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/nnerror.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nnerror.c,v 1.10 2010/04/08 05:32:30 fred Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include 15 | #include 16 | 17 | #define MAX_ERROR 33 18 | 19 | void ErrorLog(int, char *, FILE *, char *); 20 | char *ErrMsg(int); 21 | 22 | extern int error_status; 23 | 24 | void ErrorHnd(int error, char *func, FILE *efile, char *smsg) 25 | { 26 | ErrorLog(error, func, efile, smsg); 27 | } 28 | 29 | void ErrorLog(int error, char *func, FILE *efile, char *smsg) 30 | { 31 | if ( (error == 4) || (error == 5) || (error == 6 || error == 28) ) 32 | { 33 | fprintf(efile, "natgrid - warning number %d from %s:\n %s", 34 | error, func, ErrMsg(error)); 35 | error_status = 0; 36 | } 37 | else 38 | { 39 | fprintf(efile, "natgrid - error number %d from %s:\n %s", 40 | error, func, ErrMsg(error)); 41 | error_status = error; 42 | } 43 | fprintf(efile,"%s",smsg); 44 | Terminate(); 45 | } 46 | 47 | char *ErrMsg(int i) 48 | { 49 | char *rlist; 50 | const char *err_list[MAX_ERROR] = { 51 | 52 | /* #001 */ 53 | "Insufficient data in gridded region to triangulate.", 54 | 55 | /* #002 */ 56 | "Duplicate input data coordinates are not allowed.", 57 | 58 | /* #003 */ 59 | "Unable to open file for writing algorithmic data.", 60 | 61 | /* #004 */ 62 | "WARNING: The ratio of vertical to horizontal scales is too large for \n meaningful gradient estimation. Rescale the data if gradients are required.", 63 | 64 | /* #005 */ 65 | "WARNING: The ratio of vertical to horizontal scales is too small for\n meaningful gradient estimation. Rescale the data if gradients are required.", 66 | 67 | /* #006 */ 68 | "WARNING: The ratio of x-axis breadth to y-axis breadth of this gridded \n region may be too extreme for good interpolation. Changing the block \n proportions, or rescaling the x or y coordinate may be indicated.\n Gradient calculations have been disabled.", 69 | 70 | /* #007 */ 71 | "Unable to allocate storage for ivector.", 72 | 73 | /* #008 */ 74 | "Unable to allocate storage for dvector.", 75 | 76 | /* #009 */ 77 | "Unable to allocate storage for **imatrix.", 78 | 79 | /* #010 */ 80 | "Unable to allocate storage for imatrix[].", 81 | 82 | /* #011 */ 83 | "Unable to allocate storage for **fmatrix.", 84 | 85 | /* #012 */ 86 | "Unable to allocate storage for fmatrix[].", 87 | 88 | /* #013 */ 89 | "Unable to allocate storage for **dmatrix.", 90 | 91 | /* #014 */ 92 | "Unable to allocate storage for dmatrix[].", 93 | 94 | /* #015 */ 95 | "Unable to allocate storage for raw data.", 96 | 97 | /* #016 */ 98 | "Unable to allocate storage for a simplex.", 99 | 100 | /* #017 */ 101 | "Unable to allocate storage for temp.", 102 | 103 | /* #018 */ 104 | "Unable to allocate storage for neig.", 105 | 106 | /* #019 */ 107 | "Slopes have not been computed, set sdi.", 108 | 109 | /* #020 */ 110 | "Row argument out of range.", 111 | 112 | /* #021 */ 113 | "Column argument out of range.", 114 | 115 | /* #022 */ 116 | "Aspects have not been computed, set sdi.", 117 | 118 | /* #023 */ 119 | "Parameter name not known.", 120 | 121 | /* #024 */ 122 | "Cannot open error file.", 123 | 124 | /* #025 */ 125 | "Automatic scaling has been done - aspects will be distorted and \n consequently are not returned. Rescale your data manually, or \n by setting magx, magy, and magz appropriately.", 126 | 127 | /* #026 */ 128 | "Automatic scaling has been done - slopes will be distorted and \n consequently are not returned. Rescale your data manually, or \n by setting magx, magy, and magz appropriately.", 129 | 130 | /* #027 */ 131 | "Coordinate is outside of the gridded region for a single point interpolation.", 132 | 133 | /* #028 */ 134 | "Cannot compute aspects and slopes in conjunction with single point \n interpolation mode.", 135 | 136 | /* #029 */ 137 | "Fortran DOUBLE PRECISION entries are not supported on UNICOS.", 138 | 139 | /* #030 */ 140 | "Error number out of range.", 141 | 142 | /* #031 */ 143 | "Weights can be returned only for linear interpolation when in \n single point mode.", 144 | /* #032 */ 145 | "Single point mode terminated without its ever having been initialized." 146 | }; 147 | 148 | if (i >= MAX_ERROR) { 149 | rlist = (char *) err_list[29]; 150 | } 151 | else { 152 | rlist = (char *) err_list[i-1]; 153 | } 154 | return (rlist); 155 | } 156 | 157 | int ErrMax() 158 | { 159 | return(MAX_ERROR); 160 | } 161 | -------------------------------------------------------------------------------- /src/natgrids.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: natgrids.c,v 1.14 2008/07/27 03:10:12 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "nnghead.h" 19 | #include "nngheads.h" 20 | #include "nnexver.h" 21 | 22 | float *c_natgrids(int n, float x[], float y[], float z[], 23 | int nxi, int nyi, float xi[], float yi[], int *ier) 24 | { 25 | float **data_out=NULL, *rtrn_val=NULL; 26 | float *x_sav, *y_sav, *z_sav, *darray; 27 | int n_sav,i; 28 | 29 | *ier = 0; 30 | 31 | /* 32 | * Check for duplicate input values. Duplicate triples will be 33 | * culled, but duplicate coordinates with different data values 34 | * will produce an error. 35 | */ 36 | if (single_point == 0) 37 | { 38 | n_sav = n; 39 | x_sav = (float *) malloc(n*sizeof(float)); 40 | y_sav = (float *) malloc(n*sizeof(float)); 41 | z_sav = (float *) malloc(n*sizeof(float)); 42 | memcpy((void *)x_sav, (void *)x, n*sizeof(float)); 43 | memcpy((void *)y_sav, (void *)y, n*sizeof(float)); 44 | memcpy((void *)z_sav, (void *)z, n*sizeof(float)); 45 | 46 | darray = (float *) malloc(3*n*sizeof(float)); 47 | for (i = 0; i < n; i++) { 48 | darray[3*i ] = x[i]; 49 | darray[3*i+1] = y[i]; 50 | darray[3*i+2] = z[i]; 51 | } 52 | 53 | qsort( (void *)darray, n, 3*sizeof(float), comp_striples); 54 | n = cull_striples(n_sav, darray); 55 | 56 | for (i = 0; i < n; i++) { 57 | x[i] = darray[3*i ]; 58 | y[i] = darray[3*i+1]; 59 | z[i] = darray[3*i+2]; 60 | } 61 | free(darray); 62 | } 63 | 64 | if (single_point == 0) 65 | { 66 | asflag = 1; 67 | Initialize(n, x, y, nxi, nyi, xi, yi); 68 | 69 | if (ReadData(n,x,y,z) != 0) 70 | { 71 | *ier = error_status; 72 | return ( (float *) NULL); 73 | } 74 | } 75 | 76 | if (adf) 77 | { 78 | CircOut(); 79 | if (error_status) 80 | { 81 | *ier = error_status; 82 | return ( (float *) NULL); 83 | } 84 | } 85 | if (igrad) 86 | { 87 | Gradient(); 88 | if (error_status) 89 | { 90 | *ier = error_status; 91 | return ( (float *) NULL); 92 | } 93 | } 94 | 95 | data_out = MakeGrid(nxi, nyi, xi, yi); 96 | if (error_status) 97 | { 98 | if((data_out != NULL)&&(data_out[0] !=NULL)) { 99 | free(data_out[0]); 100 | free(data_out); 101 | } 102 | *ier = error_status; 103 | return ( (float *) NULL); 104 | } 105 | 106 | if (single_point == 0) 107 | { 108 | Terminate(); 109 | } 110 | 111 | horilap = -1.; 112 | vertlap = -1.; 113 | 114 | rtrn_val = data_out[0]; 115 | free(data_out); 116 | if (single_point == 0) 117 | { 118 | memcpy((void *)x, (void *)x_sav, n*sizeof(float)); 119 | memcpy((void *)y, (void *)y_sav, n*sizeof(float)); 120 | memcpy((void *)z, (void *)z_sav, n*sizeof(float)); 121 | free(x_sav); 122 | free(y_sav); 123 | free(z_sav); 124 | } 125 | return (rtrn_val); 126 | } 127 | void Initialize(int n, float x[], float y[], int nxi, int nyi, 128 | float xi[], float yi[]) 129 | { 130 | 131 | float xil, xir, yib, yit; 132 | 133 | /* 134 | * Reserve memory for returning natural neighbor indices 135 | * and associated weights when requested in single point 136 | * mode for linear interpolation. 137 | */ 138 | nbrs = (int *) calloc(n,sizeof(int)); 139 | wts = (double *) calloc(n,sizeof(double)); 140 | 141 | error_status = 0; 142 | datcnt = 0; 143 | magx_orig = magx; 144 | magy_orig = magy; 145 | magz_orig = magz; 146 | iscale = 0; 147 | magx_auto = 1.; 148 | magy_auto = 1.; 149 | magz_auto = 1.; 150 | 151 | /* 152 | * Find the limits of the output array. 153 | */ 154 | xstart = armin(nxi, xi); 155 | xend = armax(nxi, xi); 156 | ystart = armin(nyi, yi); 157 | yend = armax(nyi, yi); 158 | 159 | /* 160 | * Find the limits of the input array. 161 | */ 162 | xil = armin(n, x); 163 | xir = armax(n, x); 164 | yib = armin(n, y); 165 | yit = armax(n, y); 166 | 167 | /* 168 | * As the default (that is, unless horizontal and vertical overlaps 169 | * have been specifically set by the user) choose the overlap values 170 | * as the smallest values that will make all input data points included 171 | * in the overlap region. 172 | */ 173 | if (horilap EQ -1.) { 174 | if ( (xstart >= xil) && (xend <= xir) ) { 175 | horilap = 1.01 * (((xstart-xil) < (xir-xend)) ? 176 | (xir-xend) : (xstart-xil)); 177 | } 178 | else if ( (xstart >= xil) && (xend >= xir) ) { 179 | horilap = 1.01 * (xstart-xil); 180 | } 181 | else if ( (xstart <= xil) && (xend <= xir) ) { 182 | horilap = 1.01 * (xir-xend); 183 | } 184 | else if ( (xstart <= xil) && (xir <= xend) ) { 185 | horilap = 0.; 186 | } 187 | } 188 | if (horilap <= EPSILON) { 189 | horilap = 0.01 * (xend - xstart); 190 | } 191 | if (vertlap EQ -1.) { 192 | if ( (yib <= ystart) && (yend <= yit) ) { 193 | vertlap = 1.01 * (((ystart-yib) < (yit-yend)) ? 194 | (yit-yend) : (ystart-yib)); 195 | } 196 | else if ( (ystart <= yib) && (yend <= yit) ) { 197 | vertlap = 1.01 * (yit-yend); 198 | } 199 | else if ( (yib <= ystart) && (yit <= yend) ) { 200 | vertlap = 1.01 * (ystart-yib); 201 | } 202 | else if ( (ystart <= yib) && (yit <= yend) ) { 203 | vertlap = 0.; 204 | } 205 | } 206 | if (vertlap <= EPSILON) { 207 | vertlap = 0.01 * (yend - ystart); 208 | } 209 | } 210 | 211 | double armin(int num, float *x) 212 | { 213 | int i; 214 | float amin; 215 | amin = x[0]; 216 | for (i = 1 ; i < num ; i++) 217 | if (x[i] < amin) amin = x[i]; 218 | return(amin); 219 | } 220 | double armax(int num, float *x) 221 | { 222 | int i; 223 | float amax; 224 | amax = x[0]; 225 | for (i = 1 ; i < num ; i++) 226 | if (x[i] > amax) amax = x[i]; 227 | return(amax); 228 | } 229 | -------------------------------------------------------------------------------- /src/natgridd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: natgridd.c,v 1.12 2008/07/27 03:10:12 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "nnghead.h" 19 | #include "nngheadd.h" 20 | 21 | double *c_natgridd(int n, double x[], double y[], double z[], 22 | int nxi, int nyi, double xi[], double yi[], int *ier) 23 | { 24 | double **data_out=NULL, *rtrn_val=NULL; 25 | double *x_sav, *y_sav, *z_sav, *darray; 26 | int n_sav,i; 27 | *ier = 0; 28 | 29 | /* 30 | * Check for duplicate input values. Duplicate triples will be 31 | * culled, but duplicate coordinates with different data values 32 | * will produce an error. 33 | */ 34 | if (single_point == 0) 35 | { 36 | n_sav = n; 37 | x_sav = (double *) malloc(n*sizeof(double)); 38 | y_sav = (double *) malloc(n*sizeof(double)); 39 | z_sav = (double *) malloc(n*sizeof(double)); 40 | memcpy((void *)x_sav, (void *)x, n*sizeof(double)); 41 | memcpy((void *)y_sav, (void *)y, n*sizeof(double)); 42 | memcpy((void *)z_sav, (void *)z, n*sizeof(double)); 43 | 44 | darray = (double *) malloc(3*n*sizeof(double)); 45 | for (i = 0; i < n; i++) { 46 | darray[3*i ] = x[i]; 47 | darray[3*i+1] = y[i]; 48 | darray[3*i+2] = z[i]; 49 | } 50 | 51 | qsort( (void *)darray, n, 3*sizeof(double), comp_dtriples); 52 | n = cull_dtriples(n_sav, darray); 53 | 54 | for (i = 0; i < n; i++) { 55 | x[i] = darray[3*i ]; 56 | y[i] = darray[3*i+1]; 57 | z[i] = darray[3*i+2]; 58 | } 59 | free(darray); 60 | } 61 | 62 | if (single_point == 0) 63 | { 64 | asflag = 1; 65 | Initialized(n, x, y, nxi, nyi, xi, yi); 66 | 67 | if (ReadDatad(n,x,y,z) != 0) 68 | { 69 | *ier = error_status; 70 | return ( (double *) NULL); 71 | } 72 | } 73 | 74 | if (adf) 75 | { 76 | CircOut(); 77 | if (error_status) 78 | { 79 | *ier = error_status; 80 | return ( (double *) NULL); 81 | } 82 | } 83 | if (igrad) 84 | { 85 | Gradient(); 86 | if (error_status) 87 | { 88 | *ier = error_status; 89 | return ( (double *) NULL); 90 | } 91 | } 92 | 93 | data_out = MakeGridd(nxi, nyi, xi, yi); 94 | if (error_status) 95 | { 96 | if((data_out !=NULL)&&(data_out[0]!=NULL)) { 97 | free(data_out[0]); 98 | free(data_out); 99 | } 100 | *ier = error_status; 101 | return ( (double *) NULL); 102 | } 103 | 104 | if (single_point == 0) 105 | { 106 | Terminate(); 107 | } 108 | 109 | horilap = -1.; 110 | vertlap = -1.; 111 | 112 | rtrn_val = data_out[0]; 113 | free(data_out); 114 | if (single_point == 0) 115 | { 116 | memcpy((void *)x, (void *)x_sav, n_sav*sizeof(double)); 117 | memcpy((void *)y, (void *)y_sav, n_sav*sizeof(double)); 118 | memcpy((void *)z, (void *)z_sav, n_sav*sizeof(double)); 119 | free(x_sav); 120 | free(y_sav); 121 | free(z_sav); 122 | } 123 | return (rtrn_val); 124 | } 125 | void Initialized(int n, double x[], double y[], int nxi, int nyi, 126 | double xi[], double yi[]) 127 | { 128 | 129 | double xil, xir, yib, yit; 130 | 131 | /* 132 | * Reserve memory for returning natural neighbor indices 133 | * and associated weights when requested in single point 134 | * mode for linear interpolation. 135 | */ 136 | nbrs = (int *) calloc(n,sizeof(int)); 137 | wts = (double *) calloc(n,sizeof(double)); 138 | 139 | error_status = 0; 140 | datcnt = 0; 141 | magx_orig = magx; 142 | magy_orig = magy; 143 | magz_orig = magz; 144 | iscale = 0; 145 | magx_auto = 1.; 146 | magy_auto = 1.; 147 | magz_auto = 1.; 148 | 149 | /* 150 | * Find the limits of the output array. 151 | */ 152 | xstart = armind(nxi, xi); 153 | xend = armaxd(nxi, xi); 154 | ystart = armind(nyi, yi); 155 | yend = armaxd(nyi, yi); 156 | 157 | /* 158 | * Find the limits of the input array. 159 | */ 160 | xil = armind(n, x); 161 | xir = armaxd(n, x); 162 | yib = armind(n, y); 163 | yit = armaxd(n, y); 164 | 165 | /* 166 | * As the default (that is, unless horizontal and vertical overlaps 167 | * have been specifically set by the user) choose the overlap values 168 | * as the smallest values that will make all input data points included 169 | * in the overlap region. 170 | */ 171 | if (horilap EQ -1.) { 172 | if ( (xstart >= xil) && (xend <= xir) ) { 173 | horilap = 1.01 * (((xstart-xil) < (xir-xend)) ? 174 | (xir-xend) : (xstart-xil)); 175 | } 176 | else if ( (xstart >= xil) && (xend >= xir) ) { 177 | horilap = 1.01 * (xstart-xil); 178 | } 179 | else if ( (xstart <= xil) && (xend <= xir) ) { 180 | horilap = 1.01 * (xir-xend); 181 | } 182 | else if ( (xstart <= xil) && (xir <= xend) ) { 183 | horilap = 0.; 184 | } 185 | } 186 | if (horilap <= EPSILON) { 187 | horilap = 0.01 * (xend - xstart); 188 | } 189 | if (vertlap EQ -1.) { 190 | if ( (yib <= ystart) && (yend <= yit) ) { 191 | vertlap = 1.01 * (((ystart-yib) < (yit-yend)) ? 192 | (yit-yend) : (ystart-yib)); 193 | } 194 | else if ( (ystart <= yib) && (yend <= yit) ) { 195 | vertlap = 1.01 * (yit-yend); 196 | } 197 | else if ( (yib <= ystart) && (yit <= yend) ) { 198 | vertlap = 1.01 * (ystart-yib); 199 | } 200 | else if ( (ystart <= yib) && (yit <= yend) ) { 201 | vertlap = 0.; 202 | } 203 | } 204 | if (vertlap <= EPSILON) { 205 | vertlap = 0.01 * (yend - ystart); 206 | } 207 | } 208 | 209 | double armind(int num, double *x) 210 | { 211 | int i; 212 | float amin; 213 | amin = x[0]; 214 | for (i = 1 ; i < num ; i++) 215 | if (x[i] < amin) amin = x[i]; 216 | return(amin); 217 | } 218 | double armaxd(int num, double *x) 219 | { 220 | int i; 221 | float amax; 222 | amax = x[0]; 223 | for (i = 1 ; i < num ; i++) 224 | if (x[i] > amax) amax = x[i]; 225 | return(amax); 226 | } 227 | -------------------------------------------------------------------------------- /src/nncrunchd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nncrunchd.c,v 1.14 2008/07/27 03:10:12 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include "nncheadd.h" 15 | #include "nnchead.h" 16 | #include "nntypes.h" 17 | #include "nnexver.h" 18 | #include "nnuheadd.h" 19 | #include "nnuhead.h" 20 | 21 | int ReadDatad(int numdat, double *xin, double *yin, double *zin) 22 | { 23 | double temp[3], minx, maxx, miny, maxy, xtmp, ytmp, ztmp; 24 | double qtxy, qtyx, qtzx, qtzy; 25 | int i0, i1, n0; 26 | 27 | bigtri[0][0] = bigtri[0][1] = bigtri[1][1] = bigtri[2][0] = -1; 28 | bigtri[1][0] = bigtri[2][1] = 5; 29 | 30 | if (rootdat EQ NULL) 31 | { 32 | rootdat = IMakeDatum(); 33 | if (error_status) return (error_status); 34 | 35 | rootsimp = IMakeSimp(); 36 | if (error_status) return (error_status); 37 | 38 | roottemp = IMakeTemp(); 39 | if (error_status) return (error_status); 40 | 41 | rootneig = IMakeNeig(); 42 | if (error_status) return (error_status); 43 | 44 | rootdat->values[0] = rootdat->values[1] 45 | = rootdat->values[2] 46 | = 0; 47 | } 48 | else 49 | { 50 | FreeVecti(jndx); 51 | FreeMatrixd(points); 52 | FreeMatrixd(joints); 53 | } 54 | curdat = rootdat; 55 | datcnt = 0; 56 | minx = xstart - horilap; maxx = xend + horilap; 57 | miny = ystart - vertlap; maxy = yend + vertlap; 58 | 59 | for (n0 = 0 ; n0 < numdat ; n0++) { 60 | temp[0] = xin[n0]; 61 | temp[1] = yin[n0]; 62 | temp[2] = zin[n0]; 63 | if (temp[0] > minx AND temp[0] < maxx AND 64 | temp[1] > miny AND temp[1] < maxy) { 65 | if (curdat->nextdat EQ NULL) 66 | { 67 | curdat->nextdat = IMakeDatum(); 68 | if (error_status) return (error_status); 69 | } 70 | curdat = curdat->nextdat; 71 | datcnt++; 72 | for (i1 = 0; i1 < 3; i1++) 73 | curdat->values[i1] = temp[i1]; 74 | } 75 | } 76 | 77 | if (datcnt > 3) 78 | { 79 | datcnt3 = datcnt + 3; 80 | jndx = IntVect(datcnt3); 81 | if (error_status) return (error_status); 82 | sumx = sumy = sumz = sumx2 = sumy2 = sumxy = sumxz = sumyz = 0; 83 | iscale = 0; 84 | /* 85 | * Calculate minimums and maximums of the input data accounting for 86 | * the scale factors. 87 | * 88 | * For the initial calculations, we have: 89 | * 90 | * maxxy[0][0] = maximum x input data value 91 | * maxxy[1][0] = minimum x input data value 92 | * maxxy[0][1] = maximum y input data value 93 | * maxxy[1][1] = minimum y input data value 94 | * maxxy[0][2] = maximum z input data value 95 | * maxxy[1][2] = minimum z input data value 96 | * 97 | */ 98 | 99 | data_limits: 100 | 101 | maxxy[0][0] = maxxy[0][1] = maxxy[0][2] = 102 | -(maxxy[1][0] = maxxy[1][1] = maxxy[1][2] = BIGNUM); 103 | curdat = rootdat->nextdat; 104 | for (i0 = 0; i0 < datcnt; i0++) 105 | { 106 | xtmp = curdat->values[0] * magx; 107 | if (maxxy[0][0] < xtmp) 108 | maxxy[0][0] = xtmp; 109 | if (maxxy[1][0] > xtmp) 110 | maxxy[1][0] = xtmp; 111 | ytmp = curdat->values[1] * magy; 112 | if (maxxy[0][1] < ytmp) 113 | maxxy[0][1] = ytmp; 114 | if (maxxy[1][1] > ytmp) 115 | maxxy[1][1] = ytmp; 116 | ztmp = curdat->values[2] * magz; 117 | if (maxxy[0][2] < ztmp) 118 | maxxy[0][2] = ztmp; 119 | if (maxxy[1][2] > ztmp) 120 | maxxy[1][2] = ztmp; 121 | curdat = curdat->nextdat; 122 | } 123 | /* 124 | * Modify the mins and maxs based on the scale factors and overlap regions. 125 | * to get the actual minimums and maximums of the data under consideration. 126 | */ 127 | if (maxxy[0][0] < maxx * magx) 128 | maxxy[0][0] = maxx * magx; 129 | if (maxxy[1][0] > minx * magx) 130 | maxxy[1][0] = minx * magx; 131 | if (maxxy[0][1] < maxy * magy) 132 | maxxy[0][1] = maxy * magy; 133 | if (maxxy[1][1] > miny * magy) 134 | maxxy[1][1] = miny * magy; 135 | /* 136 | * Calculate the extents in x, y, and z. 137 | * 138 | * maxxy[0][0] = maximum x extent, including overlap regions. 139 | * maxxy[0][1] = maximum y extent, including overlap regions. 140 | * maxxy[0][2] = maximum z extent. 141 | */ 142 | for (i0 = 0 ; i0 < 3 ; i0++) 143 | { 144 | maxxy[0][i0] -= maxxy[1][i0]; 145 | } 146 | maxhoriz = maxxy[0][0]; 147 | if (maxhoriz < maxxy[0][1]) 148 | maxhoriz = maxxy[0][1]; 149 | wbit = maxhoriz * EPSILON; 150 | /* 151 | * Calculate the ratio of the x extent by the y extent (qtxy) and 152 | * the y extent by the x extent (qtyx) . 153 | */ 154 | qtxy = maxxy[0][0] / maxxy[0][1]; 155 | qtyx = 1./qtxy; 156 | if ( (qtxy > (2.+EPSILON)) OR (qtyx > (2.+EPSILON)) ) 157 | { 158 | if (auto_scale) 159 | { 160 | /* 161 | * Readjust the scaling and recompute the data limits. 162 | */ 163 | iscale = 1; 164 | if (qtxy > (2+EPSILON) ) 165 | { 166 | magy *= qtxy; 167 | } 168 | else 169 | { 170 | magx *= qtyx; 171 | } 172 | magx_auto = magx; 173 | magy_auto = magy; 174 | magz_auto = magz; 175 | goto data_limits; 176 | } 177 | else 178 | { 179 | /* 180 | * Issue a warning and turn off gradient estimation. 181 | */ 182 | TooNarrow(); 183 | } 184 | } 185 | 186 | if (igrad) 187 | { 188 | qtzx = maxxy[0][2] / maxxy[0][0]; 189 | qtzy = maxxy[0][2] / maxxy[0][1]; 190 | if ( (qtzx > 60) OR (qtzy > 60) ) 191 | { 192 | if (auto_scale) 193 | { 194 | /* 195 | * Readjust the scaling and recompute the data limits. The X and Y 196 | * scales have been appropriately adjusted by the time you get here, 197 | * so dividing magz by either qtzx or qtzy will bring it in line. 198 | */ 199 | iscale = 1; 200 | magz *= 1./qtzx; 201 | magx_auto = magx; 202 | magy_auto = magy; 203 | magz_auto = magz; 204 | goto data_limits; 205 | } 206 | else 207 | { 208 | /* 209 | * Issue a warning and turn off gradient estimation. 210 | */ 211 | TooSteep(); 212 | } 213 | } 214 | if ( (qtzx < .017) OR (qtzy < .017) ) 215 | { 216 | if (auto_scale) 217 | { 218 | /* 219 | * Readjust the scaling and recompute the data limits. The X and Y 220 | * scales have been appropriately adjusted by the time you get here, 221 | * so dividing magz by either qtzx or qtzy will bring it in line. 222 | */ 223 | iscale = 1; 224 | magz *= 1./qtzx; 225 | magx_auto = magx; 226 | magy_auto = magy; 227 | magz_auto = magz; 228 | goto data_limits; 229 | } 230 | else 231 | { 232 | /* 233 | * Issue a warning and turn off gradient estimation. 234 | */ 235 | TooShallow(); 236 | } 237 | } 238 | } 239 | 240 | if (igrad) 241 | { 242 | points = DoubleMatrix(datcnt+4, 6); 243 | if (error_status) return (error_status); 244 | } 245 | else 246 | { 247 | points = DoubleMatrix(datcnt+4, 3); 248 | if (error_status) return (error_status); 249 | } 250 | joints = DoubleMatrix(datcnt3, 2); 251 | if (error_status) return (error_status); 252 | curdat = rootdat->nextdat; 253 | rootdat->nextdat = NULL; 254 | for (i0 = 0; i0 < datcnt; i0++) 255 | { sumx += points[i0][0] = 256 | curdat->values[0] * magx; 257 | sumx2 += SQ(points[i0][0]); 258 | sumy += points[i0][1] = 259 | curdat->values[1] * magy; 260 | sumy2 += SQ(points[i0][1]); 261 | sumxy += points[i0][0] * points[i0][1]; 262 | if (densi) points[i0][2] = 1; 263 | else 264 | { sumz += points[i0][2] = 265 | curdat->values[2] * magz; 266 | sumxz += points[i0][0] * points[i0][2]; 267 | sumyz += points[i0][1] * points[i0][2]; 268 | } 269 | holddat = curdat; 270 | curdat = curdat->nextdat; 271 | free(holddat); 272 | } 273 | det = (datcnt * (sumx2 * sumy2 - sumxy * sumxy)) 274 | - (sumx * (sumx * sumy2 - sumy * sumxy)) 275 | + (sumy * (sumx * sumxy - sumy * sumx2)); 276 | aaa = ((sumz * (sumx2 * sumy2 - sumxy * sumxy)) 277 | - (sumxz * (sumx * sumy2 - sumy * sumxy)) 278 | + (sumyz * (sumx * sumxy - sumy * sumx2))) / 279 | det; 280 | bbb = 281 | ((datcnt * (sumxz * sumy2 - sumyz * sumxy)) 282 | - (sumz * (sumx * sumy2 - sumy * sumxy)) 283 | + (sumy * (sumx * sumyz - sumy * sumxz))) / 284 | det; 285 | ccc = 286 | ((datcnt * (sumx2 * sumyz - sumxy * sumxz)) 287 | - (sumx * (sumx * sumyz - sumy * sumxz)) 288 | + (sumz * (sumx * sumxy - sumy * sumx2))) / 289 | det; 290 | 291 | 292 | for (i0 = 0 ; i0 < 3 ; i0++) 293 | { points[datcnt+i0][0] = maxxy[1][0] + 294 | bigtri[i0][0] * maxxy[0][0] * RANGE; 295 | points[datcnt+i0][1] = maxxy[1][1] + 296 | bigtri[i0][1] * maxxy[0][1] * RANGE; 297 | if (densi) 298 | points[datcnt+i0][2] = 1; 299 | else 300 | points[datcnt+i0][2] = 301 | aaa + bbb * points[datcnt+i0][0] + 302 | ccc * points[datcnt+i0][1]; 303 | } 304 | rootdat = NULL; 305 | } 306 | else 307 | { 308 | ErrorHnd(1, "ReadData", stderr, "\n"); 309 | error_status = 1; 310 | return (error_status); 311 | } 312 | 313 | /* 314 | * Determine if any input data coordinates are duplicated. 315 | * [this is now handled at the top level; the code is left 316 | * here commented out for historical purposes.] 317 | * 318 | * if (nndup == 1) { 319 | * for (i0 = 0 ; i0 < datcnt ; i0++) { 320 | * for (i1 = i0+1 ; i1 < datcnt ; i1++) { 321 | * if ( (points[i0][0] == points[i1][0]) && 322 | * (points[i0][1] == points[i1][1]) ) 323 | * { 324 | * sprintf(emsg,"\n Coordinates %d and %d are identical.\n",i0,i1); 325 | * ErrorHnd(2, "ReadData", stderr, emsg); 326 | * error_status = 2; 327 | * return (error_status); 328 | * } 329 | * } 330 | * } 331 | * } 332 | */ 333 | 334 | /* 335 | * Introduce a small random perturbation into the coordinate values. 336 | */ 337 | srand(367); 338 | for (i0 = 0 ; i0 < datcnt ; i0++) 339 | { 340 | for (i1 = 0 ; i1 < 2 ; i1++) 341 | { 342 | points[i0][i1] += wbit * (0.5 - (double)rand() / RAND_MAX); 343 | } 344 | } 345 | if (sdip OR igrad) 346 | { 347 | piby2 = 2 * atan(1.0); 348 | nn_pi = piby2 * 2; 349 | piby32 = 3 * piby2; 350 | rad2deg = 90 / piby2; 351 | } 352 | return (0); 353 | } 354 | 355 | double **MakeGridd(int nxi, int nyi, double *xi, double *yi) 356 | { 357 | double wxd, wyd, wxde, wydn, surf, surfe, surfn, aspect, slope; 358 | int i0, j7, j8; 359 | static int first_c = 1, first_as = 1; 360 | static double **data_out; 361 | 362 | if (optim) { 363 | for (i0 = 0 ; i0 < datcnt ; i0++) jndx[i0] = 1; 364 | 365 | if ( (single_point == 0) || (igrad > 0) ) { 366 | TriNeigh(); 367 | } 368 | else { 369 | if (first_single == 1) { 370 | TriNeigh(); 371 | first_single = 0; 372 | } 373 | } 374 | 375 | if (error_status) return ( (double **) NULL); 376 | } 377 | 378 | data_out = DoubleMatrix(nxi,nyi); 379 | if (error_status) return ( (double **) NULL); 380 | 381 | if (sdip) { 382 | if (first_as) 383 | first_as = 0; 384 | else { 385 | FreeMatrixd(curasd.aspect_outd); 386 | FreeMatrixd(curasd.slope_outd); 387 | } 388 | curasd.crows = 0; 389 | curasd.ccols = 0; 390 | curasd.aspect_outd = DoubleMatrix(nxi,nyi); 391 | curasd.slope_outd = DoubleMatrix(nxi,nyi); 392 | } 393 | 394 | /* 395 | * jwts flags saving the neighbor indices and associated 396 | * weights when requested in single point mode using linear interpolation. 397 | */ 398 | jwts = 0; 399 | for (j8 = 0 ; j8 < nyi ; j8++) { 400 | if (updir > 0) 401 | wyd = yi[j8]*magy; 402 | else 403 | wyd = yi[nyi-j8-1]*magy; 404 | 405 | points[datcnt3][1] = wyd; 406 | 407 | for (j7 = 0 ; j7 < nxi ; j7++) { 408 | wxd = xi[j7]*magx; 409 | points[datcnt3][0] = wxd; 410 | 411 | if (!optim) { 412 | FindNeigh(datcnt3); 413 | if (error_status) return ( (double **) NULL); 414 | TriNeigh(); 415 | if (error_status) return ( (double **) NULL); 416 | } 417 | FindProp(wxd,wyd); 418 | if (error_status) return ( (double **) NULL); 419 | if (!extrap AND !goodflag) 420 | surf = nuldat; 421 | else { 422 | if(single_point==1 && j7==1 && j8==1 && igrad==0) { 423 | jwts = 1; 424 | } 425 | surf = Surface(); 426 | jwts = 0; 427 | if (igrad>0) surf = Meld(surf,wxd,wyd); 428 | if (non_neg) if (surf < 0) surf = 0; 429 | } 430 | if (sdip) { 431 | wxde = wxd + wbit; 432 | FindProp(wxde,wyd); 433 | if (error_status) return ( (double **) NULL); 434 | surfe = Surface(); 435 | if (igrad > 0) 436 | surfe = Meld(surfe,wxde,wyd); 437 | if (non_neg) if (surfe < 0) surfe = 0; 438 | wydn = wyd + wbit; 439 | FindProp(wxd,wydn); 440 | if (error_status) return ( (double **) NULL); 441 | surfn = Surface(); 442 | if (igrad > 0) 443 | surfn = Meld(surfn,wxd,wydn); 444 | if (non_neg) if (surfn < 0) surfn = 0; 445 | surfe = (surf - surfe) / wbit; 446 | surfn = (surf - surfn) / wbit; 447 | if (surfe > 0) { 448 | if (surfn > 0) 449 | aspect = piby2 - atan(surfn / surfe); 450 | else 451 | aspect = piby2 + atan(surfn / surfe) * -1; 452 | } 453 | else { 454 | if (surfe < 0) { 455 | if (surfn > 0) 456 | aspect = piby32 + atan(surfn / surfe) * -1; 457 | else aspect = 458 | piby32 - atan(surfn / surfe); 459 | } 460 | else { 461 | if (surfn > 0) 462 | aspect = 0; 463 | else 464 | aspect = nn_pi; 465 | } 466 | } 467 | slope = atan(sqrt(SQ(surfe) + SQ(surfn))); 468 | if (!rads) { 469 | aspect *= rad2deg; 470 | slope *= rad2deg; 471 | } 472 | (curasd.aspect_outd)[j7][j8] = aspect; 473 | (curasd.slope_outd)[j7][j8] = slope; 474 | curasd.crows = nxi; 475 | curasd.ccols = nyi; 476 | if (magz EQ 1. OR (!extrap AND !goodflag)) 477 | data_out[j7][j8] = surf; 478 | else 479 | data_out[j7][j8] = surf/magz; 480 | } 481 | else { 482 | if (magz EQ 1. OR (!extrap AND !goodflag)) 483 | data_out[j7][j8] = surf; 484 | else 485 | data_out[j7][j8] = surf/magz; 486 | } 487 | } 488 | } 489 | return (data_out); 490 | } 491 | 492 | void c_nngetsloped(int row, int col, double *slope, int *ier) 493 | { 494 | if (asflag == 0) { 495 | error_status = 28; 496 | ErrorHnd(error_status, "c_nngetsloped", stderr, "\n"); 497 | *ier = 28; 498 | *slope = -999.; 499 | return; 500 | } 501 | if (iscale == 1) 502 | { 503 | sprintf(emsg,"\n\n Current automatically computed scaling " 504 | "values:\n" 505 | " magx = %f\n magy = %f\n" 506 | " magz = %f\n\n", 507 | magx_auto, magy_auto, magz_auto); 508 | ErrorHnd(26, "c_nngetsloped", stderr, emsg); 509 | *ier = 26; 510 | *slope = -999.; 511 | return; 512 | } 513 | if (curasd.crows == 0) 514 | { 515 | ErrorHnd(19, "c_nngetsloped", stderr, "\n"); 516 | *ier = 19; 517 | *slope = -999.; 518 | return; 519 | } 520 | if (row >= curasd.crows || row < 0) 521 | { 522 | sprintf(emsg,"\n Requested row = %d (indices starting with one)\n",row+1); 523 | ErrorHnd(20, "c_nngetsloped", stderr, emsg); 524 | *ier = 20; 525 | *slope = -999.; 526 | return; 527 | } 528 | if (col >= curasd.ccols || col < 0) 529 | { 530 | sprintf(emsg,"\n Requested column = %d (indices starting with one)\n", 531 | col+1); 532 | ErrorHnd(21, "c_nngetsloped", stderr, emsg); 533 | *ier = 21; 534 | *slope = -999.; 535 | return; 536 | } 537 | *ier = 0; 538 | *slope = (curasd.slope_outd)[row][col]; 539 | } 540 | void c_nngetaspectd(int row, int col, double *aspect, int *ier) 541 | { 542 | if (asflag == 0) { 543 | error_status = 28; 544 | ErrorHnd(error_status, "c_nngetaspectd", stderr, "\n"); 545 | *ier = 28; 546 | *aspect = -999.; 547 | return; 548 | } 549 | if (iscale == 1) 550 | { 551 | sprintf(emsg,"\n\n Current automatically computed scaling " 552 | "values:\n" 553 | " magx = %f\n magy = %f\n" 554 | " magz = %f\n\n", 555 | magx_auto, magy_auto, magz_auto); 556 | ErrorHnd(25, "c_nngetaspectd", stderr, emsg); 557 | *ier = 25; 558 | *aspect = -999.; 559 | return; 560 | } 561 | if (curasd.crows == 0) 562 | { 563 | ErrorHnd(22, "c_nngetaspectd", stderr, "\n"); 564 | *ier = 22; 565 | *aspect = -999.; 566 | return; 567 | } 568 | if (row >= curasd.crows || row < 0) 569 | { 570 | sprintf(emsg,"\n Requested row = %d (indices starting with one)\n",row+1); 571 | ErrorHnd(20, "c_nngetaspectd", stderr, emsg); 572 | *ier = 20; 573 | *aspect = -999.; 574 | return; 575 | } 576 | if (col >= curasd.ccols || col < 0) 577 | { 578 | sprintf(emsg,"\n Requested column = %d (indices starting with one)\n", 579 | col); 580 | ErrorHnd(21, "c_nngetaspectd", stderr, emsg); 581 | *ier = 21; 582 | *aspect = -999.; 583 | return; 584 | } 585 | *ier = 0; 586 | *aspect = (curasd.aspect_outd)[row][col]; 587 | } 588 | 589 | /* 590 | * Initialize single point interpolation mode. This just 591 | * does the regridding initialization and initial data analysis. 592 | */ 593 | void c_nnpntinitd(int n, double x[], double y[], double z[]) 594 | { 595 | #define NXI 2 596 | #define NYI 2 597 | 598 | double xi[NXI], yi[NYI], wtmp; 599 | 600 | single_point = 1; 601 | first_single = 1; 602 | asflag = 0; 603 | horilap_save = horilap; 604 | vertlap_save = vertlap; 605 | horilap = -1.; 606 | vertlap = -1.; 607 | 608 | /* 609 | * Establish the gridded region to contain all of the input 610 | * data points plus an extra 10% space around the border. 611 | */ 612 | xi[0] = armind(n, x); 613 | xi[1] = armaxd(n, x); 614 | wtmp = xi[1] - xi[0]; 615 | xi[0] -= 0.1*wtmp; 616 | xi[1] += 0.1*wtmp; 617 | 618 | yi[0] = armind(n, y); 619 | yi[1] = armaxd(n, y); 620 | wtmp = yi[1] - yi[0]; 621 | yi[0] -= 0.1*wtmp; 622 | yi[1] += 0.1*wtmp; 623 | 624 | Initialized(n, x, y, NXI, NYI, xi, yi); 625 | 626 | if (ReadDatad(n,x,y,z) != 0) 627 | { 628 | ErrorHnd(error_status, "c_nnpntinitd", stderr, "\n"); 629 | } 630 | } 631 | void c_nnpntd(double x, double y, double *point) 632 | { 633 | int idum, nxi=3, nyi=3, ierr; 634 | double xdum[1], ydum[1], zdum[1], xi[3], yi[3], *out; 635 | 636 | /* 637 | * Check to see if the input point is within the gridded region 638 | * set up in the initialization. 639 | */ 640 | if ( (x < xstart) || (x > xend) || (y < ystart) || (y > yend) ) 641 | { 642 | sprintf(emsg,"\n Coordinate = (%f, %f)\n", x, y); 643 | ErrorHnd(27, "c_nnpntd", stderr, emsg); 644 | return; 645 | } 646 | 647 | /* 648 | * Set up a 3 x 3 gridded region with the desired coordinate in 649 | * the middle. 650 | */ 651 | xi[0] = x-0.05*(xend-xstart); 652 | xi[1] = x; 653 | xi[2] = x+0.05*(xend-xstart); 654 | yi[0] = y-0.05*(yend-ystart); 655 | yi[1] = y; 656 | yi[2] = y+0.05*(yend-ystart); 657 | 658 | out = c_natgridd(idum, xdum, ydum, zdum, nxi, nyi, xi, yi, &ierr); 659 | if (ierr != 0) 660 | { 661 | ErrorHnd(28, "c_nnpntd", stderr, "\n"); 662 | error_status = ierr; 663 | *point = -999.; 664 | } 665 | 666 | *point = out[3*1 +1]; 667 | } 668 | void c_nnpntendd() 669 | { 670 | if (single_point == 0) { 671 | ErrorHnd(32, "c_nnpntendd", stderr, "\n"); 672 | error_status = 32; 673 | return; 674 | } 675 | single_point = 0; 676 | first_single = 0; 677 | horilap = horilap_save; 678 | vertlap = vertlap_save; 679 | Terminate(); 680 | } 681 | -------------------------------------------------------------------------------- /src/nncrunchs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nncrunchs.c,v 1.15 2008/07/27 03:10:13 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * Copyright (C) 2000 * 7 | * University Corporation for Atmospheric Research * 8 | * All Rights Reserved * 9 | * * 10 | * The use of this Software is governed by a License Agreement. * 11 | * * 12 | ************************************************************************/ 13 | 14 | #include "nncheads.h" 15 | #include "nnchead.h" 16 | #include "nntypes.h" 17 | #include "nnexver.h" 18 | #include "nnuheads.h" 19 | #include "nnuhead.h" 20 | 21 | int ReadData(int numdat, float *xin, float *yin, float *zin) 22 | { 23 | double temp[3], minx, maxx, miny, maxy, xtmp, ytmp, ztmp; 24 | double qtxy, qtyx, qtzx, qtzy; 25 | int i0, i1, n0; 26 | 27 | bigtri[0][0] = bigtri[0][1] = bigtri[1][1] = bigtri[2][0] = -1; 28 | bigtri[1][0] = bigtri[2][1] = 5; 29 | 30 | if (rootdat EQ NULL) 31 | { 32 | rootdat = IMakeDatum(); 33 | if (error_status) return (error_status); 34 | 35 | rootsimp = IMakeSimp(); 36 | if (error_status) return (error_status); 37 | 38 | roottemp = IMakeTemp(); 39 | if (error_status) return (error_status); 40 | 41 | rootneig = IMakeNeig(); 42 | if (error_status) return (error_status); 43 | 44 | rootdat->values[0] = rootdat->values[1] 45 | = rootdat->values[2] 46 | = 0; 47 | } 48 | else 49 | { 50 | FreeVecti(jndx); 51 | FreeMatrixd(points); 52 | FreeMatrixd(joints); 53 | } 54 | curdat = rootdat; 55 | datcnt = 0; 56 | minx = xstart - horilap; maxx = xend + horilap; 57 | miny = ystart - vertlap; maxy = yend + vertlap; 58 | 59 | for (n0 = 0 ; n0 < numdat ; n0++) { 60 | temp[0] = xin[n0]; 61 | temp[1] = yin[n0]; 62 | temp[2] = zin[n0]; 63 | if (temp[0] > minx AND temp[0] < maxx AND 64 | temp[1] > miny AND temp[1] < maxy) { 65 | if (curdat->nextdat EQ NULL) 66 | { 67 | curdat->nextdat = IMakeDatum(); 68 | if (error_status) return (error_status); 69 | } 70 | curdat = curdat->nextdat; 71 | datcnt++; 72 | for (i1 = 0; i1 < 3; i1++) 73 | curdat->values[i1] = temp[i1]; 74 | } 75 | } 76 | 77 | if (datcnt > 3) 78 | { 79 | datcnt3 = datcnt + 3; 80 | jndx = IntVect(datcnt3); 81 | if (error_status) return (error_status); 82 | sumx = sumy = sumz = sumx2 = sumy2 = sumxy = sumxz = sumyz = 0; 83 | iscale = 0; 84 | /* 85 | * Calculate minimums and maximums of the input data accounting for 86 | * the scale factors. 87 | * 88 | * For the initial calculations, we have: 89 | * 90 | * maxxy[0][0] = maximum x input data value 91 | * maxxy[1][0] = minimum x input data value 92 | * maxxy[0][1] = maximum y input data value 93 | * maxxy[1][1] = minimum y input data value 94 | * maxxy[0][2] = maximum z input data value 95 | * maxxy[1][2] = minimum z input data value 96 | * 97 | */ 98 | 99 | data_limits: 100 | 101 | maxxy[0][0] = maxxy[0][1] = maxxy[0][2] = 102 | -(maxxy[1][0] = maxxy[1][1] = maxxy[1][2] = BIGNUM); 103 | curdat = rootdat->nextdat; 104 | for (i0 = 0; i0 < datcnt; i0++) 105 | { 106 | xtmp = curdat->values[0] * magx; 107 | if (maxxy[0][0] < xtmp) 108 | maxxy[0][0] = xtmp; 109 | if (maxxy[1][0] > xtmp) 110 | maxxy[1][0] = xtmp; 111 | ytmp = curdat->values[1] * magy; 112 | if (maxxy[0][1] < ytmp) 113 | maxxy[0][1] = ytmp; 114 | if (maxxy[1][1] > ytmp) 115 | maxxy[1][1] = ytmp; 116 | ztmp = curdat->values[2] * magz; 117 | if (maxxy[0][2] < ztmp) 118 | maxxy[0][2] = ztmp; 119 | if (maxxy[1][2] > ztmp) 120 | maxxy[1][2] = ztmp; 121 | curdat = curdat->nextdat; 122 | } 123 | /* 124 | * Modify the mins and maxs based on the scale factors and overlap regions. 125 | * to get the actual minimums and maximums of the data under consideration. 126 | */ 127 | if (maxxy[0][0] < maxx * magx) 128 | maxxy[0][0] = maxx * magx; 129 | if (maxxy[1][0] > minx * magx) 130 | maxxy[1][0] = minx * magx; 131 | if (maxxy[0][1] < maxy * magy) 132 | maxxy[0][1] = maxy * magy; 133 | if (maxxy[1][1] > miny * magy) 134 | maxxy[1][1] = miny * magy; 135 | /* 136 | * Calculate the extents in x, y, and z. 137 | * 138 | * maxxy[0][0] = maximum x extent, including overlap regions. 139 | * maxxy[0][1] = maximum y extent, including overlap regions. 140 | * maxxy[0][2] = maximum z extent. 141 | */ 142 | for (i0 = 0 ; i0 < 3 ; i0++) 143 | { 144 | maxxy[0][i0] -= maxxy[1][i0]; 145 | } 146 | maxhoriz = maxxy[0][0]; 147 | if (maxhoriz < maxxy[0][1]) 148 | maxhoriz = maxxy[0][1]; 149 | wbit = maxhoriz * EPSILON; 150 | /* 151 | * Calculate the ratio of the x extent by the y extent (qtxy) and 152 | * the y extent by the x extent (qtyx) . 153 | */ 154 | qtxy = maxxy[0][0] / maxxy[0][1]; 155 | qtyx = 1./qtxy; 156 | if ( (qtxy > (2.+EPSILON)) OR (qtyx > (2.+EPSILON)) ) 157 | { 158 | if (auto_scale) 159 | { 160 | /* 161 | * Readjust the scaling and recompute the data limits. 162 | */ 163 | iscale = 1; 164 | if (qtxy > (2+EPSILON) ) 165 | { 166 | magy *= qtxy; 167 | } 168 | else 169 | { 170 | magx *= qtyx; 171 | } 172 | magx_auto = magx; 173 | magy_auto = magy; 174 | magz_auto = magz; 175 | goto data_limits; 176 | } 177 | else 178 | { 179 | /* 180 | * Issue a warning and turn off gradient estimation. 181 | */ 182 | TooNarrow(); 183 | } 184 | } 185 | 186 | if (igrad) 187 | { 188 | qtzx = maxxy[0][2] / maxxy[0][0]; 189 | qtzy = maxxy[0][2] / maxxy[0][1]; 190 | if ( (qtzx > 60) OR (qtzy > 60) ) 191 | { 192 | if (auto_scale) 193 | { 194 | /* 195 | * Readjust the scaling and recompute the data limits. The X and Y 196 | * scales have been appropriately adjusted by the time you get here, 197 | * so dividing magz by either qtzx or qtzy will bring it in line. 198 | */ 199 | iscale = 1; 200 | magz *= 1./qtzx; 201 | magx_auto = magx; 202 | magy_auto = magy; 203 | magz_auto = magz; 204 | goto data_limits; 205 | } 206 | else 207 | { 208 | /* 209 | * Issue a warning and turn off gradient estimation. 210 | */ 211 | TooSteep(); 212 | } 213 | } 214 | if ( (qtzx < .017) OR (qtzy < .017) ) 215 | { 216 | if (auto_scale) 217 | { 218 | /* 219 | * Readjust the scaling and recompute the data limits. The X and Y 220 | * scales have been appropriately adjusted by the time you get here, 221 | * so dividing magz by either qtzx or qtzy will bring it in line. 222 | */ 223 | iscale = 1; 224 | magz *= 1./qtzx; 225 | magx_auto = magx; 226 | magy_auto = magy; 227 | magz_auto = magz; 228 | goto data_limits; 229 | } 230 | else 231 | { 232 | /* 233 | * Issue a warning and turn off gradient estimation. 234 | */ 235 | TooShallow(); 236 | } 237 | } 238 | } 239 | 240 | if (igrad) 241 | { 242 | points = DoubleMatrix(datcnt+4, 6); 243 | if (error_status) return (error_status); 244 | } 245 | else 246 | { 247 | points = DoubleMatrix(datcnt+4, 3); 248 | if (error_status) return (error_status); 249 | } 250 | joints = DoubleMatrix(datcnt3, 2); 251 | if (error_status) return (error_status); 252 | curdat = rootdat->nextdat; 253 | rootdat->nextdat = NULL; 254 | free(rootdat); 255 | for (i0 = 0; i0 < datcnt; i0++) 256 | { sumx += points[i0][0] = 257 | curdat->values[0] * magx; 258 | sumx2 += SQ(points[i0][0]); 259 | sumy += points[i0][1] = 260 | curdat->values[1] * magy; 261 | sumy2 += SQ(points[i0][1]); 262 | sumxy += points[i0][0] * points[i0][1]; 263 | if (densi) points[i0][2] = 1; 264 | else 265 | { sumz += points[i0][2] = 266 | curdat->values[2] * magz; 267 | sumxz += points[i0][0] * points[i0][2]; 268 | sumyz += points[i0][1] * points[i0][2]; 269 | } 270 | holddat = curdat; 271 | curdat = curdat->nextdat; 272 | free(holddat); 273 | } 274 | det = (datcnt * (sumx2 * sumy2 - sumxy * sumxy)) 275 | - (sumx * (sumx * sumy2 - sumy * sumxy)) 276 | + (sumy * (sumx * sumxy - sumy * sumx2)); 277 | aaa = ((sumz * (sumx2 * sumy2 - sumxy * sumxy)) 278 | - (sumxz * (sumx * sumy2 - sumy * sumxy)) 279 | + (sumyz * (sumx * sumxy - sumy * sumx2))) / 280 | det; 281 | bbb = 282 | ((datcnt * (sumxz * sumy2 - sumyz * sumxy)) 283 | - (sumz * (sumx * sumy2 - sumy * sumxy)) 284 | + (sumy * (sumx * sumyz - sumy * sumxz))) / 285 | det; 286 | ccc = 287 | ((datcnt * (sumx2 * sumyz - sumxy * sumxz)) 288 | - (sumx * (sumx * sumyz - sumy * sumxz)) 289 | + (sumz * (sumx * sumxy - sumy * sumx2))) / 290 | det; 291 | 292 | 293 | for (i0 = 0 ; i0 < 3 ; i0++) 294 | { points[datcnt+i0][0] = maxxy[1][0] + 295 | bigtri[i0][0] * maxxy[0][0] * RANGE; 296 | points[datcnt+i0][1] = maxxy[1][1] + 297 | bigtri[i0][1] * maxxy[0][1] * RANGE; 298 | if (densi) 299 | points[datcnt+i0][2] = 1; 300 | else 301 | points[datcnt+i0][2] = 302 | aaa + bbb * points[datcnt+i0][0] + 303 | ccc * points[datcnt+i0][1]; 304 | } 305 | rootdat = NULL; 306 | } 307 | else 308 | { 309 | ErrorHnd(1, "ReadData", stderr, "\n"); 310 | error_status = 1; 311 | return (error_status); 312 | } 313 | 314 | /* 315 | * Determine if any input data coordinates are duplicated. 316 | * [this is now handled at the top level; the code is left 317 | * here commented out for historical purposes.] 318 | * 319 | * if (nndup == 1) { 320 | * for (i0 = 0 ; i0 < datcnt ; i0++) { 321 | * for (i1 = i0+1 ; i1 < datcnt ; i1++) { 322 | * if ( (points[i0][0] == points[i1][0]) && 323 | * (points[i0][1] == points[i1][1]) ) 324 | * { 325 | * sprintf(emsg,"\n Coordinates %d and %d are identical.\n",i0,i1); 326 | * ErrorHnd(2, "ReadData", stderr, emsg); 327 | * error_status = 2; 328 | * return (error_status); 329 | * } 330 | * } 331 | * } 332 | * } 333 | */ 334 | 335 | /* 336 | * Introduce a small random perturbation into the coordinate values. 337 | */ 338 | srand(367); 339 | for (i0 = 0 ; i0 < datcnt ; i0++) 340 | { 341 | for (i1 = 0 ; i1 < 2 ; i1++) 342 | { 343 | points[i0][i1] += wbit * (0.5 - (double)rand() / RAND_MAX); 344 | } 345 | } 346 | if (sdip OR igrad) 347 | { 348 | piby2 = 2 * atan(1.0); 349 | nn_pi = piby2 * 2; 350 | piby32 = 3 * piby2; 351 | rad2deg = 90 / piby2; 352 | } 353 | return (0); 354 | } 355 | 356 | float **MakeGrid(int nxi, int nyi, float *xi, float *yi) 357 | { 358 | double wxd, wyd, wxde, wydn, surf, surfe, surfn, aspect, slope; 359 | int i0, j7, j8; 360 | static int first_c = 1, first_as = 1; 361 | static float **data_out; 362 | 363 | if (optim) { 364 | for (i0 = 0 ; i0 < datcnt ; i0++) jndx[i0] = 1; 365 | 366 | if ( (single_point == 0) || (igrad > 0) ) { 367 | TriNeigh(); 368 | } 369 | else { 370 | if (first_single == 1) { 371 | TriNeigh(); 372 | first_single = 0; 373 | } 374 | } 375 | 376 | if (error_status) return ( (float **) NULL); 377 | } 378 | 379 | data_out = FloatMatrix(nxi,nyi); 380 | if (error_status) return ( (float **) NULL); 381 | 382 | if (sdip) { 383 | if (first_as) 384 | first_as = 0; 385 | else { 386 | FreeMatrixf(curas.aspect_out); 387 | FreeMatrixf(curas.slope_out); 388 | } 389 | curas.crows = 0; 390 | curas.ccols = 0; 391 | curas.aspect_out = FloatMatrix(nxi,nyi); 392 | curas.slope_out = FloatMatrix(nxi,nyi); 393 | } 394 | 395 | /* 396 | * jwts flags saving the neighbor indices and associated 397 | * weights when requested in single point mode using linear interpolation. 398 | */ 399 | jwts = 0; 400 | for (j8 = 0 ; j8 < nyi ; j8++) { 401 | if (updir > 0) 402 | wyd = yi[j8]*magy; 403 | else 404 | wyd = yi[nyi-j8-1]*magy; 405 | 406 | points[datcnt3][1] = wyd; 407 | 408 | for (j7 = 0 ; j7 < nxi ; j7++) { 409 | wxd = xi[j7]*magx; 410 | points[datcnt3][0] = wxd; 411 | 412 | if (!optim) { 413 | FindNeigh(datcnt3); 414 | if (error_status) return ( (float **) NULL); 415 | TriNeigh(); 416 | if (error_status) return ( (float **) NULL); 417 | } 418 | FindProp(wxd,wyd); 419 | if (error_status) return ( (float **) NULL); 420 | if (!extrap AND !goodflag) 421 | surf = nuldat; 422 | else { 423 | if(single_point==1 && j7==1 && j8==1 && igrad==0) { 424 | jwts = 1; 425 | } 426 | surf = Surface(); 427 | jwts = 0; 428 | if (igrad>0) surf = Meld(surf,wxd,wyd); 429 | if (non_neg) if (surf < 0) surf = 0; 430 | } 431 | if (sdip) { 432 | wxde = wxd + wbit; 433 | FindProp(wxde,wyd); 434 | if (error_status) return ( (float **) NULL); 435 | surfe = Surface(); 436 | if (igrad > 0) 437 | surfe = Meld(surfe,wxde,wyd); 438 | if (non_neg) if (surfe < 0) surfe = 0; 439 | wydn = wyd + wbit; 440 | FindProp(wxd,wydn); 441 | if (error_status) return ( (float **) NULL); 442 | surfn = Surface(); 443 | if (igrad > 0) 444 | surfn = Meld(surfn,wxd,wydn); 445 | if (non_neg) if (surfn < 0) surfn = 0; 446 | surfe = (surf - surfe) / wbit; 447 | surfn = (surf - surfn) / wbit; 448 | if (surfe > 0) { 449 | if (surfn > 0) 450 | aspect = piby2 - atan(surfn / surfe); 451 | else 452 | aspect = piby2 + atan(surfn / surfe) * -1; 453 | } 454 | else { 455 | if (surfe < 0) { 456 | if (surfn > 0) 457 | aspect = piby32 + atan(surfn / surfe) * -1; 458 | else aspect = 459 | piby32 - atan(surfn / surfe); 460 | } 461 | else { 462 | if (surfn > 0) 463 | aspect = 0; 464 | else 465 | aspect = nn_pi; 466 | } 467 | } 468 | slope = atan(sqrt(SQ(surfe) + SQ(surfn))); 469 | if (!rads) { 470 | aspect *= rad2deg; 471 | slope *= rad2deg; 472 | } 473 | (curas.aspect_out)[j7][j8] = aspect; 474 | (curas.slope_out)[j7][j8] = slope; 475 | curas.crows = nxi; 476 | curas.ccols = nyi; 477 | if (magz EQ 1. OR (!extrap AND !goodflag)) 478 | data_out[j7][j8] = surf; 479 | else 480 | data_out[j7][j8] = surf/magz; 481 | } 482 | else { 483 | if (magz EQ 1. OR (!extrap AND !goodflag)) 484 | data_out[j7][j8] = surf; 485 | else 486 | data_out[j7][j8] = surf/magz; 487 | } 488 | } 489 | } 490 | return (data_out); 491 | } 492 | 493 | void c_nngetslopes(int row, int col, float *slope, int *ier) 494 | { 495 | if (asflag == 0) { 496 | error_status = 28; 497 | ErrorHnd(error_status, "c_nngetslopes", stderr, "\n"); 498 | *ier = 28; 499 | *slope = -999.; 500 | return; 501 | } 502 | if (iscale == 1) 503 | { 504 | sprintf(emsg,"\n\n Current automatically computed scaling " 505 | "values:\n" 506 | " magx = %f\n magy = %f\n" 507 | " magz = %f\n\n", 508 | magx_auto, magy_auto, magz_auto); 509 | ErrorHnd(26, "c_nngetslopes", stderr, emsg); 510 | *ier = 26; 511 | *slope = -999.; 512 | return; 513 | } 514 | if (curas.crows == 0) 515 | { 516 | ErrorHnd(19, "c_nngetslopes", stderr, "\n"); 517 | *ier = 19; 518 | *slope = -999.; 519 | return; 520 | } 521 | if (row >= curas.crows || row < 0) 522 | { 523 | sprintf(emsg,"\n Requested row = %d (indices starting with one)\n",row+1); 524 | ErrorHnd(20, "c_nngetslopes", stderr, emsg); 525 | *ier = 20; 526 | *slope = -999.; 527 | return; 528 | } 529 | if (col >= curas.ccols || col < 0) 530 | { 531 | sprintf(emsg,"\n Requested column = %d (indices starting with one)\n", 532 | col+1); 533 | ErrorHnd(21, "c_nngetslopes", stderr, emsg); 534 | *ier = 21; 535 | *slope = -999.; 536 | return; 537 | } 538 | *ier = 0; 539 | *slope = (curas.slope_out)[row][col]; 540 | } 541 | void c_nngetaspects(int row, int col, float *aspect, int *ier) 542 | { 543 | if (asflag == 0) { 544 | error_status = 28; 545 | ErrorHnd(error_status, "c_nngetaspects", stderr, "\n"); 546 | *ier = 28; 547 | *aspect = -999.; 548 | return; 549 | } 550 | if (iscale == 1) 551 | { 552 | sprintf(emsg,"\n\n Current automatically computed scaling " 553 | "values:\n" 554 | " magx = %f\n magy = %f\n" 555 | " magz = %f\n\n", 556 | magx_auto, magy_auto, magz_auto); 557 | ErrorHnd(25, "c_nngetaspects", stderr, emsg); 558 | *ier = 25; 559 | *aspect = -999.; 560 | return; 561 | } 562 | if (curas.crows == 0) 563 | { 564 | ErrorHnd(22, "c_nngetaspects", stderr, "\n"); 565 | *ier = 22; 566 | *aspect = -999.; 567 | return; 568 | } 569 | if (row >= curas.crows || row < 0) 570 | { 571 | sprintf(emsg,"\n Requested row = %d (indices starting with one)\n",row+1); 572 | ErrorHnd(20, "c_nngetaspects", stderr, emsg); 573 | *ier = 20; 574 | *aspect = -999.; 575 | return; 576 | } 577 | if (col >= curas.ccols || col < 0) 578 | { 579 | sprintf(emsg,"\n Requested column = %d (indices starting with one)\n", 580 | col); 581 | ErrorHnd(21, "c_nngetaspects", stderr, emsg); 582 | *ier = 21; 583 | *aspect = -999.; 584 | return; 585 | } 586 | *ier = 0; 587 | *aspect = (curas.aspect_out)[row][col]; 588 | } 589 | 590 | /* 591 | * Initialize single point interpolation mode. This just 592 | * does the regridding initialization and initial data analysis. 593 | */ 594 | void c_nnpntinits(int n, float x[], float y[], float z[]) 595 | { 596 | #define NXI 2 597 | #define NYI 2 598 | 599 | float xi[NXI], yi[NYI], wtmp; 600 | 601 | single_point = 1; 602 | first_single = 1; 603 | asflag = 0; 604 | horilap_save = horilap; 605 | vertlap_save = vertlap; 606 | horilap = -1.; 607 | vertlap = -1.; 608 | 609 | /* 610 | * Establish the gridded region to contain all of the input 611 | * data points plus an extra 10% space around the border. 612 | */ 613 | xi[0] = (float) armin(n, x); 614 | xi[1] = (float) armax(n, x); 615 | wtmp = xi[1] - xi[0]; 616 | xi[0] -= 0.1*wtmp; 617 | xi[1] += 0.1*wtmp; 618 | 619 | yi[0] = (float) armin(n, y); 620 | yi[1] = (float) armax(n, y); 621 | wtmp = yi[1] - yi[0]; 622 | yi[0] -= 0.1*wtmp; 623 | yi[1] += 0.1*wtmp; 624 | 625 | Initialize(n, x, y, NXI, NYI, xi, yi); 626 | 627 | if (ReadData(n,x,y,z) != 0) 628 | { 629 | ErrorHnd(error_status, "c_nnpntinits", stderr, "\n"); 630 | } 631 | } 632 | void c_nnpnts(float x, float y, float *point) 633 | { 634 | int idum, nxi=3, nyi=3, ierr; 635 | float xdum[1], ydum[1], zdum[1], xi[3], yi[3], *out; 636 | 637 | /* 638 | * Check to see if the input point is within the gridded region 639 | * set up in the initialization. 640 | */ 641 | /* 642 | * if ( (x < xstart) || (x > xend) || (y < ystart) || (y > yend) ) 643 | * { 644 | * sprintf(emsg,"\n Coordinate = (%f, %f)\n", x, y); 645 | * ErrorHnd(27, "c_nnpnts", stderr, emsg); 646 | * return; 647 | * } 648 | */ 649 | 650 | /* 651 | * Set up a 3 x 3 gridded region with the desired coordinate in 652 | * the middle. 653 | */ 654 | xi[0] = x-0.05*(xend-xstart); 655 | xi[1] = x; 656 | xi[2] = x+0.05*(xend-xstart); 657 | yi[0] = y-0.05*(yend-ystart); 658 | yi[1] = y; 659 | yi[2] = y+0.05*(yend-ystart); 660 | 661 | out = c_natgrids(idum, xdum, ydum, zdum, nxi, nyi, xi, yi, &ierr); 662 | if (ierr != 0) 663 | { 664 | ErrorHnd(28, "c_nnpnts", stderr, "\n"); 665 | error_status = ierr; 666 | *point = -999.; 667 | } 668 | 669 | *point = out[3*1 + 1]; 670 | } 671 | void c_nnpntend() 672 | { 673 | if (single_point == 0) { 674 | ErrorHnd(32, "c_nnpntend", stderr, "\n"); 675 | error_status = 32; 676 | return; 677 | } 678 | 679 | single_point = 0; 680 | first_single = 0; 681 | horilap = horilap_save; 682 | vertlap = vertlap_save; 683 | Terminate(); 684 | } 685 | void c_nngetwts(int *num_neig, int *fnbrs, float *fwts, float *px, float *py, float *pz) 686 | { 687 | int i; 688 | *num_neig = num_wts; 689 | for (i = 0; i < num_wts; i++) { 690 | fnbrs[i] = nbrs[i]; 691 | fwts[i] = (float) wts[i]; 692 | } 693 | for (i = 0; i < 3; i++) { 694 | px[i] = (float) points[datcnt+i][0]; 695 | py[i] = (float) points[datcnt+i][1]; 696 | pz[i] = (float) points[datcnt+i][2]; 697 | } 698 | } 699 | void c_nngetwtsd(int *num_neig, int *fnbrs, double *fwtsd, double *px, double *py, double *pz) 700 | { 701 | int i; 702 | *num_neig = num_wts; 703 | for (i = 0; i < num_wts; i++) { 704 | fnbrs[i] = nbrs[i]; 705 | fwtsd[i] = wts[i]; 706 | } 707 | for (i = 0; i < 3; i++) { 708 | px[i] = points[datcnt+i][0]; 709 | py[i] = points[datcnt+i][1]; 710 | pz[i] = points[datcnt+i][2]; 711 | } 712 | } 713 | -------------------------------------------------------------------------------- /src/nncrunch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Id: nncrunch.c,v 1.11 2008/07/27 03:10:12 haley Exp $ 3 | */ 4 | /************************************************************************ 5 | * * 6 | * The use of this Software is governed by a License Agreement. * 7 | * * 8 | ************************************************************************/ 9 | 10 | /* 11 | * The code in this file is based on code written and 12 | * copyrighted (C) by Dave Watson. Dr. Watson retains the 13 | * copyright to his original code. Augmentations and changes 14 | * to Dr. Watson's code are copyrighted (C) by UCAR, 1997. 15 | */ 16 | #include 17 | #include 18 | #include 19 | #include "nncheads.h" 20 | #include "nnchead.h" 21 | #include "nntypes.h" 22 | #include "nnexver.h" 23 | #include "nnuheads.h" 24 | #include "nnuhead.h" 25 | 26 | void Gradient() 27 | { int i0, i1, i2, i3; 28 | double u2, wxd, wyd, wxde, wydn, xc, xe, xn; 29 | for (i0=0; i0nextsimp; 62 | for (i2=0; i2<2; i2++) 63 | for (i3=0; i3<3; i3++) 64 | work3[i2][i3] = 65 | points[cursimp->vert[0]][i3] - 66 | points[cursimp->vert[i2+1]][i3]; 67 | work3[2][0] = work3[0][1] * work3[1][2] - 68 | work3[1][1] * work3[0][2]; 69 | work3[2][1] = work3[0][2] * work3[1][0] - 70 | work3[1][2] * work3[0][0]; 71 | work3[2][2] = work3[0][0] * work3[1][1] - 72 | work3[1][0] * work3[0][1]; 73 | u2 = 1; 74 | if (work3[2][2]<0) u2 = -1; 75 | xx += sqrt(SQ(work3[2][0]) + 76 | SQ(work3[2][1]) + SQ(work3[2][2])); 77 | for (i2=0; i2<3; i2++) points[i0][i2+3] += 78 | work3[2][i2] * u2; 79 | } 80 | xx = 1 - sqrt(SQ(points[i0][3]) + 81 | SQ(points[i0][4]) + 82 | SQ(points[i0][5])) / xx; 83 | points[i0][3] /= points[i0][5]; 84 | points[i0][4] /= points[i0][5]; 85 | points[i0][5] = xx; 86 | } 87 | } 88 | for (i0=0; i0<3; i0++) 89 | { points[datcnt+i0][3] = -bbb; 90 | points[datcnt+i0][4] = -ccc; 91 | points[datcnt+i0][5] = 1; 92 | } 93 | } 94 | void FindNeigh(ipt) 95 | int ipt; 96 | { int i0, i1, i2, i3, j1, j2, j3, j4, j5; 97 | if (rootsimp->nextsimp EQ NULL) 98 | { 99 | rootsimp->nextsimp = IMakeSimp(); 100 | if (error_status) return; 101 | } 102 | cursimp = rootsimp->nextsimp; 103 | cursimp->vert[0] = datcnt; 104 | cursimp->vert[1] = datcnt + 1; 105 | cursimp->vert[2] = datcnt + 2; 106 | cursimp->cent[0] = cursimp->cent[1] = 0.5; 107 | cursimp->cent[2] = BIGNUM; 108 | numtri = 1; 109 | lasttemp = roottemp; 110 | for (i2=0; i2<3; i2++) 111 | { j1 = 0; 112 | if (j1 EQ i2) j1++; 113 | j2 = j1 + 1; 114 | if (j2 EQ i2) j2++; 115 | if (lasttemp->nexttemp EQ NULL) 116 | { 117 | lasttemp->nexttemp = IMakeTemp(); 118 | if (error_status) return; 119 | } 120 | lasttemp = lasttemp->nexttemp; 121 | lasttemp->end[0] = cursimp->vert[j1]; 122 | lasttemp->end[1] = cursimp->vert[j2]; 123 | } 124 | curtemp = roottemp; 125 | for (i1=0; i1<3; i1++) 126 | { curtemp = curtemp->nexttemp; 127 | for (i2=0; i2<2; i2++) 128 | { work3[i2][0] = points[curtemp->end[i2]][0] - 129 | points[ipt][0]; 130 | work3[i2][1] = points[curtemp->end[i2]][1] - 131 | points[ipt][1]; 132 | work3[i2][2] = work3[i2][0] * 133 | (points[curtemp->end[i2]][0] + 134 | points[ipt][0]) / 2 + work3[i2][1] * 135 | (points[curtemp->end[i2]][1] + 136 | points[ipt][1]) / 2; 137 | } 138 | xx = work3[0][0] * work3[1][1] - 139 | work3[1][0] * work3[0][1]; 140 | cursimp->cent[0] = (work3[0][2] * work3[1][1] - 141 | work3[1][2] * work3[0][1]) / xx; 142 | cursimp->cent[1] = (work3[0][0] * work3[1][2] - 143 | work3[1][0] * work3[0][2]) / xx; 144 | cursimp->cent[2] = SQ(points[ipt][0] - 145 | cursimp->cent[0]) + SQ(points[ipt][1] - 146 | cursimp->cent[1]); 147 | cursimp->vert[0] = curtemp->end[0]; 148 | cursimp->vert[1] = curtemp->end[1]; 149 | cursimp->vert[2] = ipt; 150 | lastsimp = cursimp; 151 | if (cursimp->nextsimp EQ NULL) 152 | { 153 | cursimp->nextsimp = IMakeSimp(); 154 | if (error_status) return; 155 | } 156 | cursimp = cursimp->nextsimp; 157 | } 158 | numtri += 2; 159 | for (i0=0; i0nextsimp; 168 | xx = cursimp->cent[2] - 169 | SQ(points[i0][0] - cursimp->cent[0]); 170 | if (xx > 0) 171 | { xx -= SQ(points[i0][1] - 172 | cursimp->cent[1]); 173 | if (xx > 0) 174 | { j4--; 175 | for (i2=0; i2<3; i2++) 176 | { j1 = 0; 177 | if (j1 EQ i2) j1++; 178 | j2 = j1 + 1; 179 | if (j2 EQ i2) j2++; 180 | if (j3>1) 181 | { j5 = j3; 182 | curtemp = roottemp; 183 | for (i3=0; i3<=j5; i3++) 184 | { prevtemp = curtemp; 185 | curtemp = 186 | curtemp->nexttemp; 187 | if (cursimp->vert[j1] EQ 188 | curtemp->end[0]) 189 | { if (cursimp->vert[j2] EQ 190 | curtemp->end[1]) 191 | { if (curtemp EQ lasttemp) 192 | lasttemp = prevtemp; 193 | else 194 | { prevtemp->nexttemp = 195 | curtemp->nexttemp; 196 | curtemp->nexttemp = 197 | lasttemp->nexttemp; 198 | lasttemp->nexttemp = 199 | curtemp; 200 | } 201 | j3--; 202 | goto NextOne; 203 | } 204 | } 205 | } 206 | } 207 | if (lasttemp->nexttemp EQ NULL) 208 | { 209 | lasttemp->nexttemp = IMakeTemp(); 210 | if (error_status) return; 211 | } 212 | lasttemp = lasttemp->nexttemp; 213 | j3++; 214 | lasttemp->end[0] = 215 | cursimp->vert[j1]; 216 | lasttemp->end[1] = 217 | cursimp->vert[j2]; 218 | NextOne:; } 219 | if (cursimp EQ lastsimp) 220 | lastsimp = prevsimp; 221 | else 222 | { prevsimp->nextsimp = 223 | cursimp->nextsimp; 224 | cursimp->nextsimp = 225 | lastsimp->nextsimp; 226 | lastsimp->nextsimp = cursimp; 227 | cursimp = prevsimp; 228 | } 229 | } 230 | } 231 | } 232 | if (j3 > -1) 233 | { curtemp = roottemp; 234 | cursimp = lastsimp->nextsimp; 235 | for (i1=0; i1<=j3; i1++) 236 | { curtemp = curtemp->nexttemp; 237 | if (curtemp->end[0] EQ ipt OR 238 | curtemp->end[1] EQ ipt) 239 | { for (i2=0; i2<2; i2++) 240 | { work3[i2][0] = 241 | points[curtemp->end[i2]][0] - 242 | points[i0][0]; 243 | work3[i2][1] = 244 | points[curtemp->end[i2]][1] - 245 | points[i0][1]; 246 | work3[i2][2] = work3[i2][0] * 247 | (points[curtemp->end[i2]][0] + 248 | points[i0][0]) / 2 + 249 | work3[i2][1] * 250 | (points[curtemp->end[i2]][1] + 251 | points[i0][1]) / 2; 252 | } 253 | xx = work3[0][0] * work3[1][1] - 254 | work3[1][0] * work3[0][1]; 255 | cursimp->cent[0] = (work3[0][2] * 256 | work3[1][1] - work3[1][2] * 257 | work3[0][1]) / xx; 258 | cursimp->cent[1] = (work3[0][0] * 259 | work3[1][2] - work3[1][0] * 260 | work3[0][2]) / xx; 261 | cursimp->cent[2] = 262 | SQ(points[i0][0] - 263 | cursimp->cent[0]) + 264 | SQ(points[i0][1] - 265 | cursimp->cent[1]); 266 | cursimp->vert[0] = curtemp->end[0]; 267 | cursimp->vert[1] = curtemp->end[1]; 268 | cursimp->vert[2] = i0; 269 | lastsimp = cursimp; 270 | if (cursimp->nextsimp EQ NULL) 271 | { 272 | cursimp->nextsimp = IMakeSimp(); 273 | if (error_status) return; 274 | } 275 | cursimp = cursimp->nextsimp; 276 | j4++; 277 | } 278 | } 279 | numtri += j4; 280 | } 281 | } 282 | } 283 | for (i0=0; i0nextsimp; 287 | for (i2=0; i2<3; i2++) 288 | { if (cursimp->vert[i2] < datcnt) 289 | { if (cursimp->vert[i2] NE ipt) 290 | jndx[cursimp->vert[i2]] = 1; 291 | } 292 | else ext = 1; 293 | } 294 | } 295 | } 296 | void TriNeigh() 297 | { int i0, i1, i2, i3, j1, j2, j3, j4, j5; 298 | if (rootsimp->nextsimp EQ NULL) 299 | { 300 | rootsimp->nextsimp = IMakeSimp(); 301 | if (error_status) return; 302 | } 303 | lastsimp = cursimp = rootsimp->nextsimp; 304 | cursimp->vert[0] = datcnt; 305 | cursimp->vert[1] = datcnt + 1; 306 | cursimp->vert[2] = datcnt + 2; 307 | cursimp->cent[0] = cursimp->cent[1] = 0.5; 308 | cursimp->cent[2] = BIGNUM; 309 | numtri = 1; 310 | for (i0=0; i0nextsimp; 318 | xx = cursimp->cent[2] - 319 | SQ(points[i0][0] - cursimp->cent[0]); 320 | if (xx > 0) 321 | { xx -= SQ(points[i0][1] - 322 | cursimp->cent[1]); 323 | if (xx > 0) 324 | { for (i2=0; i2<3; i2++) 325 | { j1 = 0; 326 | if (j1 EQ i2) j1++; 327 | j2 = j1 + 1; 328 | if (j2 EQ i2) j2++; 329 | if (j3>1) 330 | { j5 = j3; 331 | curtemp = roottemp; 332 | for (i3=0; i3<=j5; i3++) 333 | { prevtemp = curtemp; 334 | curtemp = 335 | curtemp->nexttemp; 336 | if (cursimp->vert[j1] EQ 337 | curtemp->end[0]) 338 | { if (cursimp->vert[j2] EQ 339 | curtemp->end[1]) 340 | { if (curtemp EQ lasttemp) 341 | lasttemp = prevtemp; 342 | else 343 | { prevtemp->nexttemp = 344 | curtemp->nexttemp; 345 | curtemp->nexttemp = 346 | lasttemp->nexttemp; 347 | lasttemp->nexttemp = 348 | curtemp; 349 | } 350 | j3--; 351 | goto NextOne; 352 | } 353 | } 354 | } 355 | } 356 | if (lasttemp->nexttemp EQ NULL) 357 | { 358 | lasttemp->nexttemp = IMakeTemp(); 359 | if (error_status) return; 360 | } 361 | lasttemp = lasttemp->nexttemp; 362 | j3++; 363 | lasttemp->end[0] = 364 | cursimp->vert[j1]; 365 | lasttemp->end[1] = 366 | cursimp->vert[j2]; 367 | NextOne:; } 368 | if (cursimp EQ lastsimp) 369 | lastsimp = prevsimp; 370 | else 371 | { prevsimp->nextsimp = 372 | cursimp->nextsimp; 373 | cursimp->nextsimp = 374 | lastsimp->nextsimp; 375 | lastsimp->nextsimp = cursimp; 376 | cursimp = prevsimp; 377 | } 378 | } 379 | } 380 | } 381 | curtemp = roottemp; 382 | cursimp = lastsimp->nextsimp; 383 | for (i1=0; i1<=j3; i1++) 384 | { curtemp = curtemp->nexttemp; 385 | for (i2=0; i2<2; i2++) 386 | { work3[i2][0] = 387 | points[curtemp->end[i2]][0] - 388 | points[i0][0]; 389 | work3[i2][1] = 390 | points[curtemp->end[i2]][1] - 391 | points[i0][1]; 392 | work3[i2][2] = work3[i2][0] * 393 | (points[curtemp->end[i2]][0] + 394 | points[i0][0]) / 2 + work3[i2][1] * 395 | (points[curtemp->end[i2]][1] + 396 | points[i0][1]) / 2; 397 | } 398 | xx = work3[0][0] * work3[1][1] - 399 | work3[1][0] * work3[0][1]; 400 | cursimp->cent[0] = 401 | (work3[0][2] * work3[1][1] - 402 | work3[1][2] * work3[0][1]) / xx; 403 | cursimp->cent[1] = 404 | (work3[0][0] * work3[1][2] - 405 | work3[1][0] * work3[0][2]) / xx; 406 | cursimp->cent[2] = SQ(points[i0][0] - 407 | cursimp->cent[0]) + SQ(points[i0][1] - 408 | cursimp->cent[1]); 409 | cursimp->vert[0] = curtemp->end[0]; 410 | cursimp->vert[1] = curtemp->end[1]; 411 | cursimp->vert[2] = i0; 412 | lastsimp = cursimp; 413 | if (cursimp->nextsimp EQ NULL) 414 | { 415 | cursimp->nextsimp = IMakeSimp(); 416 | if (error_status) return; 417 | } 418 | cursimp = cursimp->nextsimp; 419 | } 420 | numtri += 2; 421 | } 422 | } 423 | cursimp = rootsimp; 424 | for (asum=0, i0=0; i0nextsimp; 426 | for (i1=0; i1<2; i1++) 427 | { work3[0][i1] = points[cursimp->vert[1]][i1] - 428 | points[cursimp->vert[0]][i1]; 429 | work3[1][i1] = points[cursimp->vert[2]][i1] - 430 | points[cursimp->vert[0]][i1]; 431 | } 432 | xx = work3[0][0] * work3[1][1] - 433 | work3[0][1] * work3[1][0]; 434 | if (xx < 0) 435 | { j4 = cursimp->vert[2]; 436 | cursimp->vert[2] = cursimp->vert[1]; 437 | cursimp->vert[1] = j4; 438 | if (cursimp->vert[0] < datcnt) 439 | asum -= xx / 2; 440 | } 441 | else if (cursimp->vert[0] < datcnt) 442 | asum += xx / 2; 443 | } 444 | } 445 | void CircOut() 446 | { 447 | FILE *filer; 448 | int ix,i0; 449 | struct simp *simpaddr; 450 | if (adf) 451 | { 452 | for (i0 = 0; i0 < datcnt; i0++) jndx[i0] = 1; 453 | TriNeigh(); 454 | if (error_status) return; 455 | 456 | if ((filer = fopen(tri_file,"w")) EQ (FILE *) NULL) 457 | { 458 | ErrorHnd(3, "CircOut", stderr, "\n"); 459 | error_status = 3; 460 | return; 461 | } 462 | 463 | /* 464 | * Put out defaults for plot control parameters. 465 | */ 466 | fprintf(filer,"/*\n"); 467 | fprintf(filer,"/* Integer flags (I5 format).\n"); 468 | fprintf(filer,"/*\n"); 469 | fprintf(filer,"/*..+....1....+....2....+....3....+....4" 470 | "....+....5....+....6....+....7....+....8\n"); 471 | fprintf(filer," 8 - GKS workstation type " 472 | "(1=ncgm; 8=X11 window; 20=PostScript).\n"); 473 | fprintf(filer," 1 - flags whether axes should be drawn.\n"); 474 | fprintf(filer," 0 - Halfax/Grid flag (0=halfax and 1=grid)\n"); 475 | fprintf(filer," 1 - Flags whether triangulation should be drawn.\n"); 476 | fprintf(filer," 0 - Flags whether a blue dot should be drawn " 477 | "at (0.,0.) [0=no; 1=yes]\n"); 478 | fprintf(filer," 0 - Flag to indicate whether the pseudo data " 479 | "should be included in the plot.\n"); 480 | fprintf(filer," 1 - Flag indicating whether the natural " 481 | "neighbor circles are drawn.\n"); 482 | fprintf(filer," 1 - Flags whether the centers of the natural " 483 | "neighborhood circles are drawn.\n"); 484 | fprintf(filer," 1 - Flag indicating if Voronoi polygons should " 485 | "be drawn [0=no; 1=yes].\n"); 486 | fprintf(filer," 1 - Flag indicating if the original points are " 487 | "to be marked.\n"); 488 | 489 | fprintf(filer,"/*\n"); 490 | fprintf(filer,"/* Color information (3F7.3 format) as RGB triples\n"); 491 | fprintf(filer,"/*\n"); 492 | fprintf(filer,"/*..+....1....+....2....+....3....+....4" 493 | "....+....5....+....6....+....7....+....8\n"); 494 | fprintf(filer," 0.000 0.000 0.000 - background color\n"); 495 | fprintf(filer," 1.000 1.000 1.000 - foreground color " 496 | "(used for axes)\n"); 497 | fprintf(filer," 1.000 0.000 0.000 - circumcircle color\n"); 498 | fprintf(filer," 0.000 1.000 0.000 - color of circumcircle " 499 | "centers\n"); 500 | fprintf(filer," 0.000 1.000 1.000 - color for triangulation\n"); 501 | fprintf(filer," 1.000 1.000 0.000 - Voronoi polygon color\n"); 502 | fprintf(filer," 1.000 1.000 0.000 - color of vertex dots\n"); 503 | fprintf(filer," 0.000 0.000 1.000 - color of reference dot\n"); 504 | fprintf(filer," 0.000 0.000 1.000 - color for natural neighbor " 505 | "points\n"); 506 | fprintf(filer," 1.000 1.000 1.000 - color to mark points where " 507 | "natural neighbors are desired\n"); 508 | 509 | fprintf(filer,"/*\n"); 510 | fprintf(filer,"/* Scale factors (F7.3 format)\n"); 511 | fprintf(filer,"/*\n"); 512 | fprintf(filer,"/*..+....1....+....2....+....3....+....4" 513 | "....+....5....+....6....+....7....+....8\n"); 514 | fprintf(filer," 1.000 - scale factor for dots at vertices\n"); 515 | fprintf(filer," 1.000 - scale factor for circumcircle centers\n"); 516 | fprintf(filer," 2.000 - scale factor for circle lines\n"); 517 | fprintf(filer," 2.000 - scale factor for Voronoi polygon lines\n"); 518 | fprintf(filer," 2.000 - scale factor for tringulation lines\n"); 519 | fprintf(filer," 1.000 - scale factor for axes lines\n"); 520 | fprintf(filer," 1.000 - scale factor for points where natural " 521 | "neighbors are desired\n"); 522 | fprintf(filer," 1.000 - scale factor for points marking natural " 523 | "neighbors\n"); 524 | 525 | fprintf(filer,"/*\n"); 526 | fprintf(filer,"/* User coordinates for SET call (4E15.3 format), " 527 | "defaults if all zeros\n"); 528 | fprintf(filer,"/*\n"); 529 | fprintf(filer,"/*..+....1....+....2....+....3....+....4" 530 | "....+....5....+....6....+....7....+....8\n"); 531 | fprintf(filer," 0.000E+00 0.000E+00 0.000E+00 " 532 | " 0.000E+00\n"); 533 | 534 | fprintf(filer,"/*\n"); 535 | fprintf(filer,"/* Number of user input data. (I5 format)\n"); 536 | fprintf(filer,"/*\n"); 537 | fprintf(filer,"/*..+....1....+....2....+....3....+....4" 538 | "....+....5....+....6....+....7....+....8\n"); 539 | fprintf(filer,"%5d\n",datcnt); 540 | 541 | fprintf(filer,"/*\n"); 542 | fprintf(filer,"/* User data. The datum number occurs first " 543 | "(in I5 format) followed\n"); 544 | fprintf(filer,"/* by the x,y,z values (in E15.3 format).\n"); 545 | fprintf(filer,"/*\n"); 546 | fprintf(filer,"/*..+....1....+....2....+....3....+....4" 547 | "....+....5....+....6....+....7....+....8\n"); 548 | for (ix = 0; ix < datcnt; ix++) { 549 | fprintf(filer,"%5d%15.3E%15.3E%15.3E\n", 550 | ix+1,points[ix][0],points[ix][1],points[ix][2]); 551 | } 552 | 553 | fprintf(filer,"/*\n"); 554 | fprintf(filer,"/* Pseudo data.\n"); 555 | fprintf(filer,"/*\n"); 556 | fprintf(filer,"/*..+....1....+....2....+....3....+....4" 557 | "....+....5....+....6....+....7....+....8\n"); 558 | for (ix = datcnt; ix < datcnt+3; ix++) { 559 | fprintf(filer,"%5d%15.3E%15.3E%15.3E\n", 560 | ix+1,points[ix][0],points[ix][1],points[ix][2]); 561 | } 562 | 563 | fprintf(filer,"/*\n"); 564 | fprintf(filer,"/* The number of circumcircles (I5 format).\n"); 565 | fprintf(filer,"/*\n"); 566 | fprintf(filer,"/*..+....1....+....2....+....3....+....4" 567 | "....+....5....+....6....+....7....+....8\n"); 568 | simpaddr = rootsimp->nextsimp; 569 | fprintf(filer,"%5d\n",numtri); 570 | 571 | fprintf(filer,"/*\n"); 572 | fprintf(filer,"/* Circumcircle data. The first three numbers are " 573 | "the numbers of the\n"); 574 | fprintf(filer,"/* data (as listed above) lying on the " 575 | "circumcircle; the next two\n"); 576 | fprintf(filer,"/* numbers give the center position of the " 577 | "circumcircle; the final\n"); 578 | fprintf(filer,"/* number is the square of the radius of the " 579 | "circumcircle.\n"); 580 | fprintf(filer,"/*\n"); 581 | fprintf(filer,"/*..+....1....+....2....+....3....+....4" 582 | "....+....5....+....6....+....7....+....8\n"); 583 | for (ix = 0; ix < numtri; ix++) { 584 | fprintf(filer,"%5d%5d%5d%15.3E%15.3E%15.3E\n", 585 | simpaddr->vert[0]+1,simpaddr->vert[1]+1,simpaddr->vert[2]+1, 586 | simpaddr->cent[0],simpaddr->cent[1],simpaddr->cent[2]); 587 | simpaddr = simpaddr->nextsimp; 588 | } 589 | 590 | fprintf(filer,"/*\n"); 591 | fprintf(filer,"/* Number of points where natural neighbors are " 592 | "to be marked and\n"); 593 | fprintf(filer,"/* a flag indicating whether just the points where " 594 | "first order neighbors\n"); 595 | fprintf(filer,"/* are desired are marked (-1), whether the first " 596 | " order neighbors \n"); 597 | fprintf(filer,"/* will be marked as well (0), or both first and " 598 | "second order neighbors\n"); 599 | fprintf(filer,"/* are marked (1). The points will be marked with " 600 | "Xs, in the\n"); 601 | fprintf(filer,"/* color described above. (2I5 format)\n"); 602 | fprintf(filer,"/*\n"); 603 | fprintf(filer,"/*..+....1....+....2....+....3....+....4" 604 | "....+....5....+....6....+....7....+....8\n"); 605 | fprintf(filer," 0 0\n"); 606 | fprintf(filer,"/*\n"); 607 | fprintf(filer,"/* The coordinate list of points whose natural " 608 | "neighbors are to\n"); 609 | fprintf(filer,"/* be displayed (using the color index as described " 610 | "above), should\n"); 611 | fprintf(filer,"/* be listed here in 2E15.3 format.\n"); 612 | fprintf(filer,"/*\n"); 613 | fprintf(filer,"/*..+....1....+....2....+....3....+....4" 614 | "....+....5....+....6....+....7....+....8\n"); 615 | fprintf(filer,"/* 0.000E-00 0.000E-00\n"); 616 | 617 | fclose(filer); 618 | return; 619 | } 620 | } 621 | 622 | void FindProp(wxd, wyd) 623 | double wxd, wyd; 624 | { int i2, i3, i4, pos_count, inside; 625 | double xx, work3[3][3], work4[3][2]; 626 | lastneig = rootneig; 627 | goodflag = 0; 628 | numnei = -1; 629 | cursimp = rootsimp; 630 | for (i2=0; i2nextsimp; 632 | xx = cursimp->cent[2] - 633 | SQ(wxd - cursimp->cent[0]); 634 | if (xx > 0) 635 | { xx -= SQ(wyd - cursimp->cent[1]); 636 | if (xx > 0) 637 | { inside = 0; 638 | if (cursimp->vert[0] < datcnt) inside = 1; 639 | for (i3=0; i3<3; i3++) 640 | { for (i4=0; i4<2; i4++) 641 | { work3[i4][0] = 642 | points[cursimp-> 643 | vert[scor[i3][i4]]][0] - wxd; 644 | work3[i4][1] = 645 | points[cursimp-> 646 | vert[scor[i3][i4]]][1] - wyd; 647 | work3[i4][2] = work3[i4][0] * 648 | (points[cursimp-> 649 | vert[scor[i3][i4]]][0] + 650 | wxd) / 2 + work3[i4][1] * 651 | (points[cursimp-> 652 | vert[scor[i3][i4]]][1] + 653 | wyd) / 2; 654 | } 655 | xx = work3[0][0] * work3[1][1] - 656 | work3[1][0] * work3[0][1]; 657 | work4[i3][0] = (work3[0][2] * 658 | work3[1][1] - work3[1][2] * 659 | work3[0][1]) / xx; 660 | work4[i3][1] = (work3[0][0] * 661 | work3[1][2] - work3[1][0] * 662 | work3[0][2]) / xx; 663 | } 664 | pos_count = 0; 665 | for (i3=0; i3<3; i3++) 666 | { work3[2][i3] = 667 | ((work4[scor[i3][0]][0] - 668 | cursimp->cent[0]) * 669 | (work4[scor[i3][1]][1] - 670 | cursimp->cent[1]) - 671 | (work4[scor[i3][1]][0] - 672 | cursimp->cent[0]) * 673 | (work4[scor[i3][0]][1] - 674 | cursimp->cent[1])) / 2; 675 | if (work3[2][i3]>0) pos_count++; 676 | } 677 | if (pos_count>2 AND inside) goodflag = 1; 678 | for (i3=0; i3<3; i3++) 679 | { if (numnei>1) 680 | { curneig = rootneig; 681 | for (i4=0; i4<=numnei; i4++) 682 | { curneig = curneig->nextneig; 683 | if (cursimp->vert[i3] EQ 684 | curneig->neinum) 685 | { curneig->narea += 686 | work3[2][i3]; 687 | goto GOTEM; 688 | } 689 | } 690 | } 691 | if (lastneig->nextneig EQ NULL) 692 | { 693 | lastneig->nextneig = IMakeNeig(); 694 | if (error_status) return; 695 | } 696 | lastneig = lastneig->nextneig; 697 | numnei++; 698 | lastneig->neinum = cursimp->vert[i3]; 699 | lastneig->narea = work3[2][i3]; 700 | GOTEM:; } 701 | } 702 | } 703 | } 704 | } 705 | double Surface() 706 | { int i0; 707 | double xx, asurf; 708 | curneig = rootneig; 709 | for (xx=0, i0=0; i0<=numnei; i0++) 710 | { curneig = curneig->nextneig; 711 | xx += curneig->narea; 712 | } 713 | curneig = rootneig; 714 | for (asurf=0, i0=0; i0<=numnei; i0++) 715 | { curneig = curneig->nextneig; 716 | curneig->narea /= xx; 717 | asurf += curneig->narea * 718 | points[curneig->neinum][2]; 719 | } 720 | if (jwts == 1) { 721 | num_wts = numnei+1; 722 | curneig = rootneig; 723 | for (i0=0; i0 <= numnei; i0++) { 724 | curneig = curneig->nextneig; 725 | nbrs[i0] = curneig->neinum; 726 | wts[i0] = curneig->narea; 727 | } 728 | } 729 | return asurf; 730 | } 731 | double Meld(double asurf, double wxd, double wyd) 732 | { int i0; 733 | double rS, rT, rB, bD, bB, hP; 734 | curneig = rootneig; 735 | for (i0 = 0 ; i0 <= numnei ; i0++) 736 | { 737 | curneig = curneig->nextneig; 738 | curneig->coord = 0; 739 | if (curneig->narea>0.00001 AND curneig->narea < 2) 740 | { 741 | if (fabs(points[curneig->neinum][5]) > 0.00001) 742 | { 743 | rS = fabs(points[curneig->neinum][5]) + bI; 744 | rT = rS * bJ; 745 | rB = 1 / rT; 746 | bD = pow(curneig->narea, rT); 747 | bB = bD * 2; 748 | if (bD>0.5) bB = (1 - bD) * 2; 749 | bB = pow(bB, rS) / 2; 750 | if (bD>0.5) bB = 1 - bB; 751 | hP = pow(bB, rB); 752 | curneig->coord = 753 | ((points[curneig->neinum][3] * 754 | points[curneig->neinum][0] + 755 | points[curneig->neinum][4] * 756 | points[curneig->neinum][1] + 757 | points[curneig->neinum][2] - 758 | points[curneig->neinum][3] * 759 | wxd - 760 | points[curneig->neinum][4] * 761 | wyd) - asurf) * hP; 762 | 763 | } 764 | } 765 | } 766 | curneig = rootneig; 767 | for (i0=0; i0<=numnei; i0++) 768 | { curneig = curneig->nextneig; 769 | asurf += curneig->coord; 770 | } 771 | return asurf; 772 | } 773 | void TooSteep() 774 | { 775 | ErrorHnd(4,"TooSteep", stderr, "\n"); 776 | igrad = 0; 777 | } 778 | void TooShallow() 779 | { 780 | ErrorHnd(5,"TooShallow", stderr, "\n"); 781 | igrad = 0; 782 | } 783 | void TooNarrow() 784 | { 785 | ErrorHnd(6, "TooNarrow", stderr, "\n"); 786 | igrad = 0; 787 | } 788 | int *IntVect(int ncols) 789 | { 790 | int *vectptr; 791 | if ((vectptr = (int *) malloc(ncols * sizeof(int))) EQ (int *) NULL) 792 | { 793 | error_status = 7; 794 | ErrorHnd(error_status, "IntVect", stderr, "\n"); 795 | vectptr = (int *) NULL; 796 | } 797 | return vectptr; 798 | } 799 | void FreeVecti(int *vectptr) 800 | { 801 | free(vectptr); 802 | } 803 | double *DoubleVect(int ncols) 804 | { 805 | double *vectptr; 806 | if ((vectptr = (double *) 807 | malloc(ncols * sizeof(double))) EQ (double *) NULL) 808 | { 809 | error_status = 8; 810 | ErrorHnd(error_status, "DoubleVect", stderr, "\n"); 811 | return ( (double *) NULL); 812 | } 813 | return vectptr; 814 | } 815 | void FreeVectd(double *vectptr) 816 | { 817 | free(vectptr); 818 | } 819 | int **IntMatrix(int nrows, int ncols) 820 | { int i0; 821 | int **matptr; 822 | if (nrows < 2) nrows = 2; 823 | if (ncols < 2) ncols = 2; 824 | if ((matptr = (int **) 825 | malloc(nrows * sizeof(int *))) EQ (int **) NULL) 826 | { 827 | error_status = 9; 828 | ErrorHnd(error_status, "IntMatrix", stderr, "\n"); 829 | return ( (int **) NULL); 830 | } 831 | if ((matptr[0] = (int *) 832 | malloc(nrows * ncols * sizeof(int))) EQ (int *) NULL) 833 | { 834 | error_status = 10; 835 | ErrorHnd(error_status, "IntMatrix", stderr, "\n"); 836 | return ( (int **) NULL); 837 | } 838 | for (i0=1; i0nextdat = NULL; 915 | return datptr; 916 | } 917 | struct simp *IMakeSimp() 918 | { 919 | struct simp *simpptr; 920 | if ((simpptr = (struct simp *) 921 | malloc(sizeof(struct simp))) EQ (struct simp *) NULL) 922 | { 923 | error_status = 16; 924 | ErrorHnd(error_status, "IMakeSimp", stderr, "\n"); 925 | return ((struct simp *) NULL); 926 | } 927 | simpptr->nextsimp = NULL; 928 | return (simpptr); 929 | } 930 | struct temp *IMakeTemp() 931 | { 932 | struct temp *tempptr; 933 | if ((tempptr = (struct temp *) 934 | malloc(sizeof(struct temp))) EQ (struct temp *) NULL) 935 | { 936 | error_status = 17; 937 | ErrorHnd(error_status, "IMakeTemp", stderr, "\n"); 938 | return ((struct temp *) NULL); 939 | } 940 | tempptr->nexttemp = NULL; 941 | return tempptr; 942 | } 943 | struct neig *IMakeNeig() 944 | { 945 | struct neig *neigptr; 946 | if ((neigptr = (struct neig *) 947 | malloc(sizeof(struct neig))) EQ (struct neig *) NULL) 948 | { 949 | error_status = 18; 950 | ErrorHnd(error_status, "IMakeNeig", stderr, "\n"); 951 | return ((struct neig *) NULL); 952 | } 953 | neigptr->nextneig = NULL; 954 | return neigptr; 955 | } 956 | --------------------------------------------------------------------------------