/****************/ /* 3d.cpp */ /****************/ // Ohjelma, jolla piirretään sin x:n kuvaaja // /vl-96 #include #include "3d.h" #include "math.h" #include "stdio.h" void cDRect::scan(tFunc f,double x1, double x2,double dx) // Alustetaan suorakaide funktion f minimillä ja maksimilla // Jos dx = 0, jaetaan väli 100 osaan { double fx,x,y1=f(x2),y2=f(x2); if ( dx == 0 ) dx = (x2-x1)/100; for ( x=x1; x x2 ) x2 = p2.px(); if ( p2.py() > y2 ) y2 = p2.py(); p1 = cDPoint(x1,y1); p2 = cDPoint(x2,y2); } //------------------------------------------------------------------------------ int vsize(int &i) // Pakotetaan aina i välille [0,VSIZE-1] { if ( VSIZE <= i ) i = VSIZE-1; if ( i < 0 ) i = 0; return i; } //------------------------------------------------------------------------------ cVector::cVector(double a0, double a1, double a2) { // Alustetaan vektoriksi (a0,a1,a2,1) for (int i=0; i iRect { cTMatrix m; double scale,xs,ys,dxf,dyf,dxt,dyt; // s=scale, f=from, t=to dxf = dRect.Width(); dyf = dRect.Height(); dxt = iRect.right - iRect.left; dyt = iRect.top - iRect.bottom; if ( dxf == 0 || dxt == 0) xs = 1; else xs = dxt/dxf; if ( dyf == 0 || dyt == 0) ys = 1; else ys = dyt/dyf; if ( equal ) { // Jos halutaan x/y = 1 scale = fabs(xs); if ( fabs(ys) < scale ) scale = fabs(ys); xs = fabs(xs)/xs*scale; ys = fabs(ys)/ys*scale; } m[0][0] = xs; m[1][1] = ys; m[0][VSIZE-1] = (iRect.left+iRect.right)/2.0 - dRect.MidX()*xs; m[1][VSIZE-1] = (iRect.top+iRect.bottom)/2.0 - dRect.MidY()*ys; *this = m; } TPoint cTMatrix::operator()(double x,double y, double z) const { // Kutsulla A(x,y) muutetaan reaalimaailman piste näytön pisteeksi cVector vr(x,y,z); // Reaalimaailman vektori cVector vs(*this * vr ); // Näytöllä vastaava vektori return TPoint(int(vs[0]),int(vs[1])); } //------------------------------------------------------------------------------ cRotMatrix::cRotMatrix(int axis,double deg) : cMatrix() // Kierto akselin ympäri (0=x,1=y,2=z) // 0: 1 0 0 1: c 0 -s 2: c -s 0 // 0 c -s 0 1 0 s c 0 // 0 s c s 0 c 0 0 1 { double a = deg*M_PI/180.0, ca=cos(a), sa=sin(a); int j[2]; for (int i=0,ji=0; i<3; i++) if ( i != axis ) j[ji++] = i; r[j[0]][j[0]] = ca; r[j[1]][j[1]] = ca; r[j[0]][j[1]] =-sa; r[j[1]][j[0]] =+sa; } //------------------------------------------------------------------------------ void cCoordinate::XTicks(TDC &dc, const cTMatrix &A, double dx, double dty) const { double x,y1,y2; y1 = origo.py()-dty; y2 = origo.py()+dty; for ( x = origo.px(); x >= dRect.rp1().px(); x -= dx ) { dc.MoveTo(A(x,y1)); dc.LineTo(A(x,y2)); } for ( x = origo.px(); x <= dRect.rp2().px(); x += dx ) { dc.MoveTo(A(x,y1)); dc.LineTo(A(x,y2)); } } void cCoordinate::YTicks(TDC &dc, const cTMatrix &A, double dy, double dtx) const { double y,x1,x2; x1 = origo.px()-dtx; x2 = origo.px()+dtx; for ( y = origo.py(); y >= dRect.rp1().py(); y -= dy ) { dc.MoveTo(A(x1,y)); dc.LineTo(A(x2,y)); } for ( y = origo.py(); y <= dRect.rp2().py(); y+= dy ) { dc.MoveTo(A(x1,y)); dc.LineTo(A(x2,y)); } } void cCoordinate::XLabels(TDC &dc, const cTMatrix &A, double dx, double dty) const { if ( xformat == NULL ) return; double x,y1; char s[50]; dc.SaveDC(); dc.SetTextAlign(TA_CENTER); y1 = origo.py()-dty; for ( x = origo.px()-dx; x >= dRect.rp1().px(); x -= dx ) { sprintf(s,xformat,x); dc.TextOut(A(x,y1),s); } for ( x = origo.px()+dx; x <= dRect.rp2().px(); x += dx ) { sprintf(s,xformat,x); dc.TextOut(A(x,y1),s); } } void cCoordinate::YLabels(TDC &dc, const cTMatrix &A, double dy, double dtx) const { if ( yformat == NULL ) return; double x1,y; char s[50]; TSize size = dc.GetTextExtent("X",1); size.cx = 0; size.cy /= 2; dc.SaveDC(); dc.SetTextAlign(TA_RIGHT); x1 = origo.px()-dtx; for ( y = origo.py()-dy; y >= dRect.rp1().py(); y -= dy ) { sprintf(s,yformat,y); dc.TextOut(A(x1,y)-size,s); } for ( y = origo.py()+dy; y <= dRect.rp2().py(); y += dy ) { sprintf(s,yformat,y); dc.TextOut(A(x1,y)-size,s); } dc.RestoreDC(); } void cCoordinate::Draw(TDC &dc, const cTMatrix &A) const { dc.MoveTo(A(dRect.rp1().px(),origo.py())); dc.LineTo(A(dRect.rp2().px(),origo.py())); XTicks(dc,A,ds.px(),dRect.Height()/100); XTicks(dc,A,db.px(),dRect.Height()/40); XLabels(dc,A,db.px(),dRect.Height()/40); dc.MoveTo(A(origo.px(),dRect.rp1().py())); dc.LineTo(A(origo.px(),dRect.rp2().py())); YTicks(dc,A,ds.px(),dRect.Width()/100); YTicks(dc,A,db.px(),dRect.Width()/40); YLabels(dc,A,db.px(),dRect.Width()/30); } //------------------------------------------------------------------------------ void Draw(TDC &dc, const cTMatrix &A, tFunc f, double x1, double x2, double dx,COLORREF col) //------------------------------------------------------------------------------ { dc.SaveDC(); TPen pen(col); dc.SelectObject(pen); dc.MoveTo(A(x1,f(x1))); for (double x=x1+dx; x