Jump to content
IGNORED

Plot a Circle


boski

Recommended Posts

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
adc temp1
ror
lsr
adc temp1
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
adc temp1
ror
lsr
adc temp1
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
adc temp1
ror
lsr
adc temp1
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




circle.bas

circle.bas.bin

circle2.bas

circle2.bas.bin

circle3.bas

circle3.bas.bin

  • Like 3
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites


the sine table is built on the (possibly) spurious theory

that it's good to start with the best accuracy and then

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

the radius


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
adc num
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

circle64_baked.bas

circle64_baked.bin

circle64_scaled.bas

circle64_scaled.bin

Edited by bogax
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...