|
25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more... |
Home Projects Up Sitemap Search Blog Forum+Chat About Us Privacy Terms of Use Feedback FAQ Images Services Payments Humor Music |
Heathkit H-100 color graphics functions to draw basic shapes in DeSmet CThese are DeSmet C functions for the Heathkit H-100 computer that use my pset function to draw basic graphic shapes: line, rectangle (box), circle, oval. |
/* -------------------------------------------------------------- */
/* H100 COLOR GRAPHICS DRAWING FUNCTIONS */
/* Copyright (C)1993 Steven Whitney. Published under the */
/* GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/* Initially published by http://25yearsofprogramming.com. */
/* -------------------------------------------------------------- */
/* LINE() 10-12-93 */
/* Copyright (C)1993 Steven Whitney. Published under the */
/* GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/* Initially published by http://25yearsofprogramming.com. */
/* DRAWS A LINE IN COLOR */
/* USES PSET(), WHICH WILL IGNORE OUT-OF-BOUNDS REQUESTS */
/* 12-5-93 TOOK DOUBLES & DOUBLE MATH OUT OF LOOP: 77% SPEED IMPROVEMENT, */
/* EVEN THOUGH LONGS ARE USED */
/* 12-7-93 SUPPORTS NEW PSET() */
/* -------------------------------------------------------------- */
#define MAX(a,b) ((a) < (b)? (b) : (a))
#define MIN(a,b) ((a) < (b)? (a) : (b))
int line(x1,y1,x2,y2,psetmode,color)
int x1, y1, x2, y2, color;
char psetmode;
{
int x, y, lastx, lasty, i;
double angle, xrange, yrange, sin(), cos(), atan();
long sine, cosine, dx, dy, longx1, longy1;
/* COULD BE SPED UP BY POKING ENTIRE BYTES FOR MIDDLE OF LINE */
if(y1 == y2) /* HORIZONTAL LINE, ALWAYS DRAWS LEFT TO RIGHT */
{
if(x1 > x2) /* LINE MUST START WITH THE LEFTMOST POINT */
{
i = x2; x2 = x1; x1 = i; /* SWAP X1 & X2 */
}
/* DRAWING OFF SCREEN WASTES TIME */
x1 = MAX(x1,-1); /* MUST BE -1 & 640 BECAUSE IF YOU USE */
x1 = MIN(x1,640); /* 0,639, A LINE ENTIRELY OFF THE SCREEN */
x2 = MIN(x2,640); /* WILL RESULT IN A POINT BEING SET */
x2 = MAX(x2,-1); /* AT THE EDGE OF THE SCREEN */
while(x1 <= x2)
pset(x1++,y1,psetmode,color);
return 1;
}
if(x1 == x2) /* VERTICAL LINE, ALWAYS DRAWS TOP TO BOTTOM */
{
if(y1 > y2)
{
i = y2; y2 = y1; y1 = i; /* SWAP Y1 & Y2 */
}
y1 = MAX(y1,-1);
y1 = MIN(y1,225);
y2 = MIN(y2,225);
y2 = MAX(y2,-1);
while(y1 <= y2)
pset(x1,y1++,psetmode,color);
return 1;
}
/* (ALLOW SLANTED LINE TO DRAW OFF SCREEN SO ANGLE IS CORRECT) */
if(x1 > x2) /* START WITH THE LEFTMOST POINT */
{
i = x2 ; x2 = x1 ; x1 = i ; /* SWAP X1 & X2 */
i = y2 ; y2 = y1 ; y1 = i ; /* SWAP Y1 & Y2 */
}
xrange = (double)(x2 - x1);
yrange = (double)(y2 - y1);
angle = atan(yrange / xrange);
cosine = (long)(cos(angle) * 10000. + .5); /* +.5 IS FOR ROUNDING */
sine = (long)(sin(angle) * 10000. + .5);
longx1 = (long)x1;
longy1 = (long)y1;
dx = dy = 0L;
x = x1;
lastx = lasty = -1; /* SET TO IMPOSSIBLE VALUE, OR AT LEAST OFF SCREEN */
while(x < x2) /* WHEN X == X2, POINT HAS ALREADY BEEN SET */
{
x = (int)(longx1 + (dx / 10000L));
y = (int)(longy1 + (dy / 10000L));
if((x != lastx) || (y != lasty)) /* DISALLOW DUPLICATE POINTS */
{ /* SO XPSET WORKS PROPERLY */
pset(x,y,psetmode,color);
lastx = x;
lasty = y;
}
dx += cosine;
dy += sine;
}
return 1;
}
/* -------------------------------------------------------------- */
/* BOX() 5-9-93 10-12-93 */
/* Copyright (C)1993 Steven Whitney. Published under the */
/* GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/* Initially published by http://25yearsofprogramming.com. */
/* DRAWS A BOX AND OPTIONALLY FILLS IT */
/* 12-5-93 SUPPORTS NEW LINE(), NEW PSET() */
/* 12-7-93 DRAWS CLOCKWISE FROM UPPER LEFT */
/* (ALTHOUGH LINE DRAWS LEFT TO RIGHT AND TOP TO BOTTOM) */
/* DOESN'T SET CORNERS TWICE, SO XPSET WORKS PROPERLY */
/* -------------------------------------------------------------- */
#define MAX(a,b) ((a) < (b)? (b) : (a))
#define MIN(a,b) ((a) < (b)? (a) : (b))
int box(x1,y1,x2,y2,psetmode,color,fill)
int x1, y1, x2, y2;
char psetmode;
int color;
int fill; /* TRUE OR FALSE */
{
int i, j, k, m;
char csts(), ci();
x1 = MAX(x1,-1); /* DRAWING OFF SCREEN WASTES TIME - SEE LINE.C */
x1 = MIN(x1,640);
y1 = MAX(y1,-1);
y1 = MIN(y1,225);
x2 = MAX(x2,-1);
x2 = MIN(x2,640);
y2 = MAX(y2,-1);
y2 = MIN(y2,225);
if(x1 > x2) /* MAKE SURE X1 IS LEFTMOST */
{
i = x2; x2 = x1; x1 = i; /* SWAP */
}
if(y1 > y2) /* MAKE SURE Y1 IS TOPMOST */
{
i = y2; y2 = y1; y1 = i;
}
if(fill)
{
for(j = y1 ; j <= y2 ; j++)
{
if(csts()) /* ^C aborts */
if(ci() == 3)
return 1;
for(i = x1 ; i <= x2 ; i++)
pset(i,j,psetmode,color);
}
}
else
{
line(x1,y1,x2-1,y1,psetmode,color); /* UPPER LEFT TO UPPER RIGHT */
line(x2,y1,x2,y2-1,psetmode,color); /* UPPER RIGHT TO LOWER RIGHT */
line(x1+1,y2,x2,y2,psetmode,color); /* LOWER LEFT TO LOWER RIGHT */
line(x1,y1+1,x1,y2,psetmode,color); /* UPPER LEFT TO LOWER LEFT */
}
return 1;
}
/* -------------------------------------------------------------- */
/* CIRCLE() 5-1-93 DRAWS A CIRCLE */
/* Copyright (C)1993 Steven Whitney. Published under the */
/* GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/* Initially published by http://25yearsofprogramming.com. */
/* 5-24-93 PLOT 8 POINTS AT ONCE INSTEAD OF 4: 3 TIMES FASTER! */
/* CAN DRAW OVALS */
/* IF ASPECT == 1., RADIUS IS MEASURED IN X UNITS */
/* IF ASPECT < 1., OVAL WILL BE HORIZONTAL, AND */
/* RADIUS WILL BE MEASURED IN X-AXIS POINTS, */
/* WITH Y AXIS SCALED SMALLER (& SCALED AGAIN TO BE PROPORTIONAL) */
/* IF ASPECT > 1., OVAL WILL BE VERTICAL, AND */
/* RADIUS WILL BE MEASURED IN TRUE Y-AXIS UNITS, */
/* WITH X AXIS SCALED SMALLER */
/* RETURNS TRUE IF SUCCEED, FALSE IF FAIL */
/* 12-5-93 SUPPORTS NEW PSET() */
/* 12-7-93 DUPLICATE POINTS DISALLOWED, SO XPSET WORKS REASONABLY WELL, */
/* BUT AXIS INTERCEPTS STILL GET SET TWICE & LEAVE HOLES, AND */
/* WITH SOME CIRCLE SIZES, PLOTTED POINTS FROM DIFFERENT SEGMENTS */
/* OVERLAP AND CAN'T BE TESTED WITH LASTX/Y */
/* NOT WORTH WORKING ON ANY MORE, BUT LEFT IN SOME OF THE CODE */
/* 5-9-94 READJUSTED ADJUSTMENT FACTOR FOR X/Y SCREEN DOTS PER INCH */
/* ADDED ^C TEST */
/* -------------------------------------------------------------- */
#define TRUE 1
#define FALSE 0
#define MAX(a,b) ((a) < (b)? (b) : (a))
int circle(x0,y0,radius,psetmode,color,aspect)
int x0, y0, radius, color;
double aspect; /* MUST HAVE A DECIMAL WHEN CALLED! */
char psetmode;
{
double i, step, angle, xradius, yradius, sine, cosine, sin(), cos();
char csts(), ci();
int dx, dy, ex, ey;
int x1, x2, x3, x4, lastx1, lastx2, lastx3, lastx4;
int y1, y2, y3, y4, lasty1, lasty2, lasty3, lasty4;
/*
INT FIRSTPASS = TRUE;
*/
if((aspect == 0.) || (color < 0) || (color > 7))
return(FALSE);
xradius = yradius = (double)(abs(radius));
/* X AXIS = 640 DOTS / 10.25" DISPLAY AREA = 62.439 DPI */
/* Y AXIS = 225 DOTS / 7.5" DISPLAY AREA = 30.0 DPI */
if(aspect == 1.)
yradius *= 0.48046875; /* RATIO DOTS/INCH IN X & Y AXES */
if(aspect < 1.) /* HORIZ. OVAL */
yradius = aspect * xradius * 0.48046875; /* MEASURED IN X UNITS */
if(aspect > 1.) /* VERT. OVAL */
xradius = (1./aspect) * yradius / 0.48046875; /* MEASURED IN Y */
lastx1 = lastx2 = lastx3 = lastx4 = -1; /* SET TO IMPOSSIBLE, */
lasty1 = lasty2 = lasty3 = lasty4 = -1; /* OR AT LEAST OFF SCREEN */
/* THE 80. CAN BE ADJUSTED */
step = 50./(MAX(xradius,yradius)); /* < FOR RESOLUTION */
for(i = 0. ; i <= 45. ; i += step ) /* OR > FOR GREATER SPEED */
{
if(csts()) /* ^C ABORTS */
if(ci() == 3) /* USEFUL FOR PARTIAL CIRCLES */
return 1;
angle = i * .0174532925; /* .0174 = 180/PI */
sine = sin(angle);
cosine = cos(angle);
dx = (int)(xradius * cosine + .5);
ex = (int)(yradius * cosine + .5);
dy = (int)(yradius * sine + .5);
ey = (int)(xradius * sine + .5);
x1 = x0 + dx;
x2 = x0 - dx;
x3 = x0 + ey;
x4 = x0 - ey;
y1 = y0 + dy;
y2 = y0 - dy;
y3 = y0 + ex;
y4 = y0 - ex;
/* INTENTIONALLY SET 4 AXIS POINTS */
/* SO WHEN THEY'RE SET AGAIN, */
/* THEY'LL COME OUT RIGHT */
/*
IF(FIRSTPASS)
{
PSET(X1,Y0,PSETMODE,COLOR); 2 OF THESE WORKED,
PSET(X2,Y0,PSETMODE,COLOR); DON'T KNOW WHICH
PSET(X0,Y1,PSETMODE,COLOR);
PSET(X0,Y2,PSETMODE,COLOR);
FIRSTPASS = FALSE;
}
*/
/* DISALLOW DUPLICATE POINT SETTING, */
/* SO XPSET WILL WORK PROPERLY */
/* PLOT POINTS USING */
/* COS FOR X, SIN FOR Y */
if((x1 != lastx1) || (y1 != lasty1))
pset(x1,y1,psetmode,color);
if((x2 != lastx2) || (y2 != lasty2))
pset(x2,y2,psetmode,color);
if((x1 != lastx1) || (y2 != lasty2))
pset(x1,y2,psetmode,color);
if((x2 != lastx2) || (y1 != lasty1))
pset(x2,y1,psetmode,color);
lastx1 = x1;
lastx2 = x2;
lasty1 = y1;
lasty2 = y2;
/* DERIVE EXTRA SET OF */
/* POINTS, USING SIN */
/* FOR X, COS FOR Y */
if((x3 != lastx3) || (y3 != lasty3))
pset(x3,y3,psetmode,color);
if((x4 != lastx4) || (y4 != lasty4))
pset(x4,y4,psetmode,color);
if((x3 != lastx3) || (y4 != lasty4))
pset(x3,y4,psetmode,color);
if((x4 != lastx4) || (y3 != lasty3))
pset(x4,y3,psetmode,color);
lastx3 = x3;
lastx4 = x4;
lasty3 = y3;
lasty4 = y4;
}
return(TRUE);
}
|
|
|
|
|
Copyright ©2011 Steven Whitney. Last modified Tue 05/24/2011 12:26:32 -0700. |
||