00001 /* 00002 File: Hermite.cc 00003 00004 Function: 00005 00006 Author: Andrew Willmott 00007 00008 Notes: 00009 */ 00010 00011 #include "gcl/Hermite.h" 00012 00013 00014 /* This basis takes [x(0),x(1),x'(0),x'(1)] as knot points 00015 Each column holds the coefficients of one of the Hermite 00016 polynomials. */ 00017 00018 static Transform gHermiteMatrix( 00019 1.0, 0.0, 0.0, 0.0, 00020 0.0, 0.0, 1.0, 0.0, 00021 -3.0, 3.0, -2.0, -1.0, 00022 2.0, -2.0, 1.0, 1.0 00023 ); 00024 00025 00026 /* 00027 Calculate hermite coefficients. 00028 00029 t0, y0, ySlope0 are start time, value, and slope. 00030 t1, y1, ySlope1 are end time, value, and slope. 00031 t1 had better not equal t0. 00032 00033 For automatic slope control, set 00034 ySlope1 = (y2 - y0) / (t2 - t0); 00035 ySlope0 = (y1 - y-1) / (t1 - t-1); 00036 */ 00037 00038 Void CalcHermiteCoeffs( 00039 GCLReal t0, 00040 GCLReal t1, 00041 GCLReal y0, 00042 GCLReal y1, 00043 GCLReal ySlope0, 00044 GCLReal ySlope1, 00045 Cubic &result 00046 ) 00047 { 00048 result = gHermiteMatrix * 00049 Cubic(y0, y1, ySlope0 * (t1 - t0), ySlope1 * (t1 - t0)); 00050 } 00051 00052 GCLReal EvalCubic(Cubic &cubicCoeffs, GCLReal t, GCLReal t0, GCLReal t1) 00053 // evaluate y(t), using coeffs computed by CalcHermiteCoeffs(). 00054 // t0, t1 have to be same as you supplied to CalcHermiteCoeffs(). 00055 // t should be between t0 and t1, inclusive. 00056 { 00057 GCLReal u = (t - t0) / (t1 - t0); 00058 Cubic uCubic(1, u, sqr(u), sqr(u) * u); 00059 00060 return(dot(uCubic, cubicCoeffs)); 00061 } 00062 00063 00064 /* 00065 Here's a dumb sample program that interpolates values of y between 00066 frame 0 and frame 30: 00067 */ 00068 00069 #ifdef HM_DEBUG 00070 #include <stdio.h> 00071 00072 main() 00073 { 00074 Cubic coeffs; 00075 GCLReal t0 = 0, t1 = 30; 00076 GCLReal y0 = 1, y1 = 3; 00077 GCLReal dy0 = .2, dy1 = 0; 00078 Int t; 00079 00080 CalcHermiteCoeffs(t0, t1, y0, y1, dy0, dy1, coeffs); 00081 00082 for(t = 0; t < 31; t++) 00083 printf("\ny(%d) = %f", t, EvalCubic(coeffs, t, t0, t1) ); 00084 } 00085 00086 #endif