#ifndef OKNO_ORAZ_WEKTOR_2D_SP #define OKNO_ORAZ_WEKTOR_2D_SP #include #include using namespace System::Windows::Forms; using namespace System::Drawing; using namespace System; using namespace std; // ============================================================================ struct WK2 { double x, y; public: WK2( void): x(0.), y(0.) {} WK2( double px, double py): x(px), y(py) {} WK2( const WK2 &P): x(P.x), y(P.y){} //--------------------------------------------------------------- inline WK2& operator+=(const WK2 &A){x+=A.x; y+=A.y; return( *this);} inline WK2& operator-=(const WK2 &A){x-=A.x; y-=A.y; return( *this);} inline WK2& operator*=(const WK2 &A){x*=A.x; y*=A.y; return( *this);} inline WK2& operator*=(const double a){x*=a; y*=a; return( *this);} inline WK2& operator=(const WK2 &A){x=A.x; y=A.y; return( *this);} inline WK2 operator+() { return( *this);} inline WK2 operator-() { return( WK2(-x,-y));} }; // ---------------------------------------------------------------------------- inline WK2 operator+(const WK2 &A, const WK2 &B){return(WK2(A.x+B.x, A.y+B.y));} inline WK2 operator-(const WK2 &A, const WK2 &B){return(WK2(A.x-B.x, A.y-B.y));} inline WK2 operator*(const WK2 &A, const WK2 &B){return(WK2(A.x*B.x ,A.y*B.y));} // ---------------------------------------------------------------------------- inline WK2 operator*(const WK2&A, double b){return( WK2( A.x*b, A.y*b));} inline WK2 operator*(double a, const WK2&B){return( WK2( a*B.x, a*B.y));} // ---------------------------------------------------------------------------- inline int operator==(const WK2 &A,const WK2&B){return int(A.x==B.x&&A.y==B.y);} inline int operator!=(const WK2 &A,const WK2&B){return int(A.x!=B.x||A.y!=B.y);} // ---------------------------------------------------------------------------- inline double suma( const WK2 &A) { return(A.x+A.y);} inline double sumakw( const WK2 &A){ return(A.x*A.x +A.y*A.y);} inline double modul( const WK2 &A) { return sqrt( sumakw( A));} inline double faza( const WK2 &A) { return ( atan2(A.y, A.x));} // -------------------------------------------------------------------------- inline double MSk(const WK2&A,const WK2 &B){ return(A.x*B.x+A.y*B.y);} // -------------------------------------------------------------------------- inline WK2 wersor( WK2 &A) { double m=modul(A); if( m!=0) m=1/m; return WK2( m*A); } // ============================================================================ public ref class TOkno { Pen ^pen,^penOsie,^penSiatka; Font ^fontOsie; SolidBrush ^brushFont; SolidBrush ^brushPunky; protected: double Xp,Xk,Yp,Yk; // Zakres rzeczywistego ukladu wsp. Graphics ^grafika; // Graphics ^grafPBox; // Uchwyt do docelowego miejsca odrysowania Graphics ^grafBMP; // Uchwyt do bitmapy Bitmap ^ bitmapa; // bitmapa int Width,Height; private: Color PenKolor, BrushKolor; public: bool klotka; // ustawia taka sama skale zarowno na osi X jak i Y int podzN; // orientacyjna ilosc znaczników na osiach double ziaX,ziaY; // dosuwanie do siatki o zadanym ziarnie double Zakres; // Zakres wyswietlania punktow jednoelementowych double Xs,Ys; // Wspolrzedne miejsca skalowania /dla srodek=2/ int srodek; // Skalowanie wzg. 0-pocz.ukl.wsp; 1-srodka okna; 2-{Xs,Ys} int promien; // promien rysowanych punktow w pikselach TOkno(void); ~TOkno(void); double JednostkaX(void){ return Width/(Xk-Xp); } double JednostkaY(void){ return Height/(Yk-Yp); } void UstawPromienX( double r) { promien=int(r*Height/(Yk-Yp)); } int ex(double x) { return ZakresInt((x-Xp)/(Xk-Xp)*Width); } int ey(double y) { return ZakresInt((Yk-y)/(Yk-Yp)*Height); } double rx(int x) { return Xp+(Xk-Xp)*x/Width; } double ry(int y) { return Yk-(Yk-Yp)*y/Height; } void Kopiuj(void) { grafPBox->DrawImage(bitmapa,0,0);grafika=grafPBox;} double FunZiarna(double z,double r) { if(z>0)r=z*floor((r+.5*z)/z);return r; } int ZakresInt(double w){ int i=int(w),M=int(2E9); return (i>M?M:(i<-M?-M:i));} void Inicjuj (PaintEventArgs ^uchwyt, bool buforAktywny); void Inicjuj (PaintEventArgs ^uchwyt) {Inicjuj(uchwyt,true);} void Czysc ( void); void Skala ( double px, double kx, double py, double ky); void Osie ( void); void Siatka ( void); void Kolor(int penBrush, Color k, bool zast) { if(penBrush==0 && zast==true) { PenKolor=pen->Color; pen->Color=k; } else if(penBrush==0 && zast==false) pen->Color=PenKolor; else if(penBrush==1 && zast==true) { BrushKolor=brushPunky->Color; brushPunky->Color=k; } else if(penBrush==1 && zast==false) brushPunky->Color=BrushKolor; } void Kolor(int i, Color k) {Kolor(i,k,true);} void Kolor(int i) {Kolor(i,Color::Black,false);} void Funkcja ( double (*Fun)(double), double A, double B); void Funkcja ( double (*Fun)(double)) {Funkcja(Fun,Xp,Xk);} void Funkcja ( double (*Fun)(double), Color k) {Kolor(0,k); Funkcja(Fun,Xp,Xk); Kolor(0);} void Funkcja ( double (*Fun)(double), double A, double B, Color k) {Kolor(0,k); Funkcja(Fun,A,B); Kolor(0);} //void Funkcja (double(*Fun)(double),TColor k){ Kolor(k); Funkcja(Fun);} WK2 Przelicznik( int xe, int ye, double *xr, double *yr); void Przelicznik( int *xe, int *ye, double xr, double yr); void SkalaMouse ( int xi, int yi, int Co); bool SkalaMouseDown( MouseEventArgs^ uchwyt); bool SkalaMouseMove( MouseEventArgs^ uchwyt); bool KtoryPunkt ( int *Nr,int xe, int ye, WK2 *P, int roz); void ZmienPunkt ( int xe, int ye, int Co ,WK2 *P, int roz); void ZmienWektor( int xe, int ye, int Co ,WK2 *P, WK2 *W , int roz); bool KtoryPunkt ( int *Nr,int xe, int ye, vector&P) { return KtoryPunkt (Nr,xe,ye,&P[0], P.size()); } void ZmienPunkt ( int xe, int ye, int Co ,vector&P) { ZmienPunkt (xe,ye,Co,&P[0], P.size()); } void ZmienWektor( int xe, int ye, int Co,vector&P,vector&W) { ZmienWektor(xe,ye,Co,&P[0], &W[0], P.size()); } void WstawPunkt (int xe, int ye, vector&P); bool UsunPunkt (int xe, int ye, vector&P); void UsunWstawPunkt(int xe,int ye,vector&P) { if(UsunPunkt(xe,ye,P)==false) WstawPunkt(xe,ye ,P);} void Punkty( WK2 *P, int rozmiar); void Punkty( vector &P){ Punkty(&P[0],P.size());} void Punkty( vector &P, Color k){Kolor(1,k); Punkty(&P[0],P.size());Kolor(0);} void Punkty( WK2 *P, int rozmiar, Color k){Kolor(1,k); Punkty(P,rozmiar);Kolor(0);} void Slupki( double *P, int rozmiar); void Slupki( vector&P){ Slupki(&P[0],P.size());} void Slupki( vector&P,Color k){Kolor(0,k); Slupki(&P[0],P.size());Kolor(0);} void Slupki( double *P, int rozmiar,Color k){Kolor(0,k);Slupki(P,rozmiar);Kolor(0);} void Linie( double *P, int rozmiar); void Linie( vector&P){ Linie(&P[0],P.size());} void Linie( vector&P, Color k){ Kolor(0,k); Linie(&P[0],P.size());Kolor(0);} void Linie( double *P, int rozmiar, Color k){ Kolor(0,k); Linie(P,rozmiar);Kolor(0);} void Lamana( WK2 *P, int rozmiar); void Lamana( vector &P){ Lamana(&P[0],P.size());} void Lamana( vector &P, Color k){Kolor(0,k); Lamana(&P[0],P.size());Kolor(0);} void Lamana( WK2 *P, int rozmiar, Color k) {Kolor(0,k); Lamana(P,rozmiar);Kolor(0);} void LiniePK( WK2 *P, WK2 *K, int rozmiar); void LiniePK( vector&P,vector&K) {unsigned int roz=P.size(); if(roz>K.size())roz=K.size(); LiniePK( &P[0],&K[0],roz);} void LiniePK( vector&P,vector&K,Color k){Kolor(0,k);LiniePK(P,K);Kolor(0);} void LiniePK( WK2 *P, WK2 *K, int roz,Color k){Kolor(0,k);LiniePK(P,K,roz);Kolor(0);} void LiniePW( WK2 *P, WK2 *W, int rozmiar); void LiniePW( vector&P,vector&K) {unsigned int roz=P.size(); if(roz>K.size())roz=K.size(); LiniePW( &P[0],&K[0],roz);} void LiniePW( vector&P,vector&K,Color k){Kolor(0,k);LiniePK(P,K);Kolor(0);} void LiniePW( WK2 *P, WK2 *K, int roz,Color k){Kolor(0,k);LiniePK(P,K,roz);Kolor(0);} void LineTo( WK2 *P, int rozmiar, bool move); void MoveTo( vector&P){ LineTo(&P[0],P.size(),true);} void LineTo( vector&P){ LineTo(&P[0],P.size(),false);} void LineTo( vector&P,Color k){Kolor(0,k); LineTo(P);Kolor(0);} void DopasujSkale( WK2 *T, int rozmiar); }; //--------------------------------------------------------------------------- TOkno::TOkno(void) :Xp(-2),Xk(2),Yp(-2.0),Yk(2.0), ziaX(0),ziaY(0),podzN(6),Zakres(10),promien(4) { pen=gcnew Pen(Color::Blue); penOsie=gcnew Pen(Color::DimGray); penSiatka=gcnew Pen(Color::Silver); fontOsie = gcnew Font( FontFamily::GenericSansSerif, 8, FontStyle::Regular); brushPunky = gcnew SolidBrush(Color::Green); brushFont = gcnew SolidBrush(Color::Black); PenKolor= pen->Color; BrushKolor=brushPunky->Color; } // -------------------------------------------------------------------------- TOkno::~TOkno(void) { LineTo( NULL,0,false); delete penOsie; delete fontOsie; delete brushFont; delete brushPunky; delete bitmapa; // if(bitmapa) bitmapa->Dispose(); } // -------------------------------------------------------------------------- void TOkno::Inicjuj(PaintEventArgs ^uchwyt, bool buforAktywny) { static bool last=false; int WidthPop=Width,HeightPop=Height; Width=uchwyt->ClipRectangle.Width; Height=uchwyt->ClipRectangle.Height; bool zmroz=(Width!=WidthPop||Height!=HeightPop); grafPBox=uchwyt->Graphics; if(buforAktywny==true) grafika=grafPBox; else grafika=grafBMP; if(klotka==true && last!=klotka) Skala(Xp,Xk,Yp,Yk); last=klotka; if(!bitmapa || zmroz) { if(klotka==true && last==klotka) Skala(Xp,Xk,Yp,Yk); if(bitmapa) { delete bitmapa; delete grafBMP; } bitmapa=gcnew Bitmap(Width, Height); //,Imaging::PixelFormat::Format24bppRgb); grafBMP=Graphics::FromImage( bitmapa); grafBMP->Clear(Color::White); } } //--------------------------------------------------------------------------- void TOkno::Czysc( void) { grafika->Clear(Color::White); } //--------------------------------------------------------------------------- void TOkno::Skala(double px,double kx,double py,double ky) { if( kx>px) { Xp=px;Xk=kx; } if( ky>py) { Yp=py;Yk=ky; } if( klotka==true) { double sX=0.5*(Xk+Xp),sY=0.5*(Yk+Yp),pole=(Xk-Xp)*(Yk-Yp); double sz05=0.5*sqrt(pole*Width/Height); double wy05=0.5*sqrt(pole*Height/Width); Xp= sX-sz05; Yp= sY-wy05; Xk= sX+sz05; Yk= sY+wy05; } } //--------------------------------------------------------------------------- void Podzial(double P,double K, int Na, double *Pocz, double *Jedn, int *Ilosc) { int t[10]={0,1,2,2,2,5,5,5,5,5}; if(Na!=0) { double Rzad=log10((K-P)/Na); int czy125=t[int(pow(10.0,Rzad-floor(Rzad)))]; *Jedn= czy125*pow( 10.0,floor(Rzad)); } *Pocz=ceil(P/ *Jedn)* *Jedn; *Ilosc=int(floor(K/ *Jedn)-ceil(P/ *Jedn)+1); if(int(ceil(P/(*Jedn)))%2!=0) { (*Pocz)-=*Jedn; (*Ilosc)++; } } //--------------------------------------------------------------------------- void TOkno::Osie( void) { double Akt,PoczX,JednX,PoczY,JednY; int x0d=ex(0.0),y0d=ey(0.0),wi,Nx,Ny; int x0=(x0d>Width?Width-8:(x0d<0?8:x0d)); int y0=(y0d>Height?Height-8:(y0d<0?8:y0d)); int dx0=5; if(x0>Width-60) dx0=-35; int dy0=-15; if(y0<10) dy0=5; penOsie->EndCap=Drawing2D::LineCap::ArrowAnchor; grafika->DrawLine(penOsie, 0, y0, Width, y0); grafika->DrawLine(penOsie, x0, Height, x0, 0); penOsie->EndCap=Drawing2D::LineCap::NoAnchor; Podzial(Xp,Xk,podzN,&PoczX,&JednX,&Nx); Podzial(Yp,Yk,podzN,&PoczY,&JednY,&Ny); if(klotka==true) if(JednXDrawLine(penOsie, wi, y0-4+2*(i%2),wi, y0+4-2*(i%2)); if(i%2==1) continue; Akt=floor(Akt/JednX+0.5)*JednX; grafika->DrawString(Akt.ToString("e2"),fontOsie,brushFont,1.f*wi-10,1.f*y0+dy0); //grafika->DrawString( } for( int i=0; iDrawLine(penOsie, x0-4+2*(i%2), wi, x0+4-2*(i%2), wi); if(i%2==1) continue; Akt=floor(Akt/JednY+0.5)*JednY; grafika->DrawString(Akt.ToString("e2"),fontOsie,brushFont,1.f*x0+dx0, 1.f*wi-5); } } //--------------------------------------------------------------------------- void TOkno::Funkcja( double (*fun)(double), double A, double B) { if(Xp>A) A=Xp; if(XkDrawLine(pen,i-1,yp,i,y); } } //--------------------------------------------------------------------------- void TOkno::Siatka(void) { int Nx,Ny; double PoczX,JednX,PoczY,JednY; Podzial(Xp,Xk,podzN,&PoczX,&JednX,&Nx); Podzial(Yp,Yk,podzN,&PoczY,&JednY,&Ny); if(klotka==true) if(JednXDashStyle = Drawing2D::DashStyle::Dash; for( int i=1; iDrawLine(penSiatka, ex(PoczX+i*JednX), 0, ex(PoczX+i*JednX), Height); for( int i=1; iDrawLine(penSiatka, 0, ey(PoczY+i*JednY), Width, ey(PoczY+i*JednY)); penSiatka->DashStyle = Drawing2D::DashStyle::Solid; for( int i=0; iDrawLine(penSiatka, ex(PoczX+i*JednX), 0, ex(PoczX+i*JednX), Height); for( int i=0; iDrawLine(penSiatka, 0, ey(PoczY+i*JednY), Width, ey(PoczY+i*JednY)); } //--------------------------------------------------------------------------- WK2 TOkno::Przelicznik( int xe, int ye, double *xr, double *yr) { WK2 Punkt=WK2(rx(xe),ry(ye)); if(xr) *xr=Punkt.x; if(yr) *yr=Punkt.y; return Punkt; } //--------------------------------------------------------------------------- void TOkno::Przelicznik( int *xe, int *ye, double xr, double yr) { int wx=ex(xr), wy=ey(yr); if(xe) *xe=wx; if(ye) *ye=wy; } //--------------------------------------------------------------------------- void TOkno::SkalaMouse( int xi, int yi, int Co) { static int xilast=0,yilast=0; double dx=rx(xi)-rx(xilast); double dy=ry(yi)-ry(yilast); if(Co==1) Skala(Xp-dx,Xk-dx,Yp-dy,Yk-dy); else if(Co==2) { double Sx=pow(1.0-5.0*fabs(dx/(Xk-Xp)),(dx<0?-1.0:1.0)); double Sy=pow(1.0-5.0*fabs(dy/(Yk-Yp)),(dy<0?-1.0:1.0)); double tOx=0.5*(Xp+Xk),tOy=0.5*(Yp+Yk); if(srodek==0) {tOx=0.0; tOy=0.0;} else if(srodek==2) {tOx=Xs; tOy=Ys; } Skala(tOx+(Xp-tOx)*Sx, tOx+(Xk-tOx)*Sx, tOy+(Yp-tOy)*Sy,tOy+(Yk-tOy)*Sy); } xilast=xi; yilast=yi; } //--------------------------------------------------------------------------- bool TOkno::SkalaMouseDown( MouseEventArgs^ e) { SkalaMouse ( e->X,e->Y, 0); return true; //KeyState } //--------------------------------------------------------------------------- bool TOkno::SkalaMouseMove( MouseEventArgs^ e) { int a=0; if(e->Button==MouseButtons::Left) a=2; else if(e->Button==MouseButtons::Right) a=1; else return false; SkalaMouse( e->X,e->Y, a); return true; } //--------------------------------------------------------------------------- bool TOkno::KtoryPunkt( int *Nr, int xe, int ye, WK2 *P, int roz) { int Szukany=-1, r=3; if(r&P) { P.push_back( WK2(rx(xe),ry(ye))); } //--------------------------------------------------------------------------- bool TOkno::UsunPunkt(int xe, int ye , vector&P) { int Nr; bool wyn=KtoryPunkt(&Nr,xe,ye,P); if(wyn==true) P.erase(P.begin()+Nr); return wyn; } //--------------------------------------------------------------------------- void TOkno::Punkty( WK2 *P, int rozmiar) { int srednica=2*promien; for(int i=0,x,y; iFillEllipse(brushPunky,x-promien,y-promien,srednica,srednica); } } //--------------------------------------------------------------------------- void TOkno::Slupki( double *P, int rozmiar) { if(rozmiar<=0) return; double dx=Zakres/rozmiar; for(int i=0,xp,xk=ex(0),y0=ey(0),y; iDrawLine(pen,xp,y0,xp,y); grafika->DrawLine(pen,xp,y,xk,y); grafika->DrawLine(pen,xk,y,xk,y0); } } //--------------------------------------------------------------------------- void TOkno::Linie( double *P, int rozmiar) { if(rozmiar<=1) return; double dx=Zakres/(rozmiar-1); for(int i=1,xp,yp,x=ex(0),y=ey(P[0]); iDrawLine(pen,xp,yp,x,y); } } //--------------------------------------------------------------------------- void TOkno::Lamana( WK2 *P, int rozmiar) { if(rozmiar<=1) return; for(int i=1,xp,yp,x=ex(P[0].x),y=ey(P[0].y); iDrawLine(pen,xp,yp,x,y); } } //--------------------------------------------------------------------------- void TOkno::LiniePK( WK2 *P, WK2 *K, int rozmiar) { for(int i=0,xp,yp,xk,yk; iDrawLine(pen,xp, yp, xk, yk); } } //--------------------------------------------------------------------------- void TOkno::LiniePW( WK2 *P, WK2 *W, int rozmiar) { for(int i=0,xp,yp,xk,yk; iDrawLine(pen,xp, yp, xk, yk); } } //--------------------------------------------------------------------------- void TOkno::LineTo( WK2 *P, int rozmiar, bool move) { static int Npoprz=0; static int *Kx=NULL,*Ky=NULL; int *Px=Kx,*Py=Ky; if(rozmiar>0) { Kx=new int[rozmiar]; Ky=new int[rozmiar]; for(int i=0; iDrawLine(pen, Px[i],Py[i],Kx[i],Ky[i]); } if(Npoprz>0) { delete[] Px; delete[] Py; } Npoprz=rozmiar; } //--------------------------------------------------------------------------- bool ZnajdzMinMax( WK2 *P, int rozmiar, WK2 *pMin, WK2 *pMax) { if(rozmiar<=0) return false; WK2 Min=P[0],Max=P[0]; for( int i=1; iP[i].x) Min.x=P[i].x; if(Min.y>P[i].y) Min.y=P[i].y; if(Max.x0 && D.y>0) { P -= 0.1*D; K += 0.1*D; Skala( P.x, K.x, P.y, K.y); } } } //--------------------------------------------------------------------------- void FFT(int dir,long pot,double *x,double *y) { long n,i,i1,j,k,n05l,l,l1,l2; double c1,c2,tx,ty,t1,t2,u1,u2,z; n=1<>1; j=0; for (j=0,i=0;i>=1; } j += k; } c1=-1.0; c2=0.0; l2=1; for(l=0;l