Author Topic: Pythagoras Optimising...  (Read 13877 times)

0 Members and 1 Guest are viewing this topic.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Pythagoras Optimising...
« Reply #20 on: November 05, 2008 »
That's right, one algorithm is linear, the other is a quadratic curve.  Small parts of quadratic curves look linear-ish, which is why you can sometimes get away with it.

Have you tried some small table look-ups?

Jim

Challenge Trophies Won:

Offline hellfire

  • Sponsor
  • Pentium
  • *******
  • Posts: 1294
  • Karma: 466
    • View Profile
    • my stuff
Re: Pythagoras Optimising...
« Reply #21 on: November 05, 2008 »
Use three (relatively big) integer-tables to store BRx/sqrt(x*x+y*y) and you're done with 3 adds.
The position of each "ball" on the screen (red) is translated into an offset inside the table (blue).
Use another table (palette) to look up the final color.
With vsync disabled you get comfortable 1000 frames per second ;D
« Last Edit: November 05, 2008 by hellfire »
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17412
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Pythagoras Optimising...
« Reply #22 on: November 05, 2008 »
Using this kind of thing for a metabobs routine is heavy though... I know that the same result can be got much more cheaply (but maybe not as elegantly) by using a simple additive gradient bob routine (see attachment).

These lights are actually metaballs..

Megafast code with loads of bugs..

Code: [Select]

        OPTION STATIC
        OPTION EXPLICIT
 
 
        #INCLUDE "TINYPTC_EXT.BI"
        #INCLUDE "WINDOWS.BI"   
        CONST   XRES = 640
        CONST   YRES = 480

        DIM SHARED AS DOUBLE RAD2DEG
       
        DIM SHARED AS INTEGER HALFX = (XRES/2)
        DIM SHARED AS INTEGER HALFY = (YRES/2)
        DIM SHARED AS INTEGER BLOB (600 * 600)
       
        '
        '

        DIM SHARED AS UINTEGER PAL (10000)


        RAD2DEG = ((4*ATN(1)) / 180 )
               
        DIM SHARED AS UINTEGER  BUFFER ( XRES * YRES )
        DIM SHARED AS UINTEGER  BUFFER2( XRES * YRES )
       

        DECLARE SUB DRAW_BG()
        DECLARE SUB PRECALC()
        DECLARE SUB COPYOVER()
        DECLARE SUB TWISTER()
        declare sub dblob(BYVAL MVOX AS INTEGER , BYVAL MVOY AS INTEGER)
        DECLARE SUB CIRC(BYVAL CX AS INTEGER , BYVAL CY AS INTEGER , BYVAL R AS INTEGER, BYVAL CR AS INTEGER)
'-------------------------------------------------------------------------------

        PRECALC()

        PTC_ALLOWCLOSE(0)
        PTC_SETDIALOG(0,"",0,0)   
       
        IF (PTC_OPEN("<( - METABALLS - )>",XRES,YRES)=0) THEN
        END-1
        END IF     
   
'-------------------------------------------------------------------------------   

DIM SHARED AS DOUBLE GD1,GD2,GD3,O,DV

WHILE(GETASYNCKEYSTATE(VK_ESCAPE)<>-32767) 
    O=TIMER
    GD1=GD1+(DV*.7)
    GD2=GD2+(DV*.6)
    GD3=GD3-(DV*.4)

    DBLOB(90*SIN(GD1)+20,(70*COS(GD2))-40 )   
    DBLOB(20*SIN(GD2+90)+20,(20*SIN(GD3))+40 )   
    DBLOB(90*COS(GD2/3)+20,(70*COS(GD2/2)) )     
    DBLOB(190*SIN(GD2+150)+20,(20*SIN(GD1))-40 )   
    DBLOB(90*COS(GD1/4)+20,(70*COS(GD3/4)) )   
    DBLOB(50*SIN(GD2-50)+20,(20*SIN(GD1*2))-40 )   
    DBLOB(90*COS(GD1/5)+20,(70*COS(GD3+90))+40 )   
    DBLOB(50*COS(GD2/23)+20,(70*COS(GD2/2))-40 )     
    DBLOB(19*SIN(GD1+50)+20,(50*SIN(GD1+180)/6) )   
    DBLOB(10*COS(GD2/14)+20,(60*COS(GD3/4)) )   
    DBLOB(250*SIN(GD2-50)+20,(80*SIN(GD1/2))+30 )   
    DBLOB(190*COS(GD1/5)+20,(70*COS(GD2+90))-40 )   

    COPYOVER()   
    PTC_UPDATE@BUFFER(0)   
    ERASE BUFFER2
    DV=(TIMER-O)*2
WEND

'-------------------------------------------------------------------------------





SUB COPYOVER()
DIM L AS INTEGER
DIM AS UINTEGER PTR PP1,PP2

PP1=@BUFFER (0)
PP2=@BUFFER2(0)
FOR L=0 TO (XRES*YRES)-1
    *PP1 = PAL(*PP2)
    PP1+=1
    PP2+=1
NEXT

END SUB



SUB PRECALC()
    DIM AS DOUBLE RR,GG,BB
    DIM AS INTEGER L
    dim as integer aval = 25
    RR=0.0:GG=0.0:BB=0.0
   
    FOR L=0 TO 7999
        IF L>1000 THEN
        RR=RR+.05
        GG=GG+.05
        BB=BB+.05
        ELSE
        BB=BB+.1
        END IF
        IF L>2000 THEN
        RR=RR+.015
        GG=GG+.015
        BB=BB+.015
        END IF
        IF L>3000 THEN
        RR=RR+.015
        GG=GG+.015
        BB=BB+.015
        END IF
   
        IF RR>255 THEN RR=255
        IF GG>255 THEN GG=255
        IF BB>255 THEN BB=255
        PAL(L)=RGBA(INT(RR),INT(GG),INT(BB),aval)
    NEXT


dim as integer radius,x1,y1,x2,clv,Z,A
DIM AS DOUBLE ANGLE,BANGLE

radius=299
clv=0
for z=1 to 299
        bangle=360
        clv=clv+1
        if z>75 then clv=clv+1
        if z>125 then clv=clv+1
        if z>215 then clv=clv+1
        if z>295 then clv=clv+1
        CIRC(300,300,RADIUS,CLV)
        radius=radius-1
next
END SUB


SUB DRAW_BG()
    DIM PP AS UINTEGER PTR
    DIM AS INTEGER Y,SLICE,TC,www
    www=30


' ERASE EDGES;
    TC=8000
FOR Y=0 to YRES-1
    SLICE=WWW
    PP = @BUFFER2((Y*XRES))   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   

    SLICE=WWW
    PP = @BUFFER2(((Y+1)*XRES)-WWW)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
NEXT


'
' BORDERS;
'

    TC=30
    FOR Y=0 TO 29
    SLICE=HALFX-www
    PP = @BUFFER2((Y*XRES)+www)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    NEXT
    FOR Y=YRES-30 TO YRES-1
    SLICE=HALFX-www
    PP = @BUFFER2((Y*XRES)+HALFX)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    NEXT


    TC=1030
   
    FOR Y=0 TO 30
    SLICE=HALFX-www
    PP = @BUFFER2((Y*XRES)+HALFX)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    NEXT
    FOR Y=YRES-30 TO YRES-1
    SLICE=HALFX-www
    PP = @BUFFER2((Y*XRES)+www)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    NEXT


'
' MAIN BODY (CENTRE)
'
    TC=20
    FOR Y=30 TO HALFY
    SLICE=HALFX-www
    PP = @BUFFER2((Y*XRES)+www)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    NEXT
    FOR Y=HALFY+1 TO YRES-30
    SLICE=HALFX-www
    PP = @BUFFER2((Y*XRES)+HALFX)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    NEXT


    TC=1020
   
    FOR Y=30 TO HALFY
    SLICE=HALFX-www
    PP = @BUFFER2((Y*XRES)+HALFX)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    NEXT
    FOR Y=HALFY+1 TO YRES-30
    SLICE=HALFX-www
    PP = @BUFFER2((Y*XRES)+www)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    NEXT


'
'
'

    TC=5100
    SLICE=XRES-100
    PP = @BUFFER2((30*XRES)+50)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
   
    SLICE=XRES-100
    PP = @BUFFER2(((YRES-30)*XRES)+50)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   


    TC=5000
    SLICE=XRES-100
    PP = @BUFFER2((29*XRES)+50)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
   
    SLICE=XRES-100
    PP = @BUFFER2(((YRES-29)*XRES)+50)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
    SLICE=XRES-100
    PP = @BUFFER2((31*XRES)+50)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm   
   
    SLICE=XRES-100
    PP = @BUFFER2(((YRES-31)*XRES)+50)   
    asm
        mov eax,dword ptr[TC]
        mov ecx, [slice]
        mov edi, [PP]
        rep stosd
    end asm       
END SUB





sub dblob(BYVAL MVOX AS INTEGER , BYVAL MVOY AS INTEGER)
   
    DIM AS INTEGER X,Y
   
    'clipping
    dim as integer STRTX,ENDX,SLICE,CLIPL,CLIPR
   
   
   
'    ENDX=MVOX+600   
   
    STRTX=0
    SLICE=600       
    IF MVOX<0 THEN         
        STRTX= - MVOX
        SLICE=600-STRTX       
    END IF
   
   
    IF (MVOX+600) >= XRES-1 THEN
   
    SLICE = (XRES-MVOX)-1
   
    END IF

    IF MVOX<0 THEN MVOX=0
    IF MVOX>XRES-1 THEN MVOX=XRES-1

    dim pp1 as uinteger ptr
    dim pp2 as uinteger ptr
   
    for y=0 to 600
       
    pp1=@buffer2(MVOX+((MVOY+Y)*XRES))
    pp2=@blob   (STRTX+(Y *600))
   
    IF (MVOY+Y<(YRES-1)) AND (MVOY+Y>0) THEN
       
        for x=0 to SLICE

            *PP1= *PP1 + *PP2

            pp1+=1
            pp2+=1

        next
   
    END IF
   
next

end sub


SUB CIRC(BYVAL CX AS INTEGER , BYVAL CY AS INTEGER , BYVAL R AS INTEGER, BYVAL CR AS INTEGER)


DIM  as integer r2,cc,loopy,ww,l,clipl , clipr,slice,tc
dim pp as integer ptr
r2=r*r
cc=-r
TC = CR
for loopy = cc to r     
        ww = Sqr(r2-loopy*loopy)

        if loopy+cy>=0 and loopy+cy<600 then
            clipl = cx-ww
            clipr = (cx+ww)-1
            if clipl<0 then clipl=0
            if clipr>600-1 then clipr = 600-1
            pp=@BLOB((600*(loopy+CY))+clipl)
            slice = clipr-clipl
           
            if slice>0 then
                    asm
                    mov eax,dword ptr[TC]
                    mov ecx, [slice]
                    mov edi, [PP]
                    rep stosd
                    end asm   
            end if
           

   
        end if

next
END SUB

Shockwave ^ Codigos
Challenge Trophies Won:

Offline relsoft

  • DBF Aficionado
  • ******
  • Posts: 3303
  • Karma: 47
    • View Profile
Re: Pythagoras Optimising...
« Reply #23 on: December 19, 2008 »
just to satisfy my curiosity... what is the problem you need to solve all this for?

In Shocky's birthday card, I had some meta balls (I think that's what they're called) where they move around and merge into each other.  The calculation is done three times per pixel and as a result it slows the thing down.  I was just looking for a way to optimise things.

I know the optimisation that hellfire is talking about should work, I just can't get it to work.

I think I need to tear that routine out as a stand alone program and post the source, that would make it a lot easier for people to see where I'm missing the obvious :D

Are those blobs in 2d or 3d?

If it's in 2d, you prolly don't need a per pixel SQR at all.
Challenge Trophies Won: