123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- #include "BSpline.h"
- USING_NS_BF;
- static void compute_intervals(int *u, int n, int t) // figure out the knots
- {
- int j;
- for (j=0; j<=n+t; j++)
- {
- if (j<t)
- u[j]=0;
- else
- if ((t<=j) && (j<=n))
- u[j]=j-t+1;
- else
- if (j>n)
- u[j]=n-t+2; // if n-t=-2 then we're screwed, everything goes to 0
- }
- }
- BSpline2D::BSpline2D()
- {
- mUVals = NULL;
- }
- BSpline2D::~BSpline2D()
- {
- delete mUVals;
- }
- void BSpline2D::AddPt(float x, float y)
- {
- delete mUVals;
- mUVals = NULL;
- PointF pt;
- pt.x = x;
- pt.y = y;
- mInputPoints.push_back(pt);
- }
- void BSpline2D::Calculate()
- {
- int n = (int) mInputPoints.size();
- int t = 1;
- PointF* control = &mInputPoints[0];
-
- mUVals=new int[n+t+1];
- compute_intervals(mUVals, n, t);
- //increment=(float) (n-t+2)/(num_output-1); // how much parameter goes up each time
- //interval=0;
- /*for (output_index=0; output_index<num_output-1; output_index++)
- {
- compute_point(u, n, t, interval, control, &calcxyz);
- output[output_index].x = calcxyz.x;
- output[output_index].y = calcxyz.y;
- output[output_index].z = calcxyz.z;
- interval=interval+increment; // increment our parameter
- }
- output[num_output-1].x=control[n].x; // put in the last point
- output[num_output-1].y=control[n].y;
- output[num_output-1].z=control[n].z;
- delete u;*/
- }
- static float blend(int k, int t, int *u, float v) // calculate the blending value
- {
- float value;
- if (t==1) // base case for the recursion
- {
- if ((u[k]<=v) && (v<u[k+1]))
- value=1;
- else
- value=0;
- }
- else
- {
- if ((u[k+t-1]==u[k]) && (u[k+t]==u[k+1])) // check for divide by zero
- value = 0;
- else
- if (u[k+t-1]==u[k]) // if a term's denominator is zero,use just the other
- value = (u[k+t] - v) / (u[k+t] - u[k+1]) * blend(k+1, t-1, u, v);
- else
- if (u[k+t]==u[k+1])
- value = (v - u[k]) / (u[k+t-1] - u[k]) * blend(k, t-1, u, v);
- else
- value = (v - u[k]) / (u[k+t-1] - u[k]) * blend(k, t-1, u, v) +
- (u[k+t] - v) / (u[k+t] - u[k+1]) * blend(k+1, t-1, u, v);
- }
- return value;
- }
- /*void compute_point(int *u, int n, int t, float v, point *control,
- point *output)*/
- void BSpline2D::Evaluate(float pct, float* x, float* y)
- {
- if (mUVals == NULL)
- Calculate();
- int k;
- float temp;
- int n = (int) mInputPoints.size();
- int t = (int)mInputPoints.size() - 3; // ????
- t = 1;
- PointF* control = &mInputPoints[0];
- // initialize the variables that will hold our outputted point
- float oX = 0;
- float oY = 0;
- for (k=0; k<=n; k++)
- {
- temp = blend(t,t,mUVals,pct); // same blend is used for each dimension coordinate
- oX = oX + (control[k]).x * temp;
- oY = oY + (control[k]).y * temp;
- }
- *x = oX;
- *y = oY;
- }
|