Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
21
Добавлен:
16.04.2013
Размер:
6.77 Кб
Скачать
// Spline.cpp: implementation of the CSpline class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Spline_3d.h"
#include "Spline.h"
#include <math.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

double CSpline::Fun(double x, double y, int FunNum)
{
	switch(FunNum){
	case 1:return 40*sin(pi/10000*sqrt(pow(x,2)*pow(y,2)));
    case 2:return 40*sin(pi/100*x)*cos(pi/150*y);
	case 3:return y*sin(pi/100*x);
    case 4:return sqrt(pow(x,2)+pow(y,2));
    case 5:return 50*pow(sin(pi/100*sqrt(pow(x,2)+pow(y,2))),2);
    default: return 0;
	}
}

CSpline::CSpline(int FunNum, int SNum, CPoint Center)
{
   XYZCenter = Center;
   L = 100; R = 50;
   Point0 = PointCoord();
   PointX = PointCoord(0, L, 0);
   PointY = PointCoord(L, 0, 0);
   PointZ = PointCoord(0, 0, L);
   
   // Setka
   SetkaNum = SNum; MaxXY = 400; 
   Setka = new PointCoord[(SetkaNum+3)*(SetkaNum+3)];
   Shag = MaxXY/SetkaNum;
   for(int i=0; i<SetkaNum+3;i++)
	  for(int j=0; j<SetkaNum+3;j++)
	  {Setka[i*(SetkaNum+1) + j].x = Shag*i - MaxXY/2;
	   Setka[i*(SetkaNum+1) + j].y = Shag*j - MaxXY/2;
	   Setka[i*(SetkaNum+1) + j].z = Fun(Setka[i*(SetkaNum+1) + j].x, Setka[i*(SetkaNum+1) + j].y, FunNum); 
	  }
   // Spline
   N = 5;
   SplineNum = SetkaNum*N;
   Point = new PointCoord[SplineNum*SplineNum];
   PointCoord r, r0;
   double tx, ty, dtx = 1.0/N, dty = 1.0/N;
  
   for(int k=0; k<SetkaNum;k++)
   for(int l=0; l<N; l++)
   {tx = dtx*l;  
	for(int j=0; j<SetkaNum; j++)
    for(int i=0; i<N; i++)	 
	{ ty = dty*i;
	  BSpline3DCom(Setka, k, tx, j, ty, r);
	  Point[(k*N+l)*SplineNum+j*N+i] = r; 
	}  
   }
  // Line
   Line1 = new PointCoord[SplineNum+3];
   Line2 = new PointCoord[SplineNum+3];
   Line3 = new PointCoord[SplineNum+3];
   double u, v1, v2, v3; 
   double y1, y2, y3, ty1, ty2, ty3;
   for(k=0; k<SetkaNum;k++)
   for(int l=0; l<N; l++)
   {tx = dtx*l;  
	u = double((k*N+l))/double(SplineNum-2*N);
	v1 = u + 0.4*sin(2*pi*u), v2 = u + 0.5*sin(2*pi*u), v3 = u + 0.6*sin(2*pi*u); 
   	y1 = (SplineNum-2*N)*v1, y2 = (SplineNum-2*N)*v2, y3 = (SplineNum-2*N)*v3;
	int j1=int(y1/N), j2=int(y2/N), j3=int(y3/N);
	ty1 = dty*fmod(y1,N), ty2 = dty*fmod(y2,N), ty3 = dty*fmod(y3,N);
	BSpline3DCom(Setka, k, tx, j1, ty1, r);	Line1[k*N+l] = r; 
	BSpline3DCom(Setka, k, tx, j2, ty2, r); Line2[k*N+l] = r; 
	BSpline3DCom(Setka, k, tx, j3, ty3, r);	Line3[k*N+l] = r; 
   }
}

CSpline::~CSpline()
{
  if(Setka) delete Setka;
  if(Point) delete Point;
  if(Line1) delete Line1;
  if(Line2) delete Line2;
  if(Line3) delete Line3;
}

void CSpline::DrawXYZ(CPaintDC &dc, double a, double b, int d, CPoint C)
{  A = a; B = b; D = d;
   XYZCenter = C;
   
   COLORREF Col = RGB(0, 150, 0);
   CPen Pen(PS_SOLID,2,Col);
   CPen *pPen = dc.SelectObject(&Pen);
   dc.SelectObject(Pen);
   CPoint Px = Transform3Dto2D(PointX);
   CPoint Py = Transform3Dto2D(PointY);
   CPoint Pz = Transform3Dto2D(PointZ);

   dc.MoveTo(XYZCenter);
   dc.LineTo(Px);
   dc.TextOut(Px.x, Px.y, "x");

   dc.MoveTo(XYZCenter);
   dc.LineTo(Py);
   dc.TextOut(Py.x, Py.y, "y");
   
   dc.MoveTo(XYZCenter);
   dc.LineTo(Pz);
   dc.TextOut(Pz.x, Pz.y, "z");

   dc.SelectObject(pPen);
}

void CSpline::DrawSpline(CPaintDC &dc, double a, double b, int d)
{   A = a; B = b; D = d; 

 COLORREF Col = RGB(250, 100, 0);
 CPen Pen(PS_SOLID,1,Col);
 CPen *pPen = dc.SelectObject(&Pen);
 dc.SelectObject(Pen);

  for(int i=0; i<SplineNum-2*N;i++)
	for(int j=0; j<SplineNum-2*N;j++)
	  {CPoint P = Transform3Dto2D(Point[i*SplineNum + j]);
	   dc.MoveTo(P);
       dc.LineTo(Transform3Dto2D(Point[(i+1)*SplineNum + j]));
	   dc.MoveTo(P);
       dc.LineTo(Transform3Dto2D(Point[i*SplineNum + j+1]));  
	}

   for(i=0; i<SplineNum-2*N;i++)
	  {dc.MoveTo(Transform3Dto2D(Point[i*SplineNum+SplineNum-2*N]));
       dc.LineTo(Transform3Dto2D(Point[(i+1)*SplineNum+SplineNum-2*N]));
	  }
    
	for(i=0; i<SplineNum-2*N;i++)
	  {dc.MoveTo(Transform3Dto2D(Point[(SplineNum-2*N)*SplineNum+i]));
       dc.LineTo(Transform3Dto2D(Point[(SplineNum-2*N)*SplineNum+i+1]));
	  }
 	dc.SelectObject(pPen);
  }

CPoint CSpline::Transform3Dto2D(PointCoord Point)
{ CPoint P;
  P.x = XYZCenter.x + int(D/(50+R)*(-Point.x*sin(A) + Point.y*cos(A)));
  P.y = XYZCenter.y + int(D/(50+R)*(-Point.x*cos(A)*cos(B) - Point.y*sin(A)*cos(B) + Point.z*sin(B)));
  return P;
}

void CSpline::BSpline3DCom(PointCoord *Setka, int i, double tx, int j, double ty, PointCoord &r)
{ double t2x = pow(tx, 2), t3x = pow(tx, 3);
  double t2y = pow(ty, 2), t3y = pow(ty, 3);  
  double bx[4], by[4];
  bx[0] = (1-3*tx+3*t2x-t3x)/6,    by[0] = (1-3*ty+3*t2y-t3y)/6;
  bx[1] = (4-6*t2x+3*t3x)/6,       by[1] = (4-6*t2y+3*t3y)/6;
  bx[2] = (1+3*tx+3*t2x-3*t3x)/6,  by[2] = (1+3*ty+3*t2y-3*t3y)/6;
  bx[3] = t3x/6,                   by[3] = t3y/6; 
  r = PointCoord();
  for(int k=0;k<4;k++)
   for(int l=0;l<4;l++)
   {r.x += Setka[(i+k)*(SetkaNum+1)+j+l].x*bx[k]*by[l];
    r.y += Setka[(i+k)*(SetkaNum+1)+j+l].y*bx[k]*by[l];
	r.z += Setka[(i+k)*(SetkaNum+1)+j+l].z*bx[k]*by[l];
   }
}

void CSpline::DrawSetka(CPaintDC &dc, double a, double b, int d)
{ A = a; B = b; D = d; 
  for(int i=1; i<SetkaNum-1;i++)
	for(int j=1; j<SetkaNum-1;j++)
	  {CPoint P = Transform3Dto2D(Setka[i*(SetkaNum+1)+j]);
	   dc.MoveTo(P);
       dc.LineTo(Transform3Dto2D(Setka[(i+1)*(SetkaNum+1)+j]));
	   dc.MoveTo(P);
       dc.LineTo(Transform3Dto2D(Setka[i*(SetkaNum+1)+j+1]));  
	}

  for(i=1; i<SetkaNum-1;i++)
	  {dc.MoveTo(Transform3Dto2D(Setka[i*(SetkaNum+1)+SetkaNum-1]));
       dc.LineTo(Transform3Dto2D(Setka[(i+1)*(SetkaNum+1)+SetkaNum-1]));
	  }
    
  for(i=1; i<SetkaNum-1;i++)
	  {dc.MoveTo(Transform3Dto2D(Setka[(SetkaNum-1)*(SetkaNum+1)+i]));
       dc.LineTo(Transform3Dto2D(Setka[(SetkaNum-1)*(SetkaNum+1)+i+1]));
	  }
}

void CSpline::DrawLine(CPaintDC &dc, double a, double b, int d)
{  A = a; B = b; D = d; 
 
  COLORREF Col = RGB(250, 0, 0);
  CPen Pen(PS_SOLID,1,Col);
  CPen *pPen = dc.SelectObject(&Pen);
  dc.SelectObject(Pen);
  
  for(int i=0; i<SplineNum-2*N;i++)
	  {dc.MoveTo(Transform3Dto2D(Line1[i]));
       dc.LineTo(Transform3Dto2D(Line1[i+1]));
	   dc.MoveTo(Transform3Dto2D(Line2[i]));
       dc.LineTo(Transform3Dto2D(Line2[i+1]));
	   dc.MoveTo(Transform3Dto2D(Line3[i]));
       dc.LineTo(Transform3Dto2D(Line3[i+1]));
	  }
  
  dc.SelectObject(pPen);
}
Соседние файлы в папке Spline_3d