Graph.Inc 圖形函數

參考:《C與C++高級圖形程序設計》

-----------------我是分隔線:-D------------------

/*

=============================================

Video Graphics Array Driver
Original Material by Christopher D.Watkins
'C' Conversion by Larry Sharp
=============================================

SetMode - selects the display mode
Plot - place pixel to screen
ClearPalette - clear palette register
SetPalette - clear palette register
InitPalette1 - 64 levels of grey, red, green and blue
InitPalette2 - 7 colors with 35 intensities each
cyclepalette - cycle through palette
Circle - circle draw routine
Draw - line draw routine
InitGraphics - initialize graphics
WaitForKey - wait for key press
ExitGraphics - sound and wait for keypress before exiting graphics
Title - set up text screen colors
*/


union REGS reg;
struct SREGS inreg;


void SetMode(int Mode)
{
reg.h.ah = 0;
reg.h.al = Mode;
int86(0x10, &reg, &reg);
}


#define MaxXres 320
#define MaxYres 200
#define MaxX (MaxXres - 1)
#define MaxY (MaxYres - 1)


int XRes, YRes;
Word PreCalcY[MaxY + 1];


void PreCalc()
{
Word j;

for (j=0; j<=MaxY; j++)
PreCalcY[j] = 0;
for (j=0; j<=MaxY; j++)
PreCalcY[j] = XRes*j;
}


void Plot(int x, int y, Byte color)
{
Word Offset;
char far *address;

if(!((x<0) || (y<0) || (x>MaxX) || (y>MaxY)))
{
Offset = PreCalcY[y] + x;
address = (char far *) (0xA0000000L + Offset);
*address = color;
}
}


typedef struct
{
Byte Red;
Byte Grn;
Byte Blu;
}RGB;


typedef RGB PaletteRegister[255];


PaletteRegister Color;


void ClearPalette(PaletteRegister Color)
{
Word i;

for (i=0; i<=255; i++)
{
Color[i].Red = 0;
Color[i].Grn = 0;
Color[i].Blu = 0;
}
}


void SetPalette(PaletteRegister Hue)
{
reg.x.ax = 0x1012;
segread(&inreg);
inreg.es = inreg.ds;
reg.x.bx = 0;
reg.x.cx = 256;
reg.x.dx = (int) &Hue[0];
int86x(0x10, &reg, &reg, &inreg);
}


void InitPalette(PaletteRegister Color)
{
Word i;

for (i=0; i<64; i++)
{
Color[i].Red = i;
Color[i].Grn = i;
Color[i].Blu = i;
}

for (i=64; i<128; i++)
{
Color[i].Red = i - 64;
Color[i].Grn = 0;
Color[i].Blu = 0;
}

for (i=128; i<192; i++)
{
Color[i].Red = 0;
Color[i].Grn = i - 128;
Color[i].Blu = 0;
}

for (i=192; i<=255; i++)
{
Color[i].Red = 0;
Color[i].Grn = 0;
Color[i].Blu = i - 192;
}
}


void InitPalette2(PaletteRegister Color)
{
Word i;

for (i=0; i<36; i++)
{
Color[i].Red = 0;
Color[i].Grn = 0;
Color[i].Blu = Round(1.8 * i);
}

for (i=36; i<72; i++)
{
Color[i].Red = 0;
Color[i].Grn = Round(1.8 * (i-36));
Color[i].Blu = 0;
}

for (i=72; i<108; i++)
{
Color[i].Red = 0;
Color[i].Grn = Round(1.8 * (i-72));
Color[i].Blu = Round(1.8 * (i-72));
}

for (i=108; i<144; i++)
{
Color[i].Red = Round(1.8 * (i-108));
Color[i].Grn = 0;
Color[i].Blu = 0;
}

for (i=144; i<180; i++)
{
Color[i].Red = Round(1.8 * (i-144));
Color[i].Grn = 0;
Color[i].Blu = Round(1.8 * (i-144));
}

for (i=180; i<216; i++)
{
Color[i].Red = Round(1.8 * (i-180));
Color[i].Grn = Round(1.8 * (i-180));
Color[i].Blu = 0;
}

for (i=216; i<252; i++)
{
Color[i].Red = Round(1.8 * (i-216));
Color[i].Grn = Round(1.8 * (i-216));
Color[i].Blu = Round(1.8 * (i-216));
}
}


