In each secondary estimation pass, only grid nodes that are adjacent to defined grid nodes are computed; multiple passes fill in the entire grid. During subsequent passes, only every other node in each direction is computed, and skipped nodes are filled in by a bicubic interpolation method. This method provides very good performance on large grids.
Each smoothing pass modifies the secondary estimates of node values that do not conform to the minimum curvature surface model. These modified values are then used as node value inputs to the next smoothing pass. While this iterative process converges rather slowly, as few as ten passes frequently produce very good results.
#include <stdio.h>
#include <Xm/Xm.h>
#include <Xm/PushB.h>
#include <Xm/Separator.h>
#include <Xm/Text.h>
#include <Xint/Box.h>
#include <Xint/Scroll.h>
#include <Xint/Contour.h>
/* Declare local and extern subroutines */
void BuildUI();
static void LocatorCallback();
static void ExitCallback();
extern double drand48();
/* Declare global variables */
Widget toplevel_widget;
Widget locator_text;
int i, j, n;
/* define constant */
#define NUM_POINTS 100
/* Main subroutine */
main(argc, argv)
int argc;
char *argv[];
{
XtAppContext app_context;
toplevel_widget = XtAppInitialize (&app_context, "Example", NULL, 0,
&argc, argv, NULL,NULL, 0);
BuildUI ();
XtRealizeWidget(toplevel_widget);
XtAppMainLoop(app_context);
}
/* Subroutine to build the user interface */
void BuildUI()
{
Widget main_vbox;
Widget control_hbox;
Widget sep, exit_pb;
Widget int_scroll;
Widget contour;
float start_x = 0;
float start_y = 0;
float end_x = 1.0;
float end_y = 1.0;
XintSourcePoint points[NUM_POINTS];
XmString cstring;
/* create a vertical box */
main_vbox = XtVaCreateManagedWidget("main_vbox", xintBoxWidgetClass,
toplevel_widget, NULL);
/* create a Scroll widget */
int_scroll = XtVaCreateManagedWidget("int_scroll",
xintScrollWidgetClass,
main_vbox,
XmNwidth, 500,
XmNheight, 500,
/* constraint resources from box */
XmNhorizontalStretch, XintFILL,
XmNhorizontalShrink , XintFILL,
XmNverticalStretch, XintFILL,
XmNverticalShrink, XintFILL,
NULL);
/* generate a random set of points for input to the contour */
srand48((long) NUM_POINTS);
for (i=0; i<NUM_POINTS; i++) {
points[i].x = drand48();
points[i].y = drand48();
points[i].z = drand48();
}
/* create the contour widget */
contour = XtVaCreateManagedWidget ("contour", xintContourWidgetClass,
int_scroll,
XmNwidth, 900,
XmNheight, 900,
XmNsourcePointArray, points,
XmNsourcePointCount, NUM_POINTS,
XmNcontourDisplayMode,
XintCONTOUR_FILLED_AND_LINE,
XmNgriddingMethod, XintGRIDDING_GLOBAL,
XmNcolormapFile, "contour.cmp",
XmNcolorScale, XintCOLOR_SCALE_LEFT,
XmNautoMarginAdjust, XintADJUST_ALL,
XmNstartDataX, &start_x,
XmNstartDataY, &start_y,
XmNendDataX, &end_x,
XmNendDataY, &end_y,
XmNverticalMajorThickness, 1,
XmNverticalMinorGridLineStyle,
XintGRID_LINE_DASHED,
XmNhorizontalMajorThickness, 1,
XmNhorizontalMajorThickness, 1,
XmNhorizontalMinorGridLineStyle,
XintGRID_LINE_DASHED,
NULL);
XtAddCallback(contour, XmNlocatorCallback, LocatorCallback, NULL);
/* create a separator */
sep = XtVaCreateManagedWidget("sep", xmSeparatorWidgetClass,
main_vbox,
/* constraint resources from box */
XmNhorizontalStretch, XintFILL,
XmNhorizontalShrink , XintFILL, NULL);
/* create a horizontal box */
control_hbox = XtVaCreateManagedWidget("control_hbox",
xintBoxWidgetClass,
main_vbox,
XmNorientation, XintHORIZONTAL,
NULL);
/* create Exit Push Button */
cstring = XmStringCreateLtoR("Exit", XmSTRING_DEFAULT_CHARSET);
exit_pb = XtVaCreateManagedWidget("exit_pb",
xmPushButtonWidgetClass,
control_hbox,
XmNlabelString, cstring, NULL);
XmStringFree(cstring);
XtAddCallback(exit_pb, XmNactivateCallback, ExitCallback, NULL);
/* locator label */
locator_text = XtVaCreateManagedWidget("locator", xmTextWidgetClass,
control_hbox,
XmNeditable, False,
XmNautoShowCursorPosition, False,
XmNeditMode, XmSINGLE_LINE_EDIT,
XmNtraversalOn, False,
XmNcolumns, 32,
/* constraint resources from box */
XmNhorizontalStretch, XintFILL,
XmNhorizontalShrink , XintFILL,
NULL);
}
/* Locator callback */
static void
LocatorCallback (Widget widget, XtPointer data,
XintGridLocatorCallbackStruct *cb)
{
char s[140];
float z;
XintContourGetZValue(widget, cb->user_x, cb->user_y, &z);
sprintf(s, "X: %.3f Y: %.3f Z: %.3f",cb->user_x, cb->user_y, z);
XmTextSetString(locator_text, s);
}
/* Exit Callback */
static void ExitCallback (Widget widget, XtPointer data,
XmAnyCallbackStruct *cb)
{
exit(0);
}
The output from example contour_1.c is shown below:

#include <stdio.h>
#include <Xm/Xm.h>
#include <Xm/Separator.h>
#include <Xm/PushB.h>
#include <Xint/Box.h>
#include <Xint/Contour.h>
/*
* Declare local and extern subroutines
*/
void BuildUI();
static void ExitCallback();
static float *ReadGrid();
/*
* Declare global variables
*/
Widget toplevel_widget;
int i, j, n;
/* Main subroutine */
main(argc, argv)
int argc;
char *argv[];
{
XtAppContext app_context;
toplevel_widget = XtAppInitialize (&app_context, "Example", NULL, 0,
&argc, argv, NULL, NULL, 0);
BuildUI ();
XtRealizeWidget(toplevel_widget);
XtAppMainLoop(app_context);
}
/* Subroutine to build the user interface */
void BuildUI()
{
Widget main_vbox;
Widget control_hbox;
Widget sep, exit_pb;
Widget contour;
float start_x;
float start_y ;
float end_x;
float end_y;
float *grid;
float null_value = 999999.0;
int num_grid_x, num_grid_y;
XmString cstring;
/* create a vertical box */
main_vbox = XtVaCreateManagedWidget("main_vbox", xintBoxWidgetClass,
toplevel_widget, NULL);
/* read grid */
grid = ReadGrid(&num_grid_x, &num_grid_y, &start_x, &start_y,
&end_x, &end_y);
/* create the contour widget */
contour = XtVaCreateManagedWidget ("contour", xintContourWidgetClass,
main_vbox,
XmNwidth, 700,
XmNheight, 700,
XmNgridData, grid,
XmNnullValue, &null_value,
XmNnumGridX, num_grid_x,
XmNnumGridY, num_grid_y,
XmNautoMarginAdjust, XintADJUST_ALL,
XmNstartDataX, &start_x,
XmNstartDataY, &start_y,
XmNendDataX, &end_x,
XmNendDataY, &end_y,
XmNverticalMajorGridLineStyle,
XintGRID_LINE_NONE,
XmNhorizontalMajorGridLineStyle,
XintGRID_LINE_NONE,
/* constraint resources from box */
XmNhorizontalStretch, XintFILL,
XmNverticalStretch, XintFILL,
XmNhorizontalShrink, XintFILL,
XmNverticalShrink, XintFILL,
NULL);
/* create a separator */
sep = XtVaCreateManagedWidget("sep", xmSeparatorWidgetClass,
main_vbox,
/* constraint resources from box */
XmNhorizontalStretch, XintFILL,
XmNhorizontalShrink , XintFILL, NULL);
/* create a horizontal box */
control_hbox = XtVaCreateManagedWidget("control_hbox",
xintBoxWidgetClass,
main_vbox,
XmNorientation, XintHORIZONTAL,
NULL);
/* create Exit Push Button */
cstring = XmStringCreateLtoR("Exit", XmSTRING_DEFAULT_CHARSET);
exit_pb = XtVaCreateManagedWidget("exit_pb",
xmPushButtonWidgetClass,
control_hbox,
XmNlabelString, cstring, NULL);
XmStringFree(cstring);
XtAddCallback(exit_pb, XmNactivateCallback, ExitCallback, NULL);
}
/* Exit Callback **/
static void
ExitCallback (Widget widget, XtPointer data, XmAnyCallbackStruct *cb)
{
exit(0);
}
/* ReadGrid */
static float * ReadGrid(int *num_grid_x, int *num_grid_y,
float *start_x, float *start_y,
float *end_x, float *end_y)
{
... /* see contour_2.c */
}
The output from example contour_2.c is shown below:
