Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Circle-drawing?

314 views
Skip to first unread message

Harry Potter

unread,
Apr 9, 2009, 12:51:46 PM4/9/09
to
How do I draw a filled, rotated or non-rotated circle on a graphics
screen, especially with integers?

J. Robertson

unread,
Apr 9, 2009, 12:59:44 PM4/9/09
to

Easy:

1. Put the C64 into your favorite graphics mode.
2. Get rid of the integers - you won't need them.
3. Find a marker. Preferably a dry erase one (color of your choice).
4. With your marker draw a circle on your screen.
5. Fill it in with marker.

Done!

Joe Forster/STA

unread,
Apr 9, 2009, 1:00:28 PM4/9/09
to
> How do I draw a filled, rotated or non-rotated circle on a graphics
> screen, especially with integers?

Non-filled circle: http://en.wikipedia.org/wiki/Midpoint_circle_algorithm

lyricalnanoha

unread,
Apr 9, 2009, 1:09:15 PM4/9/09
to

On Thu, 9 Apr 2009, Harry Potter wrote:

> How do I draw a filled, rotated or non-rotated circle on a graphics
> screen, especially with integers?
>

My usual method of doing an OPEN circle has been something like this
algorithm (which is in more or less qbasic syntax as that's what I know):

pset (cx+arx, cy), c
for deg=0 to 360
rdn=(3.141593/180)*deg
x=cx+(cos(rdn)*arx*rad)
y=cy+(sin(rdn)*ary*rad)
line -(x, y), c
next deg

where (cx,cy) is the center, rad is the radius, arx:ary is the pixel
aspect ratio (I think you want 1.6:1 or 0.8:1 for a C64 depending on the
resolution), and c is the color.

Since the C64's BASIC don't have "pset", "line" or "paint" as GW-BASIC
did, you'd need to supply those yourself.

-uso.

Bill Buckels

unread,
Apr 9, 2009, 1:42:00 PM4/9/09
to

"Harry Potter" <maspet...@aol.com> wrote:

>How do I draw a filled, rotated or non-rotated circle on a graphics screen,
>especially with integers?

Here's how I do it on the C64 in my Windows Xp Aztec C cross-compiler
library: (see below)

Why do you ask? If you actually want to do something about this why not
download the compiler with all the graphics libraries and demos and so forth
and actually work with it:

http://www.aztecmuseum.ca/compilers.htm#commodore

"This is a complete Aztec C build environment for Windows XP (MS-DOS) which
will enable you to produce efficient 6502 machine-language programs which
will, when properly built, load and run from BASIC on a Commodore 64 or in
the Vice C64 emulator, and which will exit cleanly to BASIC when done."

"An additional link library (B64NAT.LIB) is provided which supports, among
other things, the use of graphics and bit-mapped graphics images, sound
routines, and other useful routines for native mode C64 Aztec C programs."

"Several sample programs and C64 projects are provided, each with its own
MAKEFILE and each can be reviewed for information on how to write your own
C64 programs."

Bill

x--- snip ---x

/* Copyright (C) Bill Buckels 2008 */

/* standard implementation of bresenham's */
/* I am not using an external aspect ratio */
/* ellipsoids look pretty bad so no point */
circle(cx,cy,r,color,mode)
int cx,cy,r,color,mode;
{

int x,y,a,b,c,d,f,m,n;

x=r; y=0; b=1; f=0;

if (mode != 2)mode = 1; /* 320 x 200 mode 1 */

a=(-2)*x+1;
m=1;
n=mode; /* aspect of 2 for 160 x 200 mode 2 */

point:

c=x;
d=y;

plot(c*m+cx,y*n+cy,color,mode);
plot(d*m+cx,x*n+cy,color,mode);
plot(-d*m+cx,x*n+cy,color,mode);
plot(-c*m+cx,y*n+cy,color,mode);
plot(-c*m+cx,-y*n+cy,color,mode);
plot(-d*m+cx,-x*n+cy,color,mode);
plot(d*m+cx,-x*n+cy,color,mode);
plot(c*m+cx,-y*n+cy,color,mode);

if(b>= -a)
goto fin;

y+=1; f+=b;
b+=2;

if(f>r)
{
f+=a;
a+=2;
x-=1;
}
goto point;

fin:
;
}

x--- snip ---x

/* Copyright (C) Bill Buckels 2008 */

disk(cx,cy,r,color,mode)
int cx,cy,r,color,mode;
{

int xc, yc; /* xcenter, ycenter */
int x,y; /*current point around 1/8 disk*/
int rem; /*remainder value*/

cx -= r; /* draw from top left */
cy -= r;

xc = r; /* offset center by aspect */
yc = r;

y=0;
x=r; /*initial point is on axis*/
rem=r/2; /*remainder=1/2 for roundoff*/
while (x>=y) /*loop for 1/8 of a circle*/
{
/*fill in top half of circle*/
drawline(xc-x+cx,yc+y+cy,xc+x+cx,yc+y+cy,color, mode);
/*and bottom half*/
drawline(xc-x+cx,yc-y+cy,xc+x+cx,yc-y+cy,color,mode);
y += 1; /*always increment y*/
rem=rem-y; /*subtract from remainder*/
if (rem<0) /*if it's time,*/
{
x=x-1; /*then decrement x*/
rem=rem+x; /*and bump remainder back up*/
}
}
while(x>0) /*loop for the top 1/8th of circle*/
{
x=x-1; /*now you always move in x direction*/
rem=rem-x; /*and subtract x from the remainder*/
if (rem<0) /*when remainder underflows,*/
{

/*fill in the top side,*/
drawline(xc-x+cx, yc+y+cy,xc+x+cx,yc+y+cy,color,mode);
/*and the bottom*/
drawline(xc-x+cx,yc-y+cy,xc+x+cx,yc-y+cy,color,mode);
y=y+1;
rem=rem+y; /*bump the remainder back up*/
}
}
return;
}

x--- snip ---x

/* Copyright (C) Bill Buckels 2008 */

#include <poke.h>


/* the following function plots a pixel on the C64 using the currently
selected palette. It handles both of the standard videomodes;
HIRES and Multicolor. Since HIRES mode supports 2 colors, valid
color values are either 0 or 1.Multicolor mode (like the CGA on the
IBM-PC) has four colors; 0-3. */

plot(x,y,color,mode)
int x, y, color, mode;
{

/* mode 2 is MultiColor mode 160 pixels x 200 rasters x 1 bit */
/* mode 1 is HIRES mode 320 pixels x 200 rasters x 2 bits */

int c, ch, offset, row, column, temp;

/*
bmp = (char *)8192;
vram = (char *)1024;
cram = (char *)55296;

*/
/* we need to locate the 8 bit x 8 bit block that x and y refer to */
/* if in multi-color mode this is expressed in a 4 pixel x 8 bit block
*/

/* I am simplifying this by using an inclusive or */
/* get rid of whatever color was already there */
/* unless we are plotting a white pixel */

if (mode == 2) {
/* if we are in multicolor mode */
/* the matrix will be 4 pixels wide x 8 rasters deep */
row = y/8;
column = x/4;
y = y - (row * 8);
offset = (row * 320) + (column * 8) + y;

/* determine the pixel location in the byte */
x = 6 - ((x%4) * 2);
c = (3<<x);
if (color == 3) {
/* set the character at the raster */
temp = bmp[offset];
bmp[offset] = temp | c;
}
else {
/* get the character at the raster */
/* get rid of whatever color was already there */
temp = bmp[offset];

ch = (temp ^0xff) | c; /* reverse and unset pixel */
/* revert and set */
if (color == 1 || color == 2) bmp[offset] = (ch^0xff) | (color << x);
else bmp[offset] = (ch^0xff); /* revert */
}

}
else {
/* if we are in hires mode the matrix will be 8 pixels wide x 8 rasters
deep */
row = y/8;
column = x/8;
y = y - (row * 8);
offset = (row * 320) + (column * 8) + y;

/* determine the pixel location in the byte */
x = 7 - (x - (column * 8));
c = (1 << x);
/* set the character at the raster */
if (color == 1) {
temp = bmp[offset];
bmp[offset] = (temp | c);

}
else {
/* get the character at the raster */
/* get rid of whatever color was already there */
temp = bmp[offset];
ch = (temp ^0xff) | c; /* reverse and unset pixel */
bmp[offset] = (ch^0xff); /* revert */

}
}

}

x--- snip ---x

/* Copyright (C) Bill Buckels 2008 */

/* standard implementation of bresenham's */
drawline(x1,y1,x2,y2,color, mode)
int x1, y1, x2, y2, color, mode;
{
register int dx,dy,ix,iy;
int e,ei,ed,i;

dx=x2-x1;
dy=y2-y1;
ix=1;
if(dx<0)
{ ix=-1;
dx=-dx;
}
iy=1;
if(dy<0)
{ iy=-1;
dy=-dy;
}
if(dy>dx)
goto ylin;

ei=2*dy;
ed=ei-2*dx;
e=-dx+ei;
for(i=0;i<=dx;++i)
{
plot(x1,y1,color,mode);
x1=x1+ix;
if(e<0)
e=e+ei;
else{
y1=y1+iy;e=e+ed;
}
}
goto fin;

ylin:

ei=2*dx;
ed=ei-2*dy;
e=-dy+ei;
for(i=0;i<=dy;++i)
{
plot(x1,y1,color,mode);
y1=y1+iy;
if(e<0)
e=e+ei;
else{ x1=x1+ix;e=e+ed;}
}
fin:
;
}


daniel...@ucd.ie

unread,
Apr 9, 2009, 6:14:20 PM4/9/09
to
On Apr 9, 5:51 pm, Harry Potter <maspethro...@aol.com> wrote:
> How do I draw a filled, rotated or non-rotated circle on a graphics
> screen, especially with integers?

Just wondering what you mean by "rotated"? Isn't a rotated circle
still the same circle? Could you steal some routines from Simon's
Basic?

Mark McDougall

unread,
Apr 9, 2009, 7:19:55 PM4/9/09
to
daniel...@ucd.ie wrote:

> Just wondering what you mean by "rotated"? Isn't a rotated circle
> still the same circle? Could you steal some routines from Simon's
> Basic?

Maybe rotated about x or y axis... then you get an ellipse when projected
onto the Z axis.

--
| Mark McDougall | "Electrical Engineers do it
| <http://members.iinet.net.au/~msmcdoug> | with less resistance!"

Bill Buckels

unread,
Apr 9, 2009, 7:40:22 PM4/9/09
to

<daniel...@ucd.ie> wrote:

>Just wondering what you mean by "rotated"?

http://www.urbandictionary.com/define.php?term=rotated

Sam Gillett

unread,
Apr 10, 2009, 2:32:18 AM4/10/09
to

<daniel...@ucd.ie> wrote ...

Or maybe he could steal some routines from Commodore BASIC 7.0

The CIRCLE command can draw a circle, a rotated circle (ellipse), or even an
octagon, pentagon, diamond, or triangle. Then a routine could be borrowed
from the BOX command to fill the result.

Or maybe Harry could rip some code from a CAD program.
--
Best regards,

Sam Gillett

I saw Harry making crop circles,
But they turned out square!!

godot

unread,
Apr 10, 2009, 2:40:20 AM4/10/09
to

<daniel...@ucd.ie> schrieb im Newsbeitrag
news:e2054d60-b98f-4408...@b16g2000yqb.googlegroups.com...

> Could you steal some routines from Simon's Basic?

Simons' Basic uses sine and cosine algorithms and therefore is *way* longer
code. And also way slower (as you all know).


--
Arndt

GoDot C64 Image Processing
www.godot64.de


Mark McDougall

unread,
Apr 10, 2009, 3:09:22 AM4/10/09
to
Harry Potter wrote:

> How do I draw a filled, rotated or non-rotated circle on a graphics
> screen, especially with integers?

I had an integer algorithm years ago that I used to make a primitive
graphics library for Turbo Pascal on the TRS-80. I needed an integer
algorithm because I wrote it in Z80 assembler.

Try this...
<http://en.wikipedia.org/wiki/Midpoint_circle_algorithm>

You could probably fill it easily after you've drawn it using edge-detection?

Regards,

commod...@gmail.com

unread,
Apr 10, 2009, 3:13:31 AM4/10/09
to
Sam Gillett wrote:
> Or maybe he could steal some routines from Commodore BASIC 7.0
>
> The CIRCLE command can draw a circle, a rotated circle (ellipse), or even an
> octagon, pentagon, diamond, or triangle. Then a routine could be borrowed
> from the BOX command to fill the result.
If you want a filled circle, I'd think the fastest way would be the
"spans" method I read about when looking up information on the Quake
engine. Basically, for each Y position in the shape, you calculate the
minimum and maximum X position within the shape boundaries, then do a
horizontal line between those points; it works for any arbitrary
convex shape, and it's a whole lot faster than drawing the outline and
filling it. And, of course, on a multiple-pixels-per-byte screen like
the VIC's, you can do your lines by just doing the individual pixels
in the start and end bytes and "slabbing" in the rest with a series of
STAs.

daniel...@ucd.ie

unread,
Apr 10, 2009, 5:27:44 AM4/10/09
to
On Apr 10, 8:13 am, commodorej...@gmail.com wrote:
> If you want a filled circle, I'd think the fastest way would be the
> "spans" method I read about when looking up information on the Quake
> engine.

Don't know if you'll believe me but when I had a think about it, that
was the way I was thinking I'd go about it myself. I wonder do any of
the few filled polygon routines I've seen on the C64 (Space Rogue for
example) use something similar. The sums get fiendish for more than
one curve, i.e. 3 or 4 lines, I'd say.

@godot
Depends on how much speed you need I guess. On Simon's Basic, drawing
concentric circles would be much quicker anyway as the fill routine is
glacial.

godot

unread,
Apr 10, 2009, 9:37:17 AM4/10/09
to

<daniel...@ucd.ie> schrieb im Newsbeitrag
news:2e04e111-8d54-48cf...@37g2000yqp.googlegroups.com...

> @godot


> On Simon's Basic, drawing concentric circles would be
> much quicker anyway as the fill routine is glacial.

Really. As for the speed, I had a Bresenham CIRCLE in TSB (which is a
Simons' Basic rewrite), and you can compare the original speed to the
Bresenham one on this page (in the images, the text is only German):

http://www.c64-wiki.de/index.php/GRAPHICS_%28TSB%29 (fast)
http://www.c64-wiki.de/index.php/ANGL (slow)

The latter example shows for what sine and cosine are useful, anyway (see
the clock hands).

SB's fill is able of arbitrarily irregular shapes, though, as can be seen
here:

http://www.c64-wiki.de/index.php/BLOCK (just wait until the animation comes
to the fill part)

commod...@gmail.com

unread,
Apr 10, 2009, 9:45:48 AM4/10/09
to
daniel.oto...@ucd.ie wrote:
> Don't know if you'll believe me but when I had a think about it, that
> was the way I was thinking I'd go about it myself. I wonder do any of
> the few filled polygon routines I've seen on the C64 (Space Rogue for
> example) use something similar. The sums get fiendish for more than
> one curve, i.e. 3 or 4 lines, I'd say.
I wouldn't be surprised if that's how they did it. It's the most
efficient way to go about a filled-polygon routine that I can think
of, and the article I read didn't make it sound like it was a Quake-
specific innovation. I think the best way to keep the routine simple
would be to move down the shape from top to bottom, checking only the
two lines forming the current left and right edges of the shape, then
switching to a new left or right line as each one ends, since a
straight horizontal line across a convex shape can only intersect two
of the edges anyway.

daniel...@ucd.ie

unread,
Apr 10, 2009, 10:36:51 AM4/10/09
to
On Apr 10, 2:37 pm, "godot" <supp...@godot64.de> wrote:
> <daniel.oto...@ucd.ie> schrieb im Newsbeitragnews:2e04e111-8d54-48cf...@37g2000yqp.googlegroups.com...

>
> > @godot
> > On Simon's Basic, drawing concentric circles would be
> > much quicker anyway as the fill routine is glacial.
>
> Really.

Actually not really. I just tried it and it's waaaay faster by PAINT
routine. Oops. Is there a reason why SB fills vertically? I would have
thought horizontal would be faster?

Harry Potter

unread,
Apr 10, 2009, 11:45:09 AM4/10/09
to
On Apr 9, 9:51 am, Harry Potter <maspethro...@aol.com> wrote:
> How do I draw a filled, rotated or non-rotated circle on a graphics
> screen, especially with integers?

I can use the Pythagorean Theorem (spelling correct?) to calculate the
left and right end-points of a filled ellipse, but what about a
rotated filled ellipse? Also, what about using integers to calculate
the end-points? I need a SQR function to handle integers, but I don't
even know how to calculate it myself. I know of a way to do the same
with SIN and COS using Polynomial Approximations by multiplying the
numerators with the radius of the circle before factoring in the
denominators.

godot

unread,
Apr 10, 2009, 12:43:36 PM4/10/09
to
<daniel...@ucd.ie> schrieb im Newsbeitrag
news:12e8daa4-f6d1-4ff1...@k38g2000yqh.googlegroups.com...

>Is there a reason why SB fills vertically? I would have thought horizontal
>would be faster?

I'd think it's easier (and thus faster) to control the y-coordinate because
it doesn't go beyond 255. Btw SB works with tables to store the test
coordinates, TSB uses the stack (it's completely different).

Bill Buckels

unread,
Apr 11, 2009, 8:28:14 AM4/11/09
to
"Harry Potter" <maspet...@aol.com> wrote:

>I can use the Pythagorean Theorem (spelling correct?) to calculate the left
>and right end-points of a filled ellipse, but what about a rotated filled
>ellipse?

Solve your normal scenario first. By the way, I posted a disk algorithm
earlier. Why can't you apply an aspect scale and use this? Also for rotated
elements you may want to draw them first (in a buffer if necessary) then
rotate them as a bitmap around some axis point. Honestly, I can't remember
needing to create rotated ellipses to much degree and would wonder why you
are putting so much effort into this when you have so many other important
projects. I would suggest a general rotation algorithm if writing a paint
program, and to predraw and optimize your elements if writing some game and
stay away from vector graphics if you can.

Anyway, you could also apply something similar to the hands-on-a-clock
algorithm shown below with a suitable resolution.

This is taken from my Commodore 64 Version of "What Time Is It?" which comes
with the Aztec C64 cross-compiler for MS-DOS or Windows:

http://www.aztecmuseum.ca/compilers.htm#commodore

The Project itself is discussed in more detail here:

http://www.c64classics.ca/

Variations by me with source code can be found all over the internet for
Apple II and MS-DOS clock programs. Best to download at least one of them to
see how chording of circles might be accomplished in this manner.

Here's the core functions and you will note that the economy of scale is
applied to reduce this to a table of only 92 integers and a calculation
function :

/* a memory saving table for sine cosine */
/* we don't want to haul around an entire math library for */
/* the sake of 184 bytes of data and a parser function */

/* the divisor is 32767 (a signed int) */

int sine_cosine[46][2]={
0, 32767,/* 0 degree offset*/
571, 32762,/* 1 degree offset*/
1143, 32747,/* 2 degree offset*/
1714, 32722,/* 3 degree offset*/
2285, 32687,/* 4 degree offset*/
2855, 32642,/* 5 degree offset*/
3425, 32587,/* 6 degree offset*/
3993, 32522,/* 7 degree offset*/
4560, 32448,/* 8 degree offset*/
5125, 32363,/* 9 degree offset*/
5689, 32269,/* 10 degree offset*/
6252, 32164,/* 11 degree offset*/
6812, 32050,/* 12 degree offset*/
7370, 31927,/* 13 degree offset*/
7927, 31793,/* 14 degree offset*/
8480, 31650,/* 15 degree offset*/
9031, 31497,/* 16 degree offset*/
9580, 31335,/* 17 degree offset*/
10125,31163,/* 18 degree offset*/
10667,30981,/* 19 degree offset*/
11206,30790,/* 20 degree offset*/
11742,30590,/* 21 degree offset*/
12274,30381,/* 22 degree offset*/
12803,30162,/* 23 degree offset*/
13327,29934,/* 24 degree offset*/
13847,29696,/* 25 degree offset*/
14364,29450,/* 26 degree offset*/
14875,29195,/* 27 degree offset*/
15383,28931,/* 28 degree offset*/
15885,28658,/* 29 degree offset*/
16383,28377,/* 30 degree offset*/
16876,28086,/* 31 degree offset*/
17363,27787,/* 32 degree offset*/
17846,27480,/* 33 degree offset*/
18323,27165,/* 34 degree offset*/
18794,26841,/* 35 degree offset*/
19259,26509,/* 36 degree offset*/
19719,26168,/* 37 degree offset*/
20173,25820,/* 38 degree offset*/
20620,25464,/* 39 degree offset*/
21062,25100,/* 40 degree offset*/
21497,24729,/* 41 degree offset*/
21925,24350,/* 42 degree offset*/
22347,23964,/* 43 degree offset*/
22761,23570,/* 44 degree offset*/
23169,23169};/*45 degree offset*/


circlepoints(x,y,baselength,fdegrees)
int *x, *y;
int baselength;
float fdegrees;
{
float xtemp;
float ytemp;
int degrees = (int )fdegrees;
float aspect_h, aspect_v;

aspect_h = (float)1.16;
aspect_v = (float)1;

/* starting at 12 O'clock */
/* use a switch for the break */
switch(degrees)
{


default:

/* within range */
if(degrees<0 || degrees >359)degrees=0;

/* 0-45 sin */
if(degrees < 45)
{
xtemp = (float) sine_cosine[degrees][0];
ytemp = (float) sine_cosine[degrees][1];
ytemp = ytemp * -1;
break;
}

/* 45-90 cos */
if(degrees < 90)
{
xtemp = (float) sine_cosine[90-degrees][1];
ytemp = (float) sine_cosine[90-degrees][0];
ytemp = ytemp * -1;
break;
}

/* 90 - 135 */
if(degrees < 135)
{
xtemp = (float) sine_cosine[degrees-90][1];
ytemp = (float) sine_cosine[degrees-90][0];
break;
}

/* 135 - 180 */
if(degrees< 180)
{
xtemp = (float) sine_cosine[180-degrees][0];
ytemp = (float) sine_cosine[180-degrees][1];
break;
}

/* 180 - 225 */
if(degrees< 225)
{
xtemp = (float) sine_cosine[degrees-180][0];
xtemp = xtemp * -1;
ytemp = (float) sine_cosine[degrees-180][1];
break;
}

/* 225 - 270 */
if(degrees< 270)
{
xtemp = (float) sine_cosine[270-degrees][1];
xtemp = xtemp * -1;
ytemp = (float) sine_cosine[270-degrees][0];
break;
}

/* 270 - 315 */
if(degrees< 315)
{
xtemp = (float) sine_cosine[degrees-270][1];
xtemp = xtemp * -1;
ytemp = (float) sine_cosine[degrees-270][0];
ytemp = ytemp * -1;
break;
}

/* 315 - 360 */
xtemp = (float) sine_cosine[360-degrees][0];
xtemp = xtemp * -1;
ytemp = (float) sine_cosine[360-degrees][1];
ytemp = ytemp * -1;
}

ytemp = ytemp/32767;
xtemp = xtemp/32767;

xtemp *= (aspect_h*baselength);
ytemp *= (aspect_v*baselength);

*x += (int )xtemp;
*y += (int )ytemp;

}


Bill Buckels

unread,
Apr 11, 2009, 8:40:40 AM4/11/09
to

"Bill Buckels" <bbuc...@mts.net> wrote:

>By the way, I posted a disk algorithm earlier.

Here's an example of using the endpoints of a circle from my Win16 Lenslite
Screen Saver from ages ago(comes with source, just google VgaFan and Bill
Buckels):

// filled disk template structure - horizontal lines
typedef struct {
int x1;
int x2;
}DISK_STRUCT;

DISK_STRUCT disk_struct[LOGICAL_SIZE];

/* -------------------------------------------------------------------- */
/* add horizontal coordinates to a disk structure in memory */
/* helper function for BuildDisk Initialization Routine (below) */
/* -------------------------------------------------------------------- */
void HDisk(int y, int x1, int x2)
{
if (disk_struct[y].x1 == -1 || disk_struct[y].x1 > x1)
disk_struct[y].x1 = x1;
if (disk_struct[y].x2 == -1 || disk_struct[y].x2 < x2)
disk_struct[y].x2 = x2;
}

/* -------------------------------------------------------------------- */
/* BuildDisk */
/* precalculation routine - standard filled circle without floating pt. */
/* Creates a disk template structure in memory */
/* the disk structure consists of horizontal line vectors for start and */
/* end points of the specified disk size... this allows us to blit the */
/* portion of the scanline that fits within the disk by using a table */
/* reference instead of a calculated value which simplifies our actual */
/* calculations at run time... */
/* -------------------------------------------------------------------- */
void BuildDisk(int r)
{


int x,y; /*current point around 1/8 disk*/
int rem; /*remainder value*/

// initialize disk structure... make all values the same
// and make all values initially into unusable values...
for (y=0; y < LOGICAL_SIZE; y++) {
disk_struct[y].x1 = -1;
disk_struct[y].x2 = -1;
}

y=0;
x=r; /*initial point is on axis*/
rem=r/2; /*remainder=1/2 for roundoff*/
while (x>=y) /*loop for 1/8 of a circle*/
{
/*fill in top half of circle*/

HDisk(r+y,r-x,r+x);
/*and bottom half*/
HDisk(r-y,r-x,r+x);


y += 1; /*always increment y*/
rem=rem-y; /*subtract from remainder*/
if (rem<0) /*if it's time,*/
{
x=x-1; /*then decrement x*/
rem=rem+x; /*and bump remainder back up*/
}
}
while(x>0) /*loop for the top 1/8th of circle*/
{
x=x-1; /*now you always move in x direction*/
rem=rem-x; /*and subtract x from the remainder*/
if (rem<0) /*when remainder underflows,*/
{

/*fill in the top side,*/

HDisk(r+y,r-x,r+x);
/*and the bottom*/
HDisk(r-y,r-x,r+x);


y=y+1;
rem=rem+y; /*bump the remainder back up*/
}
}
return;
}

/* ---------------------------------------------------------------------- */
/* Blit a transparent disk onto the screen using the disk template */
/* to draw horizontal image lines */
/* ---------------------------------------------------------------------- */
void Disk(HWND hWnd, int xc, int yc, int r)
{
HDC hMemDC;
HBITMAP hbmOld;
int y, d, height, width;
int x1, y1;
int xoff;

if (hWorkBit == NULL) // must have a workbuffer
return; // try to avoid flicker by building
// a lens off screen...
hDC = GetDC(hWnd);
if (hDC == NULL)
return;

if (NULL != (hMemDC = CreateCompatibleDC(hDC))) {
hbmOld = SelectObject(hMemDC, hWorkBit);

d = (int)((wLiteLimit + LOGICAL_BUFFER) * 2);
if (bBlack == FALSE) {
// blacken the areas that we will not use first time thru...
BitBlt(hMemDC, 0, 0, d, d, hDCHidden, 0, 0, BLACKNESS);
bBlack = TRUE;
}

// build the lens in memory
y1 = yc - r;
x1 = xc - r;
height = (int)(wLiteLimit * 2);
xoff = NIL;
for (y = 0; y < height; y++) {
if (disk_struct[y].x1 == disk_struct[y].x2)
continue;
width = (disk_struct[y].x2 - disk_struct[y].x1) + 1;
if (!bFocus )
xoff = disk_struct[y].x1; // warp to curve on x-axis

// line by line
BitBlt(hMemDC, disk_struct[y].x1 + LOGICAL_BUFFER,
y + LOGICAL_BUFFER, width, 1,
hDCHidden, x1 + xoff,
y1 + y, SRCCOPY);
}

// do it - blit the finished lens on screen
BitBlt(hDC, x1-LOGICAL_BUFFER, y1 - LOGICAL_BUFFER,
d, d, hMemDC, 0, 0, SRCCOPY);

SelectObject(hMemDC, hbmOld); // make sure we don't
DeleteDC(hMemDC); // exhaust all resources
}

ReleaseDC(hWnd, hDC);
return;
}


5k3105

unread,
Apr 19, 2009, 12:06:44 PM4/19/09
to
Use BLARG http://www.ffd2.com/fridge/programs/blarg/blarg.docs

http://www.ffd2.com/fridge/

http://www.ffd2.com/fridge/chacking/

http://www.ffd2.com/fridge/chacking/c=hacking9.txt

"2D Graphics Toolbox -- Circles", Stephen Judd. An awfully neat circle
drawing algorithm, if I do say so myself. (See also issue 10 or 11).

http://www.ffd2.com/fridge/chacking/c=hacking10.txt

"A Different Perspective, part III", by two old bums. Neat-o line
drawing enhancement, general polygon routine, general hidden face
removal, alternative filling method, and a misplaced and important
addendum to the Circle routine in issue 9.

http://www.ffd2.com/fridge/chacking/c=hacking11.txt

"The Graphics Toolbox: Ellipses", Stephen L. Judd. Follow-up to the
circle drawing algorithm, logarithmic division.


http://www.ffd2.com/fridge/discovery/

http://www.ffd2.com/fridge/discovery/issue3.gz

Issue #3

* "Rommaging around : $A480-$A856", Stephen Judd. Disassembly and
discussion of the BASIC intrepeter, and BLARG.

Bill Buckels

unread,
Apr 19, 2009, 12:53:11 PM4/19/09
to

"5k3105" <christi...@yahoo.com> wrote:

>Use BLARG

There's a thought:) Wonder what kind of a graphics screen he wants to draw
upon and what computer language he wants to write in? The guy just trolls in
and out. Regardless the links are great so as you say, what the heck!

Bill


5k3105

unread,
Apr 19, 2009, 1:17:24 PM4/19/09
to
On Apr 19, 11:53 am, "Bill Buckels" <bbuck...@mts.net> wrote:

> "5k3105" <christianlo...@yahoo.com> wrote:
> >Use BLARG
>
> There's a thought:) Wonder what kind of a graphics screen he wants to draw
> upon and what computer language he wants to write in?

Probably PETSCII graphics in BASIC ;) Talk about overkill...


0 new messages