Jump to content

Photo

Plot a Circle


3 replies to this topic

#1 boski OFFLINE  

boski

    Space Invader

  • 15 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

  • 692 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
  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
 
 
 

Attached Files



#3 bogax OFFLINE  

bogax

    Dragonstomper

  • 692 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

    Space Invader

  • Topic Starter
  • 15 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.






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users