void CyclePalette(PaletteRegister Hue)
{
Word i;
RGB tmp;

tmp = Hue[0];
for (i = 1; i<=255; i++)
Hue[i-1] = Hue[i];
Hue[255] = tmp;
SetPalette(Hue);
}


void Swap(int *first, int *second)
{
int temp;

temp = *first;
*first = *second;
*second = temp;
}


void Circle(Word x, Word y, Word radius, Byte color)
{
int a, af, b, bf, target, r2;

target = 0;
a = radius;
b = 0;
r2 = Sqr(radius);
while(a >= b)
{
b = Round(sqrt(r2 - Sqr(a)));
Swap(&target, &b);
while(b<target)
{
af = (120*a) / 100;
bf = (120*b) / 100;
Plot(x+af, y+b, color);
Plot(x+bf, y+a, color);
Plot(x-af, y+b, color);
Plot(x-bf, y+a, color);
Plot(x-af, y-b, color);
Plot(x-bf, y-a, color);
Plot(x+af, y-b, color);
Plot(x+bf, y-a, color);
++b;
}
--a;
}
}


void Draw(int xx1, int yy1, int xx2, int yy2, Byte color)
{
int LgDelta, ShDelta, Cycle, LgStep, dtotal;

LgDelta = xx2 - xx1;
ShDelta = yy2 - yy1;

if (LgDelta < 0)
{
LgDelta = - LgDelta;
LgStep = -1;
}
else
LgStep = 1;

if (ShDelta < 0)
{
ShDelta = - ShDelta;
ShStep = -1;
}
else
ShStep = 1;

if (ShDelta < LgDelta)
{
Cycle = LgDelta >> 1;
while (xx1 != xx2)
{
Plot(xx1, yy1, color);
Cycle += ShDelta;
if (Cycle > LgDelta)
{
Cycle -= LgDelta;
yy1 += ShStep;
}
xx1 += LgStep;
}
Plot(xx1, yy1, color);
}
else
{
Cycle = ShDelta >> 1;
Swap(&LgDelta, &ShDelta);
Swap(&LgStep, &ShStep);
while (yy1 != yy2)
{
Plot(xx1, yy1, color);
Cycle += ShDelta;
if (Cycle > LgDelta)
{
Cycle -= LgDelta;
xx1 += ShStep;
}
yy1 += LgStep;
}
Plot(xx1, yy1, color);
}
}


void InitGraphics()
{
XRes = MaxXres;
YRes = MaxYres;
PreCalc();
SetMode(19);
ClearPalette(Color);
InitPalette2(Color);
SetPalette(Color)
}


void WaitForKey()
{
char k;
while (!(k =getch()));
}


void ExitGraphics()
{
sound(1000);
delay(500);
nosound();
WaitForKey();
SetMode(3);
}


void Title()
{
textcolor(YELLOW);
textbackground(BLUE);
clrscr();
}


/*
Three Dimensional Plotting Routines


InitPlotting - rotation and tilt angles
InitPerspective - observer location and distances
MapCoordinates - maps 3D space onto the 2D screen
CartesianPlot - plot a cartesian system point
CylindricalPlot3D - plot a cylindrical system point
SphericalPlot3D - plot a spherical system point
DrawLine3D - plots a line from 3D coordinates
*/


int CentreX, CentreY;
int Angl, Tilt;
float CosA, SinA;
float CosB, SinB;
float CosACosB, SinASinB;
float CosASinB, SinACosB;


void InitPlotting(int Ang, int Tlt)
{
CentreX = MaxX >> 1;
CentreY = MaxY >> 1;
Angl = Ang;
Tilt = Tlt;
CosA = CosD(Angl);
SinA = SinD(Angl);
CosB = CosD(Tilt);
SinB = SinD(Tilt);
CosACosB = CosA * CosB;
SinASinB = SinA * SinB;
CosASinB = CosA * SinB;
SinACosB = SinA * CosB;
}


Boolean PerspectivePlot;
float Mx, My, Mz, ds;


void InitPerspective(Boolean Perspective, float x, float y, float z, float m)
{
PerspectivePlot = Perspective;
Mx = x;
My = y;
Mz = z;
ds = m;
}


