Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа3 / LIGHT
.CPP#include <bios.h>
#include <conio.h>
#include <dos.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define FPlus 0x4E2B
#define FMinus 0x4A2D
#define Home 0x4700
#define Up 0x4800
#define Left 0x4B00
#define Right 0x4D00
#define End 0x4F00
#define Down 0x5000
#define Esc 0x011B
#ifdef __cplusplus
float max(float value1, float value2)
{
return ( (value1 > value2) ? value1 : value2);
}
float abs(float x)
{
return x<0? -x: x;
}
#endif
void blend(void) // ЏҐаҐЇа®Ја ¬¬Ёа®ў ЁҐ Ї «Ёвал Ё§ 64-е 梥⮢
{ int x, y; // ў 64 Ја ¤ жЁЁ паЄ®б⨠梥в
for (y=x=0; x<64; x++)
{ y++;
_AX=0x1010;
_BH=0;
_BL=y;
_CH=0;
_CL=0;
_DH=x;
geninterrupt(0x10);
}
}
int KeyWait(void) // Ћ¦Ё¤ ЁҐ ¦ вЁп Є« ўЁиг
{ int key=0; // ЏаЁ ¦ вЁЁ ў®§ўа й Ґв Є®¤ Є« ўЁиЁ
while (!key)
if (kbhit())
key=bioskey(0);
return key;
}
typedef struct P
{ float x, y, z, S;
} Point3D;
typedef struct Q
{ int x, y;
unsigned char h;
} Point2D;
typedef struct S
{ int np;
int p[4];
} Side;
Point3D T[5] = {-20, -20, -20, 0, /*Є®®а¤Ё вл в®зЄЁ*/
-20, -20, 20, 0,
20, -20, 20, 0,
20, -20, -20, 0,
0, 20, 0, 0 };
Point2D U[50], Top[12];
Side sp[5] = {3, 0, 1, 4, 0, /*®ЇЁб ЁҐ Ја Ґ©*/
3, 1, 2, 4, 0,
3, 2, 3, 4, 0,
3, 0, 3, 4, 0,
4, 0, 1, 2, 3};
float A, B, xu, yu, zu, TR[40][6], TAR[40][5];
float xp = 8, yp = 7, zp = -47; //Є®®а¤Ё вл Ў«о¤ ⥫п
float xl = 8, yl = 8, zl = 23; //Є®®а¤Ё вл в®зЄЁ Ї ¤ҐЁп ў§Ј«п¤
float f = 70; //д®Є «м®Ґ а ббв®пЁҐ
int n = 5, Link[5][5], gr = 5, mgr[5] = {1, 1, 1, 0, 1};
unsigned char far Z[320][200];
void SortTR(int n)
{ int i, j, k, m, q;
float a, b;
for (i=0; i<n-1; i++)
for(j=i; j<n; j++)
if(TR[i][0]>TR[j][0])
for (k=0; k<5; k++)
{ a=TR[i][k];
TR[i][k]=TR[j][k];
TR[j][k]=a;
}
b=TR[0][0];
for (a=i=0; i<n; i++)
{ if (b!=TR[i][0]) a++;
TR[i][5]=a;
b=TR[i][0];
}
for (m=q=b=0; b<k+1; b++)
{ m=q;
for (i=m; i<n; i++)
if (TR[i][5]!=b)
{ q=i;
break;
}
for (i=m; i<q-1; i++)
for (j=i; j<q; j++)
if (TR[i][2]>TR[j][2])
for (k=0; k<5; k++)
{ a=TR[i][k];
TR[i][k]=TR[j][k];
TR[j][k]=a;
}
}
}
void SortTAR(int n)
{ int i, j, k;
float a;
for (i=0; i<n-1; i++)
for (j=i; j<n; j++)
if (TAR[i][2]>TAR[j][2])
for (k=0; k<5; k++)
{ a=TAR[i][k];
TAR[i][k]=TAR[j][k];
TAR[j][k]=a;
}
}
int AddGroupTAR(int i, int na, int n)
{ int k, j, a=0;
for (j=i; j<n; j++)
if (TR[j][5]==TR[i][5]) a++;
for (j=0; j<a; j++, na++)
for (k=0; k<5; k++)
TAR[na][k]=TR[i+j][k];
return na;
}
int isTop(Point2D *t, int n, int x, int y)
{ int i;
for (i=0; i<n; i++)
if (t[i].x==x && t[i].y==y)
if ((y<t[i? i-1: n-1].y && y<t[i<n-1? i+1: 0].y) ||
(y>=t[i? i-1: n-1].y && y>=t[i<n-1? i+1: 0].y))
return 1;
return 0;
}
// ‡ ЇЁб вм Ј«гЎЁг ЇЁЄбҐ« ў ЎгдҐа
void PutPixel(int x, int y, unsigned char h)
{ if (x>=0 && x<320 && y>=0 && y<200)
if (Z[x][y] <= h)
Z[x][y]=h;
}
#define Hmax 255
#define Smin 5
#define Smax 200
// ‚®§ўа в паЄ®бвЁ ў § ўЁбЁ¬®бвЁ ®в Ј«гЎЁл
unsigned int Bright(int h)
{ int v;
//v=20+43*h/Hmax;
v = h%Hmax;
v=(v<1)? 0: v;
v=v>63? 63: v;
return v;
}
// ‚뢥б⨠ᮤҐа¦Ё¬®Ґ ЎгдҐа
void ShowBuffer(void)
{
int x, y;
for (y=0; y<200; y++)
for (x=0; x<320; x++)
pokeb(0xA000, 320*y+x, Z[x][y]? Bright(Z[x][y]): 0);
}
void Line(Point2D a, Point2D b)
{ float h, dh, dx, dy, x, y, i, w;
x=a.x; y=a.y; h=a.h;
w=max(abs(b.x-a.x), abs(b.y-a.y));
dh=w? (b.h-a.h)/w: a.h;
if (!w)
PutPixel(x, y, h);
else
{ dx=abs(b.x-a.x)/w;
dy=abs(b.y-a.y)/w;
if (b.x<a.x) dx=-dx;
if (b.y<a.y) dy=-dy;
for (i=0; i<w; i++)
{ PutPixel(x, y, h);
x+=dx; y+=dy; h+=dh;
}
}
}
float H(float y1, float y2, float y)
{ int i, j, a, b;
for (i=0; i<n; i++)
for (j=0; j<n; j++)
if (U[i].y==y1 && U[j].y==y2 && Link[i][j])
{ a=i; b=j; j=n; i=n;
}
return U[a].h+(U[b].h-U[a].h)*(y-y1)/(y2-y1);
}
// ‡ «ЁўЄ § ¬Єгв®© ®Ў« бвЁ ¬Ґв®¤®¬ Ї®бва®з®Ј® бЄ Ёа®ў Ёп
void Fill(Point2D *t, int q)
{ int i, j, na, p, a, b;
float Y, Ymax, k, h1, h2, h, dh;
for (na=i=0; i<q; i++) // €ЁжЁ «Ё§ жЁп TR
{ j=i>q-2? 0: i+1;
TR[i][0]=t[i].y<t[j].y? t[i].y: t[j].y;
TR[i][1]=t[i].y>t[j].y? t[i].y: t[j].y;
TR[i][2]=t[i].y==TR[i][0]? t[i].x: t[j].x;
TR[i][3]=t[i].y!=TR[i][0]? t[i].x: t[j].x;
TR[i][4]=(TR[i][3]-TR[i][2])/((TR[i][1]-TR[i][0])? TR[i][1]-TR[i][0]: 1);
}
SortTR(q);
Y=TR[0][0];
for (Ymax=i=0; i<q; i++)
Ymax=TR[i][1]>Ymax? TR[i][1]: Ymax;
do
{ for (i=0; i<q; i++)
if (Y==TR[i][0])
{ na=AddGroupTAR(i, na, q);
break;
}
SortTAR(na);
if (TAR[0][0]==TAR[0][1] && TAR[1][0]==TAR[1][1])
break;
if (TAR[0][0]==TAR[1][1] ||
(TAR[1][0]==TAR[0][1] && TAR[0][0]!=TAR[0][1]))
{ h1=H(TAR[0][0], TAR[0][1], Y);
h2=H(TAR[2][0], TAR[2][1], Y);
}
else
{ if (TAR[0][0]==TAR[0][1])
h1=H(TAR[1][0], TAR[1][1], Y);
else
h1=H(TAR[0][0], TAR[0][1], Y);
if (TAR[1][0]==TAR[1][1])
h2=H(TAR[2][0], TAR[2][1], Y);
else
h2=H(TAR[1][0], TAR[1][1], Y);
}
for (i=0; i<na-1; i++)
if ((Y==TAR[i][1] && Y==TAR[i+1][0]) || (Y==TAR[i][0] && Y==TAR[i+1][1]))
{ TAR[i][2]=(int)(TAR[i][2]+.5);
TAR[i+1][2]=(int)(TAR[i+1][2]+.5);
}
for (p=i=0; i<na-1; i++)
{ a=TAR[i][2]; b=TAR[i+1][2];
h=h1;
if (a!=b)
dh=(h2-h1)/(b-a);
if (a!=b && !isTop(t, q, a+.5, Y))
p=!p;
if (p)
for (k=a; k<b; k+=.9, h+=dh)
PutPixel(k+.5, Y, h);
}
for (i=0; i<na; i++)
if (Y==TAR[i][1])
{ for (j=0; j<5; j++)
TAR[i][j]=TAR[na-1][j];
na--; i=-1;
}
for (i=0; i<na; i++)
TAR[i][2]+=TAR[i][4];
Y++;
}
while (Y<Ymax);
}
void ClearImage(void) // ‘вЁа ЁҐ Ё§®Ўа ¦ҐЁп нЄа Ґ
{ int x, y;
for (y=0; y<200; y++)
for (x=0; x<320; x++)
Z[x][y]=0;
}
void OutputImage(void) // ‚лў®¤ Ё§®Ўа ¦ҐЁп нЄа
{
int i, j;
float a, b, c, d, l, a1, a2, a3, b1, b2, b3, c2, c3, lxy;
xu=xp-xl;
yu=yp-yl;
zu=zp-zl;
lxy=sqrt(xu*xu+yu*yu);
l=sqrt(xu*xu+yu*yu+zu*zu);
a1=-yu/lxy;
a2=-xu*zu/(l*lxy);
a3=xu/l;
b1=xu/lxy;
b2=-yu*zu/(l*lxy);
b3=yu/l;
c2=lxy/l;
c3=zu/l;
for (i=0; i<n; i++)
{
a=T[i].x-xp;
b=T[i].y-yp;
c=T[i].z-zp;
d=a*a3+b*b3+c*c3;
T[i].S=-d;
U[i].x=-f*(a*a1+b*b1)/d+160;
U[i].y=-f*(a*a2+b*b2+c*c2)/d+100;
U[i].h=(int)A/T[i].S-B;
}
for (i=0; i<n; i++)
for (j=i+1; j<n; j++)
if (Link[i][j])
if (T[i].S >= 0 && T[j].S >= 0)
Line(U[i], U[j]);
for (i=0; i<gr; i++)
if (mgr[i])
{ for (j=0; j<sp[i].np; j++)
Top[j]=U[sp[i].p[j]];
Fill(Top, sp[i].np);
}
ShowBuffer();
}
void Analysis(int k)
{
int i;
float j;
ClearImage();
switch (k)
{
case FPlus: f+=3; break; // “ўҐ«Ёз. д®Єгб
case FMinus: { f=f>2? f-3: f; } break; // “¬Ґми. д®Єгб
case Home: { zp=zp+3; zl=zl+3;} break; // ЏаЁЎ«Ё§Ёвмбп
case End: { zp=zp-3; zl=zl-3;} break; // “¤ «Ёвмбп
case Up: { yp+=3; yl+=3;} break; // ‚ўҐае
case Down: { yp-=3; yl-=3;} break; // ‚Ё§
case Left: { xp-=3; xl-=3;} break; // ‚«Ґў®
case Right: { xp+=3; xl+=3;} break; // ‚Їа ў®
}
OutputImage();
}
void main(void)
{
int i, k;
// for (k=0; k<12; mgr[k]=1, k++);
A=(float)Hmax*Smin*Smax/(Smax-Smin);
B=(float)Hmax*Smin/(Smax-Smin);
for (i=0; i<5; i++)
for (k=0; k<5; k++)
Link[i][k]=0;
for (i=0; i<gr; i++)
{ Link[sp[i].p[0]][sp[i].p[sp[i].np-1]]=1;
Link[sp[i].p[sp[i].np-1]][sp[i].p[0]]=1;
for (k=0; k<sp[i].np-1; k++)
{ Link[sp[i].p[k]][sp[i].p[k+1]]=1;
Link[sp[i].p[k+1]][sp[i].p[k]]=1;
}
}
_AX=0x13;
geninterrupt(0x10);
blend();
OutputImage();
do
{
k=KeyWait();
Analysis(k);
}
while (k!=Esc);
_AX=3;
geninterrupt(0x10);
}