Spline3.h //////////////////////// //使用Borland C++ Builder编写 //--------------------------------------------------------------------------- #ifndef Spline3H #define Spline3H typedef struct tagReturnRecord { int Counter_X_Y; float *Coord_X_Y; } ReturnRecord; extern "C" __declspec(dllexport) ReturnRecord* WINAPI spMakeSpline(int RealCounter,float *RealPoint,int AddCounter,float Coeff); extern "C" __declspec(dllexport) float* WINAPI spMakeInput(int Counter,char *Para); extern "C" __declspec(dllexport) int WINAPI spGetCounter(ReturnRecord* rr); extern "C" __declspec(dllexport) float WINAPI spGetX(ReturnRecord* rr,int Offset); extern "C" __declspec(dllexport) float WINAPI spGetY(ReturnRecord* rr,int Offset); extern "C" __declspec(dllexport) void WINAPI spRelease(ReturnRecord *rr); //--------------------------------------------------------------------------- #endif Spline3.cpp /////////////////////////// //--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include <math.h> #include <string.h> #include <strstrea.h> #include "Spline3.h"
float* WINAPI spMakeInput(int Counter,char *Para) { float* InputData; int i; istrstream s(Para,strlen(Para)); InputData=new float[Counter]; for(i=0;i<Counter;i++) s>>InputData; return InputData; } int WINAPI spGetCounter(ReturnRecord* rr) { return rr->Counter_X_Y; } float WINAPI spGetX(ReturnRecord* rr,int Offset) { return rr->Coord_X_Y[2*Offset]; } float WINAPI spGetY(ReturnRecord* rr,int Offset) { return rr->Coord_X_Y[2*Offset+1]; } void WINAPI spRelease(ReturnRecord *rr) { delete rr->Coord_X_Y; delete rr; } ReturnRecord* WINAPI spMakeSpline(int RealCounter,float *RealPoint,int AddCounter,float Coeff) { int Counter; int i,j; double *t,*a,*c,*dx,*dy; ReturnRecord* rr; Counter=RealCounter-1; if(Counter<=0) return NULL; rr=new ReturnRecord; if(Counter<3||AddCounter==0) { rr->Counter_X_Y=RealCounter*2; rr->Coord_X_Y=new float[rr->Counter_X_Y]; for(i=0;i<rr->Counter_X_Y;i++) rr->Coord_X_Y=RealPoint; return rr; } t=new double[Counter]; for(i=0;i<Counter;i++) { t=sqrt((RealPoint[2*(i+1) ]-RealPoint[2*i ])*(RealPoint[2*(i+1) ]-RealPoint[2*i ])+ (RealPoint[2*(i+1)+1]-RealPoint[2*i+1])*(RealPoint[2*(i+1)+1]-RealPoint[2*i+1])); if(t<0.005) t=0.005; } a=new double[Counter]; c=new double[Counter]; dx=new double[Counter]; dy=new double[Counter]; for(i=1;i<Counter;i++) { a=t/(t[i-1]+t); c=1.0-a; dx=3*a*(RealPoint[2*i ]-RealPoint[2*(i-1)])/t[i-1]+ 3*c*(RealPoint[2*(i+1)]-RealPoint[2*i ])/t; dy=3*a*(RealPoint[2*i+1 ]-RealPoint[2*(i-1)+1])/t[i-1]+ 3*c*(RealPoint[2*(i+1)+1]-RealPoint[2*i+1 ])/t; } double *rx,*ry,*q; double w; q =new double[Counter]; rx=new double[Counter]; ry=new double[Counter]; q[0] =0.0; // rx[0]=0.7; // ry[0]=0.7; double Lx,Ly,Ld; Lx=RealPoint[2]-RealPoint[0]; Ly=RealPoint[3]-RealPoint[1]; Ld=sqrt(Lx*Lx+Ly*Ly); rx[0]=Lx/Ld; ry[0]=Ly/Ld; for(i=1;i<Counter;i++) { w=2.0-a*q[i-1]; if(abs(w)<0.0001) w=0.0005; q=c/w; rx=(dx-a*rx)/w; ry=(dy-a*ry)/w; } double *vx,*vy; vx=new double[RealCounter]; vy=new double[RealCounter]; // vx[Counter]=0.7; // vy[Counter]=0.7; Lx=RealPoint[RealCounter*2-2]-RealPoint[RealCounter*2-4]; Ly=RealPoint[RealCounter*2-1]-RealPoint[RealCounter*2-3]; Ld=sqrt(Lx*Lx+Ly*Ly); vx[Counter]=Lx/Ld; vy[Counter]=Ly/Ld; for(j=0;j<Counter;j++) { i=Counter-j-1; vx=rx-q*vx[i+1]; vy=ry-q*vy[i+1]; } int TotalCounter=RealCounter+Counter*AddCounter; int ProgramCounter=0; double TempX,TempY; double u; double f1,f2,g1,g2; w=1.0/(AddCounter+1); rr->Counter_X_Y=TotalCounter; rr->Coord_X_Y=new float[TotalCounter*2]; for(i=0;i<Counter;i++) { u=w; rr->Coord_X_Y[2*ProgramCounter ]=RealPoint[2*i ]; rr->Coord_X_Y[2*ProgramCounter+1]=RealPoint[2*i+1]; ProgramCounter++; for(j=0;j<AddCounter;j++) { f1=1.0-3.0*u*u+2.0*u*u*u; f2=3.0*u*u-2.0*u*u*u; g1=u-2.0*u*u+u*u*u; g2=-u*u+u*u*u; TempX=RealPoint[2*i]*f1+RealPoint[2*(i+1)]*f2+vx[i ]*g1*t*Coeff+ vx[i+1]*g2*t*Coeff; TempY=RealPoint[2*i+1]*f1+RealPoint[2*(i+1)+1]*f2+vy[i ]*g1*t*Coeff+ vy[i+1]*g2*t*Coeff; rr->Coord_X_Y[2*ProgramCounter ]=TempX; rr->Coord_X_Y[2*ProgramCounter+1]=TempY; ProgramCounter++; u=u+w; } } rr->Coord_X_Y[2*ProgramCounter ]=RealPoint[2*Counter]; rr->Coord_X_Y[2*ProgramCounter+1]=RealPoint[2*Counter+1]; if(ProgramCounter!=rr->Counter_X_Y-1) { ShowMessage("Error"); } delete[] t; delete[] a; delete[] c; delete[] dx; delete[] dy; delete[] q; delete[] rx; delete[] ry; delete[] vx; delete[] vy; delete[] RealPoint; return rr; } //--------------------------------------------------------------------------- #pragma package(smart_init)
|