void MapCoordinates(float X, float Y, float Z, int *Xp, int *Yp)
{
float Xt, Yt, Zt;

Xt = (Mx + X*CosA - Y*SinA);
Yt = (My + X*SinASinB + Y*CosASinB + Z*CosB);

if (PerspectivePlot)
{
Zt = Mz + X*SinACosB + Y*CosACosB - Z*SinB;
*Xp = CentreX + Round(ds*Xt/Zt);
*Yp = CentreY - Round(ds*Yt/Zt);
}
else
{
*Xp = CentreX + Round(Xt);
*Yp = CentreY - Round(Yt);
}
}


void CartesianPlot3D(float X, float Y, float Z, Byte Color)
{
int Xp, Yp;

MapCoordinates(X, Y, Z, &Xp, &Yp);
Plot(Xp, Yp, Color);
}


void SphericalPlot3D(float R, float Theta, float Phi, Byte Color)
{
float X, Y, Z;

Theta = Radians(Theta);
Phi = Radians(Phi);
X = R * sin(Theta) * cos(Phi);
Y = R * sin(Theta) * sin(Phi);
Z = R * cos(Theta);
CartesianPlot3D(X, Y, Z, Color);
}


void DrawLine3D(TDA Pnt1, TDA Pnt2, Byte Color)
{
int Xp1, Yp1;
int Xp2, Yp2;
float x1, y1, z1;
float x2, y2, z2;

UnVec(Pnt1, &x1, &y1, &z1);
UnVec(Pnt2, &x2, &y2, &z2);
MapCoordinates(x1, y1, z1, &Xp1, &Yp1);
MapCoordinates(x2, y2, z2, &Xp2, &Yp2);
Draw(Xp1, Yp1, Xp2, Yp2, Color);
}


/*
Pixel


PutPixel - plots pixel
GetPixel - gets pixel


Color
1 - Blue
2 - Green
3 - Cyan
4 - Red
5 - Magenta
6 - Brown/Yellow
7 - Gray Scale


Intensity levels (0..35) for each color
*/


#define MaxCol 7
#define MaxInten 35


void PutPixel(int x, int y, Byte Color, Byte Intensity)
{
Byte Col;

if ( Intensity > MaxInten)
{
printf("*Inten > MaxInten!!\n\nHit any hey to exit.\n");
getch();
exit(1);
}
Col = ((MaxInten + 1)*(color - 1) + Intensity) & 255;
Plot(x, y, Col);
}


int GetPixel(int x, int y)
{
reg.x.ax = 3328;
reg.x.dx = y;
reg.x.cx = x;
int86(0x10, &reg, &reg);
return(reg.x.ax&255);
}


/*
Set up of Coordinate Axes and Color Palette


PutAxisAndPalette - toggle for Axis and Palette
AxisAndPalette - places Axis and Color Palette on screen
*/


Boolean DrawAxisAndPalette;
void PutAxisAndPalette(Boolean PlaceOnScreen)
{
if (PlaceOnScreen)
DrawAxisAndPalette = true;
else
DrawAxisAndPalette = false;
}


void DisplayAxis()
{
int x, y, z;

for (x=-100; x<101; x++)
{
CartesianPlot3D(x, 0, 0, 35);
CartesianPlot3D(100, 0, 0, 251);
}

for (y = -100; y<101; y++)
{
CartesianPlot3D(0, y, 0, 71);
CartesianPlot3D(0, 100, 0, 251);
}

for (z = -100; z<101; z++)
{
CartesianPlot3D(0, 0, z, 107);
CartesianPlot3D(0, 0, 100, 251);
}
}


void DisplayPalette()
{
int X, Y;
Byte Color;
Byte Intensity;

for (Color=1; Color<=MaxCol; Color++)
{
for (Intensity=0; Intensity<=MaxInten; Intensity++)
{
for (X=0; X<4; X++)
{
for (Y=0; Y<4; Y++)
PutPixel(X+5*Color, 190-Y-5*Intensity, Color, Intensity);
}
}
}
}


void AxisAndPalette()
{
if (DrawAxisAndPalette)
{
DisplayAxis();
DisplayPalette();
}
}
發佈了9 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章