Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Rotating some points , seems slow
#1
I was going to make a vector graphics game like asteroids but different
I rotated some points around an origin but even that seems too slow

I was going to draw lines between the points


Code:
#include <FSin.bas> Dim trishipx(12) as UByte Dim trishipy(12) as UByte Dim drawtrishipx(12) as UByte dim drawtrishipy(12) as UByte trishipx(0)=62 trishipy(0)=58 trishipx(1)=58 trishipy(1)=58 trishipx(2)=58 trishipy(2)=62 trishipx(3)=58 trishipy(3)=54 trishipx(4)=60 trishipy(4)=58 trishipx(5)=60 trishipy(5)=62 Dim trishipangle as Integer Function rotate(degrees as Integer) as Integer dim transformedX as Ubyte=0 dim transformedY as ubyte=0 dim pointx as Ubyte=54 dim pointy as Ubyte=54 for x=0 to 5 'Local theta:Float=1 transformedX= fCos(degrees) * (trishipx(x)-pointx) - fSin(degrees) * (trishipy(x)-pointy) + pointx transformedY = fSin(degrees) * (trishipx(x)-pointx) + fCos(degrees) * (trishipy(x)-pointy) + pointy drawtrishipx(x) = transformedX drawtrishipy(x) = transformedY Next return 1 End Function Function drawship() as Integer for x=0 to 5 plotPoint(drawtrishipx(x),drawtrishipy(x)) next return 1 End Function While 1 trishipangle=trishipangle+1 if trishipangle>360 then trishipangle=0 end if rotate(trishipangle) drawship() Wend SUB plotPoint (x as uByte, y as uByte) ASM ld d,(IX+5) ;'X ld e,(IX+7) ;'Y ld a, 191 sub e ret c ld e, a and a rra scf rra and a rra xor e and 248 xor e ld h, a ld a, d rlca rlca rlca xor e and 199 xor e rlca rlca ld l, a ld a, d and 7 ld b, a inc b ld a, 1 plotPoint_loop: rrca djnz plotPoint_loop ;cpl ld b, a ld a, (hl) or b ld (hl), a END ASM END SUB
Reply
#2
slenkar Wrote:I was going to make a vector graphics game like asteroids but different
I rotated some points around an origin but even that seems too slow

I was going to draw lines between the points
There is little you can do in your code, I guess. Some tips:

  1. Not a huge optimization, but more elegant: initialize the trishipx array directly
  2. Most of the demos I know cache all pre-calculated values in a table. So do something like DIM fSIN(360) As Fixed might be a good idea.
  3. The above might be even faster if you use PEEK instead of array access.
  4. The lines in the fsin / fcos degree calculates twice these values.

For the last point, consider:
Code:
transformedX= fCos(degrees) * (trishipx(x)-pointx) - fSin(degrees) * (trishipy(x)-pointy) + pointx transformedY = fSin(degrees) * (trishipx(x)-pointx) + fCos(degrees) * (trishipy(x)-pointy) + pointy
To be rewritten as
Code:
Dim fc, fs, tx, ty As Fixed fc = fCos(degrees) fs = fSin(degrees) tx = trishipx(x) - pointx ty = trishipy(x) - pointy transformedX= fc * tx - fs * ty + pointx transformedY = fs * tx + fc * ty + pointy
And remember that variables declared (DIMed) within a function have slower access. This is because they are relative to the stack pointer (IX). Global variables are much faster. At the moment the compiler does not support static variables. :oops:

Maybe Britlion can give you more suggestions, as he is an optimization expert Tongue
Reply
#3
thanks I put fsin and fcos into arrays and now a circle completes in a few seconds as opposed to a few minutes
Reply
#4
slenkar Wrote:thanks I put fsin and fcos into arrays and now a circle completes in a few seconds as opposed to a few minutes


Wow. Really?

I mean...that's basically how Fsin works in the first place. I'm surprised it's possible to optimize it that massively!

(You are using <!-- m --><a class="postlink" href="http://www.boriel.com/wiki/en/index.php/ZX_BASIC:FSin.bas">http://www.boriel.com/wiki/en/index.php ... C:FSin.bas</a><!-- m --> yes?)
Reply
#5
Awesome :!: Confusedhock:

BTW I implemented CIRCLE using bresenham's algorithm. It does not use neither SIN nor COS but integer aritmethic (Try CIRCLE command).
Maybe you could use that to rotate your triangle in some way :?:
Reply
#6
yeah im using that FSin cos it seemed to be the fastest(?)

here is a little demo of the dots being rotated, it makes a nice picture too

<!-- m --><a class="postlink" href="http://www.4shared.com/file/VKojb8gm/rotate.html">http://www.4shared.com/file/VKojb8gm/rotate.html</a><!-- m -->
there is a delay at the beginning while the FSin values are calculated


interesting point about the circle command...
Reply
#7
slenkar Wrote:yeah im using that FSin cos it seemed to be the fastest(?)

here is a little demo of the dots being rotated, it makes a nice picture too

<!-- m --><a class="postlink" href="http://www.4shared.com/file/VKojb8gm/rotate.html">http://www.4shared.com/file/VKojb8gm/rotate.html</a><!-- m -->
there is a delay at the beginning while the FSin values are calculated
interesting point about the circle command...
Keep in mind that Circle only computes 1/4 of the circle. The other 3 quarters are just calculated by reflection Wink
For drawing circles, I think you should definitely use CIRCLE (both CIRCLE & DRAW are heavily optimized, they don't use the ROM routines at all - ok, just bragging, but it took me a lot of time :roll: ).

On the other hand, I you want circle coords for other purposes (e.g. calc coordinates in a trajectory), maybe you should have a look at library-asm/circle.asm Wink
The bresenham circle algorithm is described here: <!-- m --><a class="postlink" href="http://en.wikipedia.org/wiki/Midpoint_circle_algorithm">http://en.wikipedia.org/wiki/Midpoint_circle_algorithm</a><!-- m --> (the C routine under the "Optimization section").
Reply
#8
im drawing lines between the points now (with DRAW Smile )
but they seem to go up and right for some reason,

here is the code

triship arrays are two dimensional, one dimension for which ship it refers to
and the other dimension for the points

Code:
#include <FSin.bas> #include <SP/Fill.bas> Dim fsinarray(361) as Fixed for iter=0 to 360 fsinarray(iter)=fSin(iter) next Dim fcosarray(361) as Fixed for iter=0 to 360 fcosarray(iter)=fCos(iter) next Dim trishipx(2,12) as UByte Dim trishipy(2,12) as UByte Dim drawtrishipx(2,12) as UByte dim drawtrishipy(2,12) as UByte Dim fc, fs, tx, ty As Fixed trishipx(0,0)=62 trishipy(0,0)=58 trishipx(0,1)=58 trishipy(0,1)=58 trishipx(0,2)=58 trishipy(0,2)=62 trishipx(0,3)=58 trishipy(0,3)=54 trishipx(0,4)=60 trishipy(0,4)=58 trishipx(0,5)=60 trishipy(0,5)=62 trishipx(1,0)=162 trishipy(1,0)=158 trishipx(1,1)=158 trishipy(1,1)=158 trishipx(1,2)=158 trishipy(1,2)=162 trishipx(1,3)=158 trishipy(1,3)=154 trishipx(1,4)=160 trishipy(1,4)=158 trishipx(1,5)=160 trishipy(1,5)=162 Dim trishipangle as Integer Function rotate(degrees as Integer) as Integer dim pointx as Ubyte dim pointy as Ubyte for trishipiter =0 to 1 if trishipiter=0 then pointx=54 pointy=54 end if if trishipiter=1 then pointx=100 pointy=100 end if if trishipiter=2 then pointx=154 pointy=54 end if for x=0 to 5 'Local theta:Float=1 fc = fcosarray(degrees) fs = fsinarray(degrees) tx = trishipx(trishipiter,x) - pointx ty = trishipy(trishipiter,x) - pointy drawtrishipx(trishipiter,x)= fc * tx - fs * ty + pointx drawtrishipy(trishipiter,x)= fs * tx + fc * ty + pointy 'transformedX= fCos(degrees) * (trishipx(x)-pointx) - fSin(degrees) * (trishipy(x)-pointy) + pointx 'transformedY = fSin(degrees) * (trishipx(x)-pointx) + fCos(degrees) * (trishipy(x)-pointy) + pointy Next next return 1 End Function Function drawship() as Integer for trishipiter=0 to 1 for x=0 to 5 'plotPoint(drawtrishipx(trishipiter,x),drawtrishipy(trishipiter,x)) if x<5 then PLOT drawtrishipx(trishipiter,x), drawtrishipy(trishipiter,x) DRAW drawtrishipx(trishipiter,x+1), drawtrishipy(trishipiter,x+1) end if if x=5 then PLOT drawtrishipx(trishipiter,x), drawtrishipy(trishipiter,x) DRAW drawtrishipx(trishipiter,0), drawtrishipy(trishipiter,0) end if next next return 1 End Function While 1 CLS trishipangle=trishipangle+1 if trishipangle>360 then trishipangle=0 end if 'for x=0 to 5 'plotPoint(drawtrishipx(x),drawtrishipy(x)) 'next rotate(trishipangle) drawship() Wend SUB plotPoint (x as uByte, y as uByte) ASM ld d,(IX+5) ;'X ld e,(IX+7) ;'Y ld a, 191 sub e ret c ld e, a and a rra scf rra and a rra xor e and 248 xor e ld h, a ld a, d rlca rlca rlca xor e and 199 xor e rlca rlca ld l, a ld a, d and 7 ld b, a inc b ld a, 1 plotPoint_loop: rrca djnz plotPoint_loop ;cpl ld b, a ld a, (hl) or b ld (hl), a END ASM EDIT- after drawing my own lines I could draw a rotating part of a spaceship (featuring britlions fill routine) http://www.4shared.com/file/DLgxB2PY/rotate_1.html looks like it will have to be...turn based spaceship combat END SUB
Reply
#9
I tried drawing my own lines and now I can draw part of a rotating spaceship
(also featuring britlions fill routine)
<!-- m --><a class="postlink" href="http://www.4shared.com/file/DLgxB2PY/rotate_1.html">http://www.4shared.com/file/DLgxB2PY/rotate_1.html</a><!-- m -->

turn based spaceship battles ahoy
Reply
#10
slenkar Wrote:I was going to make a vector graphics game like asteroids but different
I rotated some points around an origin but even that seems too slow
Sorry. Didn't read this msg yesterday. This could be a bug. Will have a look.
Also, Draw routines uses Integer values (Byte / Ubyte / Uinteger will overflow).

Let me check it...
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)