# Plot a Circle

5 replies to this topic

### #1 boski OFFLINE

boski

• 26 posts
• Location:Janesville, WI

Posted Sat Mar 18, 2017 4:34 PM

I want my sprites to essentially orbit the center of the screen. That means I need to be able to plot a circle to calculate the sprite's x,y coordinates, which will be constantly changing. Does anyone know how to do this?

### #2 bogax OFFLINE

bogax

Dragonstomper

• 731 posts

Posted Mon Mar 20, 2017 6:55 PM

here's one that uses a sine table

```

dim angle = a.c
dim tangle = temp1

angle = 0

gosub su

loop

temp3 = sine(angle)
temp3 = scl(temp3)

player0x = temp3 + 37

temp3 = angle - 64
temp3 = sine(temp3)
temp3 = scl(temp3)
player0y = temp3 + 7

angle = angle + 1.0

COLUP0 = \$3A
COLUP1 = \$14
drawscreen
goto loop

;  multiply by .328125 so scales 255 -> 83
function scl
asm
lda temp1
lsr
lsr
ror
lsr
ror
lsr
rts
end

function sine
temp2 = tangle
if tangle{6} then temp2 = temp2 ^ %00111111  ; if its an odd quadrant complement the angle in 64 (64 is one quadrant)
temp2 = (temp2 & %00111111)                  ; scale to index table 0..63 /2 for 32 elements /4 for 16 elements
temp2 = sinetbl[temp2]/2
if tangle{7} then temp2 = 255 - temp2        ; if the angle is greater than 128 then complement the sine in 128
temp2 = temp2 + 128                          ; add an offset so the sine is 0..255 no negatives
return

;  data sinetbl
;    0,  50,  74,  98, 121, 142, 162, 181
;  198, 213, 226, 237, 245, 251, 255, 255
;end

;  data sinetbl
;    0,  25,  37,  50,  62,  74,  86,  98
;  109, 120, 131, 142, 152, 162, 171, 180
;  189, 197, 205, 212, 219, 225, 231, 236
;  240, 244, 247, 250, 252, 254, 255, 255
;end

data sinetbl
0,  13,  19,  25,  31,  38,  44,  50
56,  62,  68,  74,  80,  86,  92,  98
104, 109, 115, 121, 126, 132, 137, 142
147, 152, 157, 162, 167, 172, 177, 181
185, 190, 194, 198, 202, 206, 209, 213
216, 220, 223, 226, 229, 231, 234, 237
238, 241, 243, 245, 247, 248, 250, 251
252, 253, 254, 255, 255, 255, 255, 255
end

su

player0:
%00000000
%00000000
%00011000
%00111100
%00111100
%00011000
%00000000
%00000000
end

player1:
%00111100
%01111110
%11111111
%11111111
%11111111
%11111111
%01111110
%00111100
end

COLUPF = \$48

player1x = 80
player1y = 48

return

```

here's one that uses a smaller sine table to form a circle from a set of line segments

```

dim angle = a.c
dim tangle = temp1

angle = 0

gosub su

loop

temp3 = sine(angle)
x = x + temp3
player0x = scl(x)
player0x = player0x + 39

temp3 = angle + 64
temp3 = sine(temp3)
y = y + temp3
player0y = scl(y)
player0y = player0y + 6

angle = angle + 1.0

COLUP0 = \$3A
COLUP1 = \$14
drawscreen
goto loop

;  multiply by .328125 so scales 255 -> 83
function scl
asm
lda temp1
lsr
lsr
ror
lsr
ror
lsr
rts
end

function sine
temp2 = tangle & %00111111
if tangle{6} then temp2 = 64 - temp2         ; if its an odd quadrant complement the angle in 64 (64 is one quadrant)
temp2 = (temp2 & %00111111)/8                ; scale to index table 0..63 -> 0..7
temp2 = sinetbl[temp2]
if tangle{7} then temp2 = 0 - temp2          ; if the angle is greater than 128 then negate
temp2 = temp2
return

data sinetbl
0,   1,  1,  2,  2,  3,  3,  3
end

su

player0:
%00000000
%00000000
%00011000
%00111100
%00111100
%00011000
%00000000
%00000000
end

player1:
%00111100
%01111110
%11111111
%11111111
%11111111
%11111111
%01111110
%00111100
end

COLUPF = \$48

x = 0 : y = 128 : angle = 0

player1x = 80
player1y = 48

return

```

here's one that uses a parabolic aproximation of sines-cosines
if you look closely you'll see it's actually sort of elliptical

```
dim dx = v
dim dy = w

gosub su

loop

c = c + 1

if c & 7 then skip

if x{7} then dx = dx - 1 else dx = dx + 1
x = x + dx

player0x = scl(x)
player0x = player0x + 34

if y{7} then dy = dy - 1 else dy = dy + 1
y = y + dy

player0y = scl(y)
player0y = player0y + 2

skip

COLUP0 = \$3A
COLUP1 = \$14
drawscreen
goto loop

;  multiply by .34375 so scales 247 -> 84
function scl
asm
lda temp1
lsr
ror
lsr
ror
lsr
rts
end

su

player0:
%00000000
%00000000
%00011000
%00111100
%00111100
%00011000
%00000000
%00000000
end

player1:
%00111100
%01111110
%11111111
%11111111
%11111111
%11111111
%01111110
%00111100
end

COLUPF = \$48

dx = \$0E : x = \$7F
dy = \$00 : y = \$F7

player1x = 80
player1y = 46

return

```

