home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
listings
/
v_02_03
/
2n03050a
< prev
next >
Wrap
Text File
|
1991-01-15
|
11KB
|
401 lines
/********************************************************************
* BEZDIS.C -- Interactive Bezier Curve Display.
*
* Author : Bob Zigon
* Date : July 26, 1989
********************************************************************/
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "bios.h"
#include "graphics.h"
#include "keys.h"
/*******************************************************************
* Global Defines
********************************************************************/
#define OFF 0
#define ON (!OFF)
#define MAXTDivisions 150
#define MINTDivisions 30
#define MAXCP 10
#define CPDx 0.05
#define CPDy 0.05
/*******************************************************************
* Variable Declarations
********************************************************************/
double XCp[MAXCP+1], /* X Control Points */
YCp[MAXCP+1]; /* Y Control Points */
short int XCpScr[MAXCP+1],
YCpScr[MAXCP+1];
double XCurve[MAXTDivisions+1], /* X Curve Points */
YCurve[MAXTDivisions+1]; /* Y Curve Points */
short int Xv[MAXTDivisions+1],
Yv[MAXTDivisions+1];
short int XvpMin, /* Viewport dimensions */
XvpMax,
YvpMin,
YvpMax,
XsMax, /* Screen Dimensions in pixels */
YsMax;
short int TDivisions = MINTDivisions,
NumCP,
CurCP = 0,
Refresh = ON;
short int CurveColor,
LineColor,
CrossColor,
BgdColor;
double XCpMin = 0.0,
XCpMax = 5.0,
YCpMin = 0.0,
YCpMax = 5.0;
char *HelpMsg[] =
{
" F1 - Help",
" F2 - Toggle refresh of CP line segments",
" ",
" Left - Move current CP left 1 unit",
" Right - Move current CP right 1 unit",
" Up - Move current CP up 1 unit",
" Down - Move current CP down 1 unit",
" ",
" PgUp - Next CP",
" PgDn - Prev CP",
" Ins - Insert CP",
" Del - Delete CP",
" ",
" Home - Add 5 to number of parametric divisions",
" End - Sub 5 from number of parametric divisions ",
" ",
" ESC - QUIT"
};
#define NUMHELP (sizeof(HelpMsg)/sizeof(char *))
/*******************************************************************
* Function Prototypes
********************************************************************/
void Binomial(short int NumControl), UpdateStatus(void);
void BezierToScreen(short int, short int, short int *, short int *);
short int GetInput(void), Check8087(void);
void Initialize(void), DrawCurve(short int), DrawCross(short int);
void WToVConst(void), GetHelp(void);
void main()
{
short int i, cc;
Initialize();
WToVConst();
Binomial(NumCP);
BezierToScreen(TDivisions, NumCP, Xv, Yv);
DrawCurve(ON);
UpdateStatus();
while ((cc = GetInput()) != ESC)
switch (cc)
{
case F1 : GetHelp();
break;
case F2 : DrawCurve(OFF);
Refresh = !Refresh;
DrawCurve(ON);
UpdateStatus();
break;
case LEFT : if (XCp[CurCP]-CPDx > XCpMin)
{
DrawCurve(OFF);
XCp[CurCP] -= CPDx;
BezierToScreen(TDivisions, NumCP, Xv, Yv);
DrawCurve(ON);
}
break;
case RIGHT : if (XCp[CurCP]+CPDx < XCpMax)
{
DrawCurve(OFF);
XCp[CurCP] += CPDx;
BezierToScreen(TDivisions, NumCP, Xv, Yv);
DrawCurve(ON);
}
break;
case DOWN : if (YCp[CurCP]-CPDy > YCpMin)
{
DrawCurve(OFF);
YCp[CurCP] -= CPDy;
BezierToScreen(TDivisions, NumCP, Xv, Yv);
DrawCurve(ON);
}
break;
case UP : if (YCp[CurCP]+CPDy < YCpMax)
{
DrawCurve(OFF);
YCp[CurCP] += CPDy;
BezierToScreen(TDivisions, NumCP, Xv, Yv);
DrawCurve(ON);
}
break;
case PGUP : if (CurCP+1 < NumCP)
{
DrawCross(BgdColor);
CurCP++;
DrawCurve(ON);
DrawCross(CrossColor);
UpdateStatus();
}
break;
case PGDN : if (CurCP-1 > -1)
{
DrawCross(BgdColor);
CurCP--;
DrawCurve(ON);
DrawCross(CrossColor);
UpdateStatus();
}
break;
case HOME : if (TDivisions+5 < MAXTDivisions)
{
DrawCurve(OFF);
TDivisions += 5;
BezierToScreen(TDivisions, NumCP, Xv, Yv);
DrawCurve(ON);
UpdateStatus();
}
break;
case END : if (TDivisions-5 >= MINTDivisions)
{
DrawCurve(OFF);
TDivisions -= 5;
BezierToScreen(TDivisions, NumCP, Xv, Yv);
DrawCurve(ON);
UpdateStatus();
}
break;
case INS : if (NumCP+1 < MAXCP && CurCP+1 != NumCP)
{
DrawCurve(OFF);
for (i = NumCP++; i > CurCP; i--)
{
XCp[i] = XCp[i-1];
YCp[i] = YCp[i-1];
}
Binomial(NumCP);
BezierToScreen(TDivisions, NumCP, Xv, Yv);
DrawCurve(ON);
UpdateStatus();
}
break;
case DEL : if (NumCP > 2)
{
DrawCurve(OFF);
for (i = CurCP, NumCP--; i < NumCP; i++)
{
XCp[i] = XCp[i+1];
YCp[i] = YCp[i+1];
}
if (CurCP == NumCP)
CurCP--;
Binomial(NumCP);
BezierToScreen(TDivisions, NumCP, Xv, Yv);
DrawCurve(ON);
UpdateStatus();
}
break;
}
closegraph();
}
void Initialize()
{
int Gdriver, Gmode;
if (Check8087() == 0)
{
printf("\nNo Arithmetic Coprocessor Present.");
exit(1);
}
detectgraph(&Gdriver, &Gmode);
if (Gdriver < 0)
{
printf("\nError : No graphics hardware detected.");
exit(1);
}
if (Gmode == CGAHI)
Gmode = CGAC0;
initgraph(&Gdriver, &Gmode, "");
XvpMin = 5;
YvpMin = 5;
XvpMax = getmaxx()-5;
YvpMax = getmaxy()-3-textheight("A");
XsMax = getmaxx();
YsMax = getmaxy();
if (Gdriver == CGA)
{
BgdColor = 0;
CurveColor = CGA_GREEN;
LineColor = CGA_BROWN;
CrossColor = CGA_RED;
}
else
{
BgdColor = BLACK;
CurveColor = WHITE;
LineColor = YELLOW;
CrossColor = RED;
}
NumCP = 4;
XCp[0] = 1.0; YCp[0] = 1.0;
XCp[1] = 2.0; YCp[1] = 3.0;
XCp[2] = 4.0; YCp[2] = 3.0;
XCp[3] = 3.0; YCp[3] = 1.0;
}
void DrawCurve(OnOff)
short int OnOff;
{
register short int i;
if (OnOff == OFF)
{
DrawCross(BgdColor);
if (Refresh == ON)
{
moveto(XCpScr[0], YCpScr[0]);
for (i = 1; i < NumCP; i++)
lineto(XCpScr[i], YCpScr[i]);
}
moveto(Xv[0], Yv[0]);
for (i = 1; i < TDivisions+1; i++)
lineto(Xv[i], Yv[i]);
}
else
{
setcolor(LineColor);
if (Refresh == ON)
{
moveto(XCpScr[0], YCpScr[0]);
for (i = 1; i < NumCP; i++)
lineto(XCpScr[i], YCpScr[i]);
}
setcolor(CurveColor);
moveto(Xv[0], Yv[0]);
for (i = 1; i < TDivisions+1; i++)
lineto(Xv[i], Yv[i]);
DrawCross(CrossColor);
}
}
void DrawCross(color)
short int color;
{
setcolor(color);
line(XCpScr[CurCP]-3, YCpScr[CurCP], XCpScr[CurCP]+3, YCpScr[CurCP]);
line(XCpScr[CurCP], YCpScr[CurCP]-3, XCpScr[CurCP], YCpScr[CurCP]+3);
}
void UpdateStatus()
{
char buf[80];
setviewport(0, YvpMax+1, XsMax, YsMax, 0);
clearviewport();
setcolor(LineColor);
sprintf(buf, " CP %2d of %2d Div: %3d ", CurCP+1, NumCP, TDivisions);
outtextxy(0, 0, buf);
setviewport(0, 0, XsMax, YsMax, 0);
}
void GetHelp()
{
short int HelpL, HelpR, HelpT, HelpB;
short int i, THgt, MaxLen, HSize, MaxHgt;
char *Buf;
for (i = 0, MaxLen = 0; i < NUMHELP; i++)
if (strlen(HelpMsg[i]) > MaxLen)
MaxLen = strlen(HelpMsg[i]);
MaxLen *= textwidth("A");
THgt = textheight("A");
MaxHgt = THgt*NUMHELP;
HelpL = (XsMax-MaxLen)/2;
HelpR = HelpL+MaxLen+5;
HelpT = (YsMax-MaxHgt)/2;
HelpB = HelpT+MaxHgt+5;
HSize = imagesize(HelpL, HelpT, HelpR, HelpB);
if ((Buf=malloc(HSize)) == NULL)
return;
getimage(HelpL, HelpT, HelpR, HelpB, Buf);
setviewport(HelpL, HelpT, HelpR, HelpB, 1);
clearviewport();
setcolor(LineColor);
line(0, 0, MaxLen+4, 0);
line(MaxLen+4, 0, MaxLen+4, MaxHgt+4);
line(MaxLen+4, MaxHgt+4, 0, MaxHgt+4);
line(0, MaxHgt+4, 0, 0);
for (i = 0; i < NUMHELP; i++)
outtextxy(2, i*THgt+2, HelpMsg[i]);
while (GetInput() != ESC)
;
setviewport(0, 0, XsMax, YsMax, 0);
putimage(HelpL, HelpT, Buf, COPY_PUT);
free(Buf);
}
short int GetInput(void)
{
short int key;
/*
* If it is not an extended key, then return the ascii value.
*/
if ((key = bioskey(0)) & 0xFF)
return (key & 0xFF);
return (0x200 + ((key & 0xFF00) >> 8));
}