home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- #include <stdio.h>
- #include <stdlib.h>
-
- #include "SplineClass.h"
-
- //
- // SPLINE STUFF!!!!!
- // I stole these mostly from Drew Olbrich
- //
-
- SplineClass::SplineClass(int num, double *xvals, double *fvals)
- {
- int i;
- double t;
- double *h;
- double *u;
- double *ta;
- double *td;
- double *tb;
- double *tf;
- screwed = 0;
-
- if (num < 3) {
- fprintf(stderr, "too few points\n");
- screwed = 1;
- return;
- }
-
- x = (double *) malloc((num*sizeof(double)));
- if (x == NULL)
- {
- fprintf(stderr, "Could not allocate spline data.\n");
- screwed = 1;
- return;
- }
- for (i = 0; i < num; i++)
- x[i] = xvals[i];
-
- n = num;
- min_x = xvals[0];
- max_x = xvals[n - 1];
-
- a = (double *) malloc(n*sizeof(double));
- b = (double *) malloc(n*sizeof(double));
- c = (double *) malloc(n*sizeof(double));
- d = (double *) malloc(n*sizeof(double));
-
- if (d == NULL)
- {
- fprintf(stderr, "Could not allocate spline coefficient data.\n");
- screwed = 1;
- return;
- }
-
- h = (double *) malloc((n+1)*sizeof(double));
- u = (double *) malloc((n+1)*sizeof(double));
-
- ta = (double *) malloc((n+1)*sizeof(double));
- td = (double *) malloc((n+1)*sizeof(double));
- tb = (double *) malloc((n+1)*sizeof(double));
- tf = (double *) malloc((n+1)*sizeof(double));
-
- if (tf == NULL)
- {
- fprintf(stderr, "Could not allocate temporary spline data.\n");
- screwed = 1;
- return;
- }
-
- for (i = 0; i < n - 1; i++) {
- h[i] = x[i + 1] - x[i];
- u[i] = (fvals[i + 1] - fvals[i])/h[i];
- a[i] = fvals[i];
- }
-
- for (i = 0; i < (n - 2); i++)
- td[i] = 2.0*(h[i] + h[i + 1]);
-
- for (i = 0; i < (n - 2); i++)
- ta[i] = tb[i] = h[i + 1];
-
- for (i = 0; i < (n - 2); i++)
- tf[i] = 3.0*(u[i + 1] - u[i]);
-
- for (i = 1; i < (n - 2); i++)
- {
- t = ta[i - 1]/td[i - 1];
- td[i] = td[i] - t*tb[i - 1];
- tf[i] = tf[i] - t*tf[i - 1];
- }
-
- c[0] = 0.0;
- c[n - 1] = 0.0;
- c[n - 2] = tf[n - 3]/td[n - 3];
- for (i = (n - 4); i >= 0; i--)
- c[i + 1] = (tf[i] - tb[i]*c[i + 2])/td[i];
-
- for (i = 0; i < (n - 1); i++) {
- b[i] = u[i] - h[i]*(2.0*c[i] + c[i + 1])/3.0;
- d[i] = (c[i + 1] - c[i])/(h[i]*3.0);
- }
-
- free(h);
- free(u);
-
- free(ta);
- free(td);
- free(tb);
- free(tf);
-
- screwed = 0;
- }
-
- short SplineClass::isOk()
- {
- return screwed;
- }
-
- double SplineClass::evaluate(double t)
- {
- int i;
- int high, low, mid;
- double result, qq;
-
- if (screwed) {
- fprintf(stderr, "screwed!\n");
- return 0.0;
- }
-
- // I am changing this behavior so before min_x you get min_x and
- // after max_x you get max_x
- // if ((t < min_x) || (t > max_x))
- // return 0.0;
-
- low = 0;
- high = (int) n - 1;
-
- if (t < min_x) return a[low];
- if (t > max_x) return a[high];
-
- i = -1;
- while (i == -1 && low <= high) {
- mid = (low + high) >> 1;
- if (t < x[mid])
- high = mid - 1;
- else if (mid + 1 < n && t > x[mid + 1])
- low = mid + 1;
- else
- i = mid;
- }
- qq = t - x[i];
-
- result = a[i]
- + qq*(b[i] + qq*(c[i] + qq*d[i]));
-
- return result;
- }
-
-
- SplineClass::~SplineClass()
- {
- free(x);
- free(a);
- free(b);
- free(c);
- free(d);
- }
-