Posts: 282
Threads: 48
Joined: Feb 2011
Reputation:
0
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
Posts: 1,774
Threads: 55
Joined: Aug 2019
Reputation:
24
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:
- 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
Posts: 282
Threads: 48
Joined: Feb 2011
Reputation:
0
thanks I put fsin and fcos into arrays and now a circle completes in a few seconds as opposed to a few minutes
Posts: 805
Threads: 135
Joined: Apr 2009
Reputation:
5
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?)
Posts: 1,774
Threads: 55
Joined: Aug 2019
Reputation:
24
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 :?:
Posts: 282
Threads: 48
Joined: Feb 2011
Reputation:
0
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...
Posts: 1,774
Threads: 55
Joined: Aug 2019
Reputation:
24
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
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: <!-- 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").
Posts: 282
Threads: 48
Joined: Feb 2011
Reputation:
0
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 <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
Posts: 282
Threads: 48
Joined: Feb 2011
Reputation:
0
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
Posts: 1,774
Threads: 55
Joined: Aug 2019
Reputation:
24
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...
|