Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа №44 / 0000
.CPP //Rot optimization
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <graphics.h>
#include <math.h>
//#define PutPnt(h,v,c) asm MOV ah,0xC; asm { MOV al,c; MOV cx,h; MOV dx,v; INT 0x10 };
#define PutPnt(h,v,c) putpixel(h,v,c);
#define defC 1
#define maxZ 400
//-----------------------------------------------------------------------------------
void SetModeA (char ); //;l;
char GetModeA (void);
//void PutPnt (int , int , char );
inline void LineM (int, int , int , int, double, double, char);
void MapD(char IC);
void XPut(int ,int , int , char ); //!!!
//------------------------------------------------------------------------------------
class Dot
{
public:
long double X;
long double Y;
long double Z;
int sX;
int sY;
int Check (); //+ //'0'-Dot out of range , else '1'
inline void ReCalc(); //+
Dot (long double X=0,long double Y=0,long double Z=0);//+
};
class Obj
{
unsigned V : 1; //Visible
unsigned UTD : 1; //Up to date
public:
void Show () {V=1;}; //+
void Hide () {V=0;}; //+
void UTDS () {UTD=1;}; //+
void UTDR () {UTD=0;}; //+
virtual int RotateOne (long double,long double){return 0;}; //+
virtual void DrawOne (){}; //+
virtual int MoveOne (int,int,int){return 0;}; //+
virtual void HideOne (){}; //+
Obj () ; //+ glob
};
class Link
{
friend class List;
unsigned int Base : 1; //Start of list
Obj *One;
Link *NextPtr;
public:
Link (Obj*, Link *); //+
~Link(); //+
};
class List
{
Link *Cur;
public:
inline int NextS(); //+ //Donot modify Base parameter
//'0'-Again at the beginning; '-1'-Empty '1'-other case
int Add(Obj *); //+
inline int Next(); //+ //'0'-Empty;'1'-Other case
int Del(); //+ //'0'-Already empty or result empty
void Clear (); //+
Obj *Get(); //+
void ReDrawAll (); //+
inline void Hide(){Cur->One->HideOne();};
inline void RotateOne (long double a,long double b) {Cur->One->RotateOne(a,b);};
// int MoveAll(int,int,int); //'0'-Impossible(No action) '1'-OK
inline void MoveOne(int x,int y,int z){Cur->One->MoveOne(x,y,z);}; // +
List (); //+
List (Obj*); //+
~List(); //+
};
class Match : public Obj
{
public:
Dot A;
Dot B;
int RotateOne (long double,long double,Dot*); //+
void DrawOne (); //+
int MoveOne (int,int,int,int); //+
void HideOne (); //+
Match (); //+
Match(int,int,int,int,int,int);
};
class OctEdr : public Obj
{
Match *A[12];
public:
int RotateOne (long double,long double); //
void DrawOne (); //+
int MoveOne (int,int,int); //+
void HideOne (); //+
OctEdr (int,int,int); //+
~OctEdr ();
};
void AddCube (List *, int,int,int);
//-----------------------------------------------------------------------------------
const int R=900, XON=0;
const Dot COE (320,175,175); //Center of environment
//------------------------------------------------------------------------------------
inline void Line3D (Dot *A,Dot *B)
{
// LineM (A->sX,A->sY,B->sX,B->sY,A->Z,B->Z,1);
};
//------------------------------------------------------------------------------------
Dot::Dot (long double aX,long double aY,long double aZ)
{
X=aX;
Y=aY;
Z=aZ;
ReCalc();
};
int Dot::Check()
{
if ((((X-COE.X)*(X-COE.X)+(Y-COE.Y)*(Y-COE.Y)+(Z-COE.Z)*(Z-COE.Z))<=R*R)) //Optimize Later
return 1;
else
return 0;
};
void Dot::ReCalc()
{
sX=X+(Z*(320-X))/R;
sY=Y+((175-Y)*Z)/R;
};
Obj::Obj ()
{
V=1;
UTD=0;
};
Link::Link (Obj *a, Link *e)
{
One=a;
if (e)
{
e->Base=0;
NextPtr=e->NextPtr;
e->NextPtr=this;
}
else
NextPtr=this;
Base=1;
};
Link::~Link ()
{
delete One;
};
List::List ()
{
Cur=0;
};
List::List(Obj *t)
{
Cur=new Link(t,0);
};
int List::Add (Obj *t)
{
Cur=new Link(t,Cur);
return 1;
};
int List::NextS()
{
if (!Cur)
return -1;
Cur=Cur->NextPtr;
if (Cur->Base)
return 0;
else
return 1;
};
int List::Next()
{
if (!Cur)
return 0;
Cur->Base=0;
Cur=Cur->NextPtr;
Cur->Base=1;
return 1;
};
int List::Del()
{
Link *t;
if (!Cur)
return 0;
if (Cur==Cur->NextPtr)
{
delete Cur;
Cur=0;
return 0;
}
for (t=Cur->NextPtr; t->NextPtr!=Cur;t=t->NextPtr);
t->NextPtr=Cur->NextPtr;
delete Cur;
Cur=t;
Cur->Base=1;
return 1;
};
void List::Clear()
{
while (Del());
};
Obj *List::Get()
{
return Cur->One;
};
Match::Match()
{
A=COE;
B=COE;
B.Z+=100;
A.ReCalc();
B.ReCalc();
};
Match::Match(int x1,int y1,int z1,int x2,int y2,int z2)
{
A.X=x1;
A.Y=y1;
A.Z=z1;
B.X=x2;
B.Y=y2;
B.Z=z2;
A.ReCalc();
B.ReCalc();
};
int Match::MoveOne (int x,int y, int z,int E)
{
Dot *A1= new Dot;
Dot *B1= new Dot;
*A1=A;
*B1=B;
A1->X+=x;
A1->Y+=y;
A1->Z+=z;
B1->X+=x;
B1->Y+=y;
B1->Z+=z;
/*if (E)
if (!(A1->Check()&&B1->Check()))//Check it ???
return 0;*/
if (E) HideOne();
A=*A1;
B=*B1;
A.ReCalc();
B.ReCalc();
delete A1;
delete B1;
DrawOne();
return 1;
};
void Match::DrawOne()
{
// Line3D(&A,&B);
LineM(A.sX,A.sY,B.sX,B.sY,A.Z,B.Z,1);
};
void Match::HideOne()
{
LineM(A.sX,A.sY,B.sX,B.sY,A.Z,B.Z,0); //'0'-Black
};
int Match::RotateOne(long double a,long double b,Dot *C1) //End
{
long double s,c;// sa,ca,sb,cb ;
Dot *A1=new Dot;
Dot *B1=new Dot; //C1 -Center of rotation
B.X-=C1->X;
B.Y-=C1->Y;
B.Z-=C1->Z;
A.X-=C1->X;
A.Y-=C1->Y;
A.Z-=C1->Z;
if (a)
{
s=sinl(a);
c=cosl(a);
B1->X=B.X*c-B.Z*s+C1->X;
B1->Z=B.X*s+B.Z*c+C1->Z;;
B1->Y=B.Y+C1->Y;
A1->X=A.X*c-A.Z*s+C1->X;
A1->Z=A.X*s+A.Z*c+C1->Z;;
A1->Y=A.Y+C1->Y;
}
else if (b)
{
s=sinl(b);
c=cosl(b);
B1->Y=B.Y*c-B.X*s+C1->Y;
B1->X=B.Y*s+B.X*c+C1->X;
B1->Z=B.Z+C1->Z;
A1->Y=A.Y*c-A.X*s+C1->Y;
A1->X=A.Y*s+A.X*c+C1->X;
A1->Z=A.Z+C1->Z;
};
/*
sa=sinl(a);
ca=cosl(a);
sb=sinl(b);
cb=cosl(b);
B1->X=B.X*ca*sb+B.Y*cb-B.Z*sa*sb+C1->X;
B1->Y=B.X*ca*cb-B.Y*sb-B.Z*sa*cb+C1->Y;
B1->Z=B.X*sa+B.Z*ca+C1->Z;
A1->X=A.X*ca*sb+A.Y*cb-A.Z*sa*sb+C1->X;
A1->Y=A.X*ca*cb-A.Y*sb-A.Z*sa*cb+C1->Y;
A1->Z=A.X*sa+A.Z*ca+C1->Z;
*//*
B.X=B1->X+C1->X;
B.Y=B1->Y+C1->Y;
B.Z=B1->Z+C1->Z;
A.X=A1->X+C1->X;
A.Y=A1->Y+C1->Y;
A.Z=A1->Z+C1->Z;
*/
A=*A1;
B=*B1;
B.ReCalc();
A.ReCalc();
delete A1;
delete B1;
return 1;
};
void List::ReDrawAll()
{
// clearviewport();
if (!Cur)
return;
do
Cur->One->HideOne();
while (NextS());
MapD(7);
do
Cur->One->DrawOne();
while (NextS());
};
List::~List()
{
Clear();
};
OctEdr::OctEdr(int a=0,int b=0,int c=0)
{
a+=270;
b+=125;
A[1]=new Match(0+a,100+b,0+c,0+a,100+b,100+c);
A[2]=new Match(0+a,0+b,0+c,0+a,0+b,100+c);
A[3]=new Match(100+a,100+b,0+c,100+a,100+b,100+c);
A[4]=new Match(100+a,0+b,0+c,100+a,0+b,100+c);
A[5]=new Match(0+a,0+b,0+c,100+a,0+b,0+c);
A[6]=new Match(0+a,0+b,100+c,100+a,0+b,100+c);
A[7]=new Match(0+a,100+b,0+c,100+a,100+b,0+c);
A[8]=new Match(0+a,100+b,100+c,100+a,100+b,100+c);
A[9]=new Match(100+a,100+b,0+c,100+a,0+b,0+c);
A[10]=new Match(100+a,100+b,100+c,100+a,0+b,100+c);
A[11]=new Match(0+a,100+b,0+c,0+a,0+b,0+c);
A[0]=new Match(0+a,100+b,100+c,0+a,0+b,100+c);
};
OctEdr::~OctEdr()
{
for(int i=0;i<12;i++)
delete A[i];
};
void OctEdr::DrawOne()
{
for(int i=0;i<12;i++)
A[i]->DrawOne();
};
void OctEdr::HideOne()
{
for(int i=0;i<12;i++)
A[i]->HideOne();
};
int OctEdr::MoveOne(int x,int y,int z)
{
HideOne();
for(int i=0;i<12;i++)
A[i]->MoveOne(x,y,z,0);
return 1;
DrawOne();
};
int OctEdr::RotateOne (long double a,long double b)
{
HideOne();
Dot C(0,0,0);
int i;
for( i=0;i<12;i++)
{
C.X+=A[i]->A.X+A[i]->B.X;
C.Y+=A[i]->A.Y+A[i]->B.Y;
C.Z+=A[i]->A.Z+A[i]->B.Z;
}
C.X/=24;
C.Y/=24;
C.Z/=24;
C.ReCalc();
// XPut (C.sX,C.sY, 3, 3) ; //!!!
// C=COE; C.Z=50;
for(i=0;i<12;i++)
{
A[i]->RotateOne(a,b,&C);
A[i]->DrawOne();
}
//XPut (A[11]->A.sX,A[11]->A.sY, 3, 4) ;
return 1;
};
//---------------------------------------------------------------------------------------------
void main (void)
{
int gd=DETECT,gm=0;
gd=installuserdriver("svga256",NULL);
gm=2;
initgraph(&gd,&gm,"c:\\progra~1 \\bgi");
setcolor(2);
outtextxy(320,200,"Loading");
for(int i=0;i<255;i++)
{
setrgbpalette(255-i,i/4,i/4,i/4);
putpixel(320 - 255/2+i,200,i);
};
cleardevice();
// char i=GetModeA();
// int inter=0;
// SetModeA (0x10);
List *A=new List;
//MapD(7);
A->Add(new OctEdr(0,0,0));
// A->Add(new Match(100,100,0,100,100,100));
A->ReDrawAll();
// getch();
int t=1;
while (t!=' ')
{
t=getch() ;
switch(t)
{
case 'q':
A->MoveOne(-10,0,0);
break;
case 'w':
A->MoveOne(10,0,0);
break;
case 'a':
A->MoveOne(0,-10,0);
break;
case 's':
A->MoveOne(0,10,0);
break;
case 'z':
A->MoveOne(0,0,-10);
break;
case 'x':
A->MoveOne(0,0,10);
break;
case 'f':
A->RotateOne (0l,0.1l) ; //cos
break;
case 'd':
A->RotateOne (0l,-0.1l) ; //cos
break;
case 'r':
// if(inter==51)
// {inter++;};
A->RotateOne (0.1l,0l) ; //cos
// inter++;
break;
case 'e':
A->RotateOne (-0.1l,0l) ; //cos
break;
case'1':
A->ReDrawAll();
break;
}
}
// SetModeA (i);
closegraph();
cout <<"Error #: "<< errno<<"\nAny key to exit.";
getch();
A->Clear();
}
//-------------------------------------------------------------
void MapD(char IC)
{
setcolor(IC);
line (320, 10,320,340);//v c
line (10, 10,10,340);//v l
line (630, 10,630,340);//v r
line (10,175,630,175); //h c
line (10,10,630,10); //h t
line (10,340,630,340); //h b
}
void SetModeA (char mode) //we need 10h
{
asm MOV ah,0x0;
asm{
mov al,mode
int 0x10
} ;
return;
} ;
char GetModeA (void)
{
char mode;
asm {
mov ah,0xf
int 0x10
mov mode,al
}
return mode;
}
void XPut(int x,int y, int XS, char XC) //!!!
{
int tx,ty;
for (int o=0;o<=XS ;o++)
{
tx=x+o;
ty=y+o;
PutPnt(tx,ty,XC );
ty=y-o;
PutPnt(tx,ty,XC );
}
return ;
}
void LineM (int x1, int y1, int x2, int y2, double c1, double c2, char c) //!!!
{
double cc=0;
if(c) c1=c1-1000;
if(c) c2=c2-1000;
int i;
if (XON)
XPut(x1,y1,1,4);
if ((x2!=x1))
{
int tx,ty;
long double d=((long double)(y2-y1))/((long double)(x2-x1));
if (abs(d)<=1)
{
i=(x1<x2)?1:(-1);
for (int j=0;(abs(j)<=abs(x2-x1));j+=i)
{
ty=y1+((long double)j)*d;
tx=x1+j;
cc=c1+(c2-c1)/(abs(x2-x1))*abs(j);
putpixel(tx,ty,ceil((double)(cc*255)/2800)*c);
}
}
if (abs(d)>=1)
{
d=((long double)(x2-x1))/((long double)(y2-y1));
i=(y1<y2)?1:(-1);
for (int j=0;(abs(j)<=abs(y2-y1));j+=i)
{
ty=y1+j;
tx=x1+((long double)j)*d;
cc=c1+(c2-c1)/(abs(y2-y1))*abs(j);
putpixel(tx,ty,ceil((double)(cc*255)/2800)*c);
}
}
}
else
{
int t;
i=(y1<y2)?1:(-1);
i=(y1==y2)?0:i;
do
{
// PutPnt(x1,y1,c);
cc=(c1+(c2-c1)*((y1!=y2)?(1/abs(y1-y2)):1));
putpixel(x1,y1,ceil(((double)(cc*255)/2800)*c));
y1+=i;
} while (y2!=y1);
};
};