Forum
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 <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



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


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 <!-- 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?)


Re: Rotating some points , seems slow - boriel - 04-10-2013

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 :?:


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

<!-- 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...


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

<!-- 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").


Re: Rotating some points , seems slow - slenkar - 04-10-2013

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



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)
<!-- 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


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 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...