Rotating some points , seems slow - Printable Version +- Forum (https://www.boriel.com/forum) +-- Forum: Compilers and Computer Languages (https://www.boriel.com/forum/forumdisplay.php?fid=12) +--- Forum: ZX Basic Compiler (https://www.boriel.com/forum/forumdisplay.php?fid=11) +---- Forum: Help & Support (https://www.boriel.com/forum/forumdisplay.php?fid=16) +---- Thread: Rotating some points , seems slow (/showthread.php?tid=535) Rotating some points , seems slow - slenkar - 04-08-2013 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 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``` Re: Rotating some points , seems slow - boriel - 04-08-2013 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 pointsThere is little you can do in your code, I guess. Some tips: Not a huge optimization, but more elegant: initialize the trishipx array directly 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. The above might be even faster if you use PEEK instead of array access. 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 Re: Rotating some points , seems slow - slenkar - 04-08-2013 thanks I put fsin and fcos into arrays and now a circle completes in a few seconds as opposed to a few minutes Re: Rotating some points , seems slow - britlion - 04-10-2013 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 http://www.boriel.com/wiki/en/index.php ... C:FSin.bas yes?) Re: Rotating some points , seems slow - boriel - 04-10-2013 Awesome :!: hock: 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 :?: Re: Rotating some points , seems slow - slenkar - 04-10-2013 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 http://www.4shared.com/file/VKojb8gm/rotate.html there is a delay at the beginning while the FSin values are calculated interesting point about the circle command... Re: Rotating some points , seems slow - boriel - 04-10-2013 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 http://www.4shared.com/file/VKojb8gm/rotate.html 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 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 The bresenham circle algorithm is described here: http://en.wikipedia.org/wiki/Midpoint_circle_algorithm (the C routine under the "Optimization section"). Re: Rotating some points , seems slow - slenkar - 04-10-2013 im drawing lines between the points now (with DRAW ) 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 #include 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``` Re: Rotating some points , seems slow - slenkar - 04-11-2013 I tried drawing my own lines and now I can draw part of a rotating spaceship (also featuring britlions fill routine) http://www.4shared.com/file/DLgxB2PY/rotate_1.html turn based spaceship battles ahoy Re: Rotating some points , seems slow - boriel - 04-11-2013 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 slowSorry. 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...