The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
/*--------------------------------------------------------------------
 *    The GMT-system:	@(#)gmt_bcr.h	3.13  06/17/99
 *
 *	Copyright (c) 1991-1999 by P. Wessel and W. H. F. Smith
 *	See COPYING file for copying and redistribution conditions.
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; version 2 of the License.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	Contact info: www.soest.hawaii.edu/gmt
 *--------------------------------------------------------------------*/
/* bcr.h  --  stuff for implementing bicubic rectangle grid interpolation.
   Has bilinear case as a subset.
   The bilinear interpolation will give continuity of the function z only.
   The bicubic interpolation will give continuity of z, dz/dx, dz/dy, and
   d2z/dxdy.
   Designed to operate with at least one spare row/column around each edge,
   to allow derivative computations.
   Follows the outline in Lancaster and Salkauskas, section 9.3
   Meant to replace Taylor routines in GMT in version 3.0 of GMT.

   Author:	Walter H F Smith
   Date:	23 September, 1993
   Revised:	20 September, 1998

   This include file defines structures and functions used.
*/

EXTERN_MSC struct BCR bcr;

EXTERN_MSC void GMT_bcr_init (struct GRD_HEADER *grd, int *pad, int bilinear);
EXTERN_MSC double GMT_get_bcr_z (struct GRD_HEADER *grd, double xx, double yy, float *data,  struct GMT_EDGEINFO *edgeinfo);		/* Compute z(x,y) from bcr structure  */

/*----------------------------------------------------------------
		Here are some more remarks:

	Define x,y on the bcr so that they are in the range [0,1).  For pixel grids
with points close to edges, x,y will have to be in [-0.5,1) or [0, 1.5].  Now the
rectangle has 4 vertices, which we number thus:
	vertex 0:	x=0, y=0;
	vertex 1:	x=1, y=0;
	vertex 2:	x=0, y=1;
	vertex 3:	x=1, y=1.

i,j in struct BCR refers to the location of vertex 0.  The i,j will be referred to
the struct GRD header values, not to the location in the padded array, so that i=0,
j=0 is the point h.x_min, h.y_max.

The nodal values are specified at each vertex as nodal_value[vertex][value], where
value stands for the following:
	value 0:	z;
	value 1:	dz/dx;
	value 2:	dzdy;
	value 3:	d2zdxdy.

If we want a bilinear estimate of z(x,y), only nodal_value[vertex][0] is needed
and the estimate is obtained thus:
	z = 0.0;
	for (vertex = 0; vertex < 4; vertex++)
		z += bl_basis[vertex] * nodal_value[vertex][0];

This means that bl_basis[i] is the function that gives 1 at vertex i and 0 at
the other three vertices:
	bl_basis[0] = (1.0 - x)*(1.0 - y);
	bl_basis[1] = x*(1.0 - y);
	bl_basis[2] = y*(1.0 - x);
	bl_basis[3] = x*y;


	If we want a bicubic surface, then there are sixteen multiply-add operations,
looping over vertex and over value.  There are 16 basis functions, which are more
complicated.  See the table in Lancaster and Salkauskas or the source code for
GMT_get_bcr_cardinals().

	Given a point xx,yy in user's units, we need to be able to find i,j for
that point and x,y.  This will depend on struct GRD_HEADER information.

	If i,j for x,y is not equal to the last i,j we need to recompute the
nodal_values.  If the current i,j is within +/- 1 of the last i,j we can save
some old nodal_values.  If we discover a NaN during the computation of these,
we cannot continue.

	If nan_condition is false, we can evaluate the cardinals and do the
multiply-adds.  If x=0 or 1 or y = 0 or 1, there may be a trivial solution.

*/