3次样条曲线生成程序

[复制链接]
查看1309 | 回复0 | 2009-4-29 21:12:00 | 显示全部楼层 |阅读模式

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)

您需要登录后才可以回帖 登录 | 注册哦

本版积分规则