#### Attached Files

• Random Terrain , SpiceWare and The Maxx like this

### #3 bogax OFFLINE

bogax

Dragonstomper

• 731 posts

Posted Tue Mar 21, 2017 6:22 PM

I forgot to mention that in the case of the line segment circle

the table is matched to the number of steps in the circle so if you change the number of steps

the circle changes

it will get larger or smaller and if things don't add up just right it will probably wobble

### #4 boski OFFLINE

boski

• Topic Starter
• 26 posts
• Location:Janesville, WI

Posted Tue Mar 21, 2017 7:05 PM

Thank you very much for your help! I've already learned a lot just playing around with the code. I'm sure this will help a lot of other people too. Just one more question - how can I change the radius in circle one? It seems like I'd need to change the code in more than one spot to keep it even.

### #5 bogax OFFLINE

bogax

Dragonstomper

• 731 posts

Posted Sat Mar 25, 2017 11:33 AM

the sine table is built on the (possibly) spurious theory
throw away what you don't need
so the sines are 0..255 and which would give you
sines -255..255
the sine function immediately throws some of that away and
returns sines that range 0..255
those values are scaled to fit by multiplying by the
reciprocal of the scale factor
that's what the scl function does

if you just want a different radius that can be baked into
the sine table

```

dim angle = a.c
dim tangle = temp1

angle = 0

gosub su

loop

temp1 = angle/4
player0x = sinetbl[temp1] + 42

temp1 = (angle - 64)/4
player0y = sinetbl[temp1] + 7

angle = angle + 0.5

COLUP0 = \$3A
COLUP1 = \$14
drawscreen
goto loop

data sinetbl
38,  42,  45,  49,  53,  56,  59,  62
65,  67,  70,  72,  73,  74,  75,  76
76,  76,  75,  74,  73,  72,  70,  67
65,  62,  59,  56,  53,  49,  45,  42
38,  34,  31,  27,  23,  20,  17,  14
11,   9,   6,   4,   3,   2,   1,   0
0,   0,   1,   2,   3,   4,   6,   9
11,  14,  17,  20,  23,  27,  31,  34
end

su

player0:
%00000000
%00000000
%00011000
%00111100
%00111100
%00011000
%00000000
%00000000
end

player1:
%00111100
%01111110
%11111111
%11111111
%11111111
%11111111
%01111110
%00111100
end

COLUPF = \$48

player1x = 80
player1y = 48

return

```

if you want to vary the radius on the fly probably the easiest way is to
scale the sines to suit

here the sines are scaled using an approximate reciprocal calulated from

you can vary the radius from 4..40 using joy0 up-down

none of it is very accurate
the sine table is not very accurate
the scl function is not very accurate
and the reciprocal approximation is not very accurate

```

dim angle = a.c
dim tangle = temp1

angle = 0

gosub su

dim num = temp1
dim mul = temp2

r = 20

loop

f = (SWCHA ^ \$FF) & f
if f{4} then r = r + 1 : if r > 40 then r =  4
if f{5} then r = r - 1 : if r <  4 then r = 40
f = SWCHA

temp1 = angle/4
temp1 = sinetbl[temp1]
temp2 = r * 2
temp1 = scl(temp1,temp2)
player0x = temp1 + 80 - r

temp1 = (angle - 64)/4
temp1 = sinetbl[temp1]
temp2 = r * 2
temp1 = scl(temp1,temp2)
player0y = temp1 + 48 - r

angle = angle + 0.5

COLUP0 = \$3A
COLUP1 = \$14
drawscreen
goto loop

;  multiply by .328125 so scales 255 -> 83
function scl
asm
lda #\$00
sec
ror mul
loop
bcc shift
shift
ror
enter
lsr mul
bne loop
rts
end

data sinetbl
127, 139, 151, 163, 175, 186, 197, 207
216, 225, 232, 239, 244, 248, 251, 253
253, 253, 251, 248, 244, 239, 232, 225
216, 207, 197, 186, 175, 163, 151, 139
126, 114, 102,  90,  78,  67,  56,  46
37,  28,  21,  14,   9,   5,   2,   0
0,   0,   2,   5,   9,  14,  21,  28
37,  46,  56,  67,  78,  90, 102, 114
end

su

player0:
%00000000
%00000000
%00011000
%00111100
%00111100
%00011000
%00000000
%00000000
end

player1:
%00111100
%01111110
%11111111
%11111111
%11111111
%11111111
%01111110
%00111100
end

COLUPF = \$48

player1x = 80
player1y = 48

return

```

#### Attached Files

Edited by bogax, Sat Mar 25, 2017 11:35 AM.

### #6 boski OFFLINE

boski

• Topic Starter
• 26 posts
• Location:Janesville, WI

Posted Sun Mar 26, 2017 6:33 PM

Thank you very much! This will keep me busy for a while!

#### 0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users