Jump to content

Photo

How to have an object move in a circle


6 replies to this topic

#1 BNE Jeff OFFLINE  

BNE Jeff

    Moonsweeper

  • 286 posts
  • Location:Virginia, USA

Posted Thu Aug 25, 2016 2:38 AM

Good Morning..

 

If I want to have an object move in a circle, what's the best way to accomplish that?  Can a circle be calculated?  Plotted points on a table?  Something else?



#2 GroovyBee OFFLINE  

GroovyBee

    Games Developer

  • 9,736 posts
  • Busy bee!
  • Location:North, England

Posted Thu Aug 25, 2016 2:43 AM

Use the "C" code from here :-

 

https://en.wikipedia...ircle_algorithm

 

To generate a table of coordinates at the X, Y position and radius you need.



#3 bogax OFFLINE  

bogax

    Dragonstomper

  • 704 posts

Posted Sat Aug 27, 2016 8:28 AM

Use the "C" code from here :-

 

https://en.wikipedia...ircle_algorithm

 

To generate a table of coordinates at the X, Y position and radius you need.

 

Presumably you wont be putting a table in RAM

There are easier ways to generate a table to put in ROM

 

If you mean generating positions on the fly then since you always move one step

in the major direction and sometimes move 0 steps or 1 step in the other direction

I think your speed would vary depending on the angle.

 

If you take 1 pixel in 160 as the minimum tangent ie you're moving in an arc such that

you move eg 160 pixels in the x direction and 1 pixel in the y direction

that's about .36 degrees or about 1/1000 of a circle

if you use a 1 quadrant sine table with linear interpolation and 8 steps per table entry

that's a table with 1000 / ( 4 * 8 ) = ~32 entries

 

But of course you'd use some code (and cycles) doing interpolation and scaling and such

 

That is to say I don't think a sine table itself would take much

whether or not it would be faster or smaller overall would depend on exactly what

you needed to do with it (and you'd still have to determine octants and stuff with

a Bresenham's type algorithm)


Edited by bogax, Sat Aug 27, 2016 8:36 AM.


#4 DanOliver OFFLINE  

DanOliver

    Moonsweeper

  • 333 posts
  • Location:Phoenix AZ

Posted Sat Aug 27, 2016 9:35 AM

Table...simple table. Assuming radius never changes. You can use the math if you want, I wouldn't bother. For example, start with an X,Y table that moves the sprite in a square, pretty easy, radius of say 5 pixels the table might be:

 

{0,-5} , // N

{5,-5} , // NE

{5,0} , // E

{5,5} , // SE

{0,5} , // S

{-5,5} , // SW

{-5,0} , // W

{-5,-5} , // NW

 

Assume bugs in the table, but you get the idea hopefully. The position of the sprite is the center, add each X,Y from the table to get the screen position.

 

To change from a square to a circle you add more entries in the table, 2 entries each for NE,SE,SW,NW while N,E,S,W remain the same. You can use some match if you like, but really you're dealing with low res here so you're only option is 4 instead of 5. See how it looks on screen and tweak as needed. Bigger the circle the smoother the movement because this is all low res.

 

For smaller circles, if you really wanted to get tricky, you might be able to change the sprite art as it goes around to make it look smoother. Depends on the shape you have to work with. I wouldn't bother probably.

 

There's the way you're suppose to do things and there's the getting it done way.


Edited by DanOliver, Sat Aug 27, 2016 9:35 AM.


#5 BNE Jeff OFFLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 286 posts
  • Location:Virginia, USA

Posted Sun Aug 28, 2016 8:55 AM

Table...simple table. Assuming radius never changes. You can use the math if you want, I wouldn't bother. For example, start with an X,Y table that moves the sprite in a square, pretty easy, radius of say 5 pixels the table might be:

 

{0,-5} , // N

{5,-5} , // NE

{5,0} , // E

{5,5} , // SE

{0,5} , // S

{-5,5} , // SW

{-5,0} , // W

{-5,-5} , // NW

 

OK thanks everybody :)

 

I'm not sure which way to go.

 

I am planning on other movements besides a circle so this might be the way to go.  I can plug in any shape I want this way- correct?

 

The alternative which is scalable is:

 

I don't really need to plot a circle.  I just need to have a position and a bearing for each move I make.

 

The bearing will point to a table which contains proportions of moves that correspond to a full move along the other coordinate for 1/8th of a circle.

 

These results will be translated into the closest matching coordinates for display.

 

Hmm...



#6 BNE Jeff OFFLINE  

BNE Jeff

    Moonsweeper

  • Topic Starter
  • 286 posts
  • Location:Virginia, USA

Posted Sun May 21, 2017 1:44 PM

Does this code get me where I want to go?  It looks like when you call it, it puts a sine and cosine in the accumulator and x register.  I enjoyed most on my math classes in high school and college, but not trig so I'm not sure if its of value to me. I'll still need to plot a point- right? Note:  I'm also interested in plotting a circle so this looks like it might help with that too.  My questions in the comments are preceded by "???"s

 

Thanks-

-Jeff

;----------------------------------------------------------------
;
; SIN(A) COS(A) routines. a full circle is represented by $00 to
; $00 in 256 1.40625 degree steps. returned value is signed 15
; bit with X being the high byte and ranges over +/-0.99997

;----------------------------------------------------------------
;
; get COS(A) in AX
; ??? What is AX?  Accumulator and X reg?

cos_A
      CLC                     ; clear carry for add
      ADC   #$40              ; add 1/4 rotation (decimal 64)
; ??? What was in the accumulator- presume 0?

;----------------------------------------------------------------
;
; get SIN(A) in AX. enter with flags reflecting the contents of A


sin_A
      BPL   sin_cos           ; just get SIN/COS and return if +ve

      AND   #$7F              ; else make +ve
      JSR   sin_cos           ; get SIN/COS
                              ; now do twos complement
      EOR   #$FF              ; toggle low byte
      CLC                     ; clear carry for add
      ADC   #$01              ; add to low byte
      PHA                     ; save low byte
      TXA                     ; copy high byte
      EOR   #$FF              ; toggle high byte
      ADC   #$00              ; add carry from low byte
      TAX                     ; copy back to X
      PLA                     ; restore low byte
      RTS

;----------------------------------------------------------------
;
; get AX from SIN/COS table

sin_cos
      CMP   #$41              ; compare with max+1 (65 decimal.)
      ;??? What does max mean?
      BCC   quadrant          ; branch if less

      EOR   #$7F              ; wrap $41 to $7F ..
      ADC   #$00              ; .. to $3F to $00
quadrant
      ASL                     ; * 2 bytes per value
      TAX                     ; copy to index
      LDA   sintab,X          ; get SIN/COS table value low byte
      PHA                     ; save it  (Push on stack)
      LDA   sintab+1,X        ; get SIN/COS table value high byte
      TAX                     ; copy to X
      PLA                     ; restore low byte
      RTS

;----------------------------------------------------------------
;
; SIN/COS table. returns values between $0000 and $7FFF
; ??? How is it both SIN&COS?


sintab
      .word $0000,$0324,$0647,$096A,$0C8B,$0FAB,$12C8,$15E2
      .word $18F8,$1C0B,$1F19,$2223,$2528,$2826,$2B1F,$2E11
      .word $30FB,$33DE,$36BE,$398C,$3C56,$3F17,$41CE,$447A
      .word $471C,$49B4,$4C3F,$4EBF,$5133,$539B,$55F5,$5842
      .word $5A82,$5CB4,$5ED7,$60EC,$62F2,$64EB,$66CF,$68A6
      .word $6A6D,$6C24,$6DC4,$6F5F,$70E2,$7255,$73B5,$7504
      .word $7641,$776C,$7884,$798A,$7A7D,$7B5D,$7C2A,$7CE3
      .word $7D8A,$7E1D,$7E9D,$7F09,$7F62,$7FA7,$7FD8,$7FF6
      .word $7FFF
; (65 values)

;----------------------------------------------------------------


#7 G-type OFFLINE  

G-type

    Chopper Commander

  • 193 posts

Posted Mon Jun 5, 2017 7:59 AM

Another method that occured to me.. is player graphics can slide along walls if you convert their positions to playfield pixel coordinates... maybe you could make a playfield graphic in a circle shape and hide it by making it the same color as the background.






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users