Codesnippets > 2D-snippets

2D drawdisc() drawcircle()

(1/6) > >>

sf-in-sf:
I'd like to share my 3 useful functions. Enjoy and experiment!
More on my artistic experimental programming: google 'artist F.P. Brixey saatchionline'. NEW: my collection is visible on deviant art.


--- Code: GLBasic ---// --------------------------------- //
// Project: circle1
// Start: Sunday, February 03, 2013
// IDE Version: 10.244


// SETCURRENTDIR("Media") // go to media files
GLOBAL scrx%=666, scry%=666 //your custom size.
// For PC use menu;project;options;win32
GETSCREENSIZE scrx, scry
SETSCREEN scrx,scry,0           // Size matters.
CREATESCREEN 1,1,scrx,scry
        // the drawing surface.
GLOBAL cnt%
//****************************************************
WHILE TRUE
        //press F12 to view long lines of code.
        LOCAL alpha=(RND(1999)/1000.0 -1.0)+0.00000003
                // additive when >0
                // interpolated when <0, ='mix' ='cross-fade'
                // ...in my opinion.
        LOCAL color%=RGB(128*RND(2)-1,128*RND(2)-1,128*RND(2)-1)
        LOCAL smoothedge = 1.5+9*RND(2)
        LOCAL thickness=1.5+11*RND(3)
//      USESCREEN 1

IF RND(1) >0
        drawdisc2(RND(scrx), RND(scry), 4+RND(300), color, alpha, smoothedge)   // yes smoothing.
ELSE
        drawcircle2_(RND(scrx), RND(scry), 4+RND(300), thickness,color, alpha, smoothedge)   // yes smoothing.
ENDIF
        //drawdisc1(RND(scrx), RND(scry), 4+RND(300), color, alpha) // no smoothing. // unused.
       
        //USEASBMP // optional
        USESCREEN -1
        ALPHAMODE -1
        DRAWSPRITE 1,0,0
        SHOWSCREEN
                INC cnt,1
                IF cnt >4
                        cnt=0
                        SEEDRND (GETTIMERALL()) //shuffle the cards.
                ENDIF

//FOR more clarity:
        DEBUG alpha ; DEBUG "\n"
        // please activate the 'bug' icon
//      SLEEP 2012 // additional time

        SLEEP 800 +RND(3333)
        //SLEEP 787// Merry dream, liner!
WEND
//****************************************************


FUNCTION drawdisc1:cx%,cy%,r%,col%,a //raw shape
// a fast function with no blending.
//would be nearly 4x faster using symetry, working on just 1/4circle.
LOCAL r2% = r*r
USESCREEN 1
//Only plot within the screen to save time:
LOCAL bx1%=cx-r
        IF bx1 <0 THEN bx1=0
LOCAL by1%=cy-r
        IF by1 <0 THEN by1=0
LOCAL bx2%=cx+r
        IF bx2 >scrx THEN bx2=scrx
LOCAL by2%=cy+r
        IF by2 >scry THEN by2=scry

ALPHAMODE a // same speed for a=0, a=-1, strangely. Any suggestion for more speed?

FOR x%=bx1 TO bx2
FOR y%=by1 TO by2
        IF (x-cx)*(x-cx) +(y-cy)*(y-cy) <= r2 THEN SETPIXEL x,y,col
NEXT
NEXT
ENDFUNCTION

// On the day the atom is a cube I will start believing in the square pixel.

FUNCTION drawdisc2: cx,cy,r,col%,a,smoo //smoothed.
// Basic values are a=-1, smoo=1.
// N.B. a= -1...+1 but a=0 cancels the smoothing.
//   (if trouble try a permanent "INC a, 0.00000000000000042")
// Higher smoo values blur the edges. (Do try it at home!)
// Smoothing is symetrical across the circle position:
//      blurring goes both inwards and outwards. It is done in a quick
// way as it doesn't calculate SQR(d^2), using directly the r^2
// values for interpolation. Not as nice as a proper bicubic one.
// Just feel free to try your own way to interpolate the alpha
// value for a nicer smoothing/halo.
USESCREEN 1
IF smoo <0 THEN smoo =0
LOCAL halfsmoo =smoo*0.5
LOCAL r2  = (r-halfsmoo)*(r-halfsmoo) //contracted
LOCAL r2_ = (r+halfsmoo)*(r+halfsmoo) //expanded
LOCAL d2
LOCAL w=r2_ -r2

//Only plot within the screen to save time:
LOCAL bx1%=cx-r-halfsmoo
        IF bx1 <0 THEN bx1=0
LOCAL by1%=cy-r-halfsmoo
        IF by1 <0 THEN by1=0
LOCAL bx2%=cx+r+halfsmoo
        IF bx2 >scrx THEN bx2=scrx
LOCAL by2%=cy+r+halfsmoo
        IF by2 >scry THEN by2=scry


FOR x%=bx1 TO bx2
FOR y%=by1 TO by2

        d2=(x-cx)*(x-cx) +(y-cy)*(y-cy)
        IF d2 <= r2
                ALPHAMODE a
                SETPIXEL x,y,col
        ELSEIF d2 >= r2_
                // leave it alone.
        ELSE
                //interpolation:
                ALPHAMODE (r2_ -d2)*a/w
                SETPIXEL x,y,col
        ENDIF
NEXT
NEXT
ENDFUNCTION

// On the day the atom is a cube I will start believing in the square pixel.

FUNCTION drawcircle2_: cx,cy,r,thick,col%,a,smoo //smoothed.
// Same principle as drawdisc2( .
// using the real r value instead of r*r looks nicer but takes longer.
// This interpolation is linear but I believe a 'S' shape would
// be perfect. Also keep in mind that only an alpha interpolation is
// NOT enough; at the same time you should also interpolate the
// color into the next area. (Yes it's a bit bizarre.)
USESCREEN 1
IF smoo <0 THEN smoo =0
LOCAL halfsmoo =smoo*0.5
LOCAL th =thick*0.5
LOCAL ra  = (r+halfsmoo+th)
LOCAL ra2  = (r+halfsmoo+th)*(r+halfsmoo+th)    //outermost
LOCAL rb2  = (r+th)*(r+th)                                      //
LOCAL rc2  = (r-th)*(r-th)                                      //
LOCAL rd2  = (r-th-halfsmoo)*(r-th-halfsmoo) //innermost
LOCAL rd  = (r-th-halfsmoo)

LOCAL d2
LOCAL r2 =r*r
LOCAL w_out =ra-(r+th) +0.000001//r2_ -r2
LOCAL w_in  =(r-th)-rd +0.000001

//Only plot within the screen to save time:
LOCAL bx1%=cx-r-halfsmoo-th
        IF bx1 <0 THEN bx1=0
LOCAL by1%=cy-r-halfsmoo-th
        IF by1 <0 THEN by1=0
LOCAL bx2%=cx+r+halfsmoo+th
        IF bx2 >scrx THEN bx2=scrx
LOCAL by2%=cy+r+halfsmoo+th
        IF by2 >scry THEN by2=scry


FOR x%=bx1 TO bx2
FOR y%=by1 TO by2

        d2=(x-cx)*(x-cx) +(y-cy)*(y-cy) //distance to center
        IF d2 <= r2 //internal

                IF d2 >= rc2
                        //plot it plain.
                        ALPHAMODE a
                        SETPIXEL x,y,col
                ELSEIF d2 <=  rd2
                        // ignore it
                ELSE
                        // interpolate, blend it.
                        ALPHAMODE (SQR(d2) -rd)*a/w_in
                        SETPIXEL x,y,col
                ENDIF
        ELSE //external

                IF d2 < rb2
                        //plot it plain.
                        ALPHAMODE a
                        SETPIXEL x,y,col
                ELSEIF d2 >=  ra2
                        // ignore it
                ELSE
                        // interpolate, blend it.
                        ALPHAMODE (ra -SQR(d2))*a/w_out
                        SETPIXEL x,y,col
                ENDIF
        ENDIF
NEXT
NEXT
ENDFUNCTION

//__________________________________________________________________________________

// P.S. On the day the atom is a cube I will start believing in the square pixel.

 

Wampus:
Thanks. This came in handy tonight when I was coding.

CW:
Very nice, SF.

Having recently struggled with the slow nature of plotting (drawing) circles in Basic, I am very well placed to admire how quickly your code can draw simple circles. (I especially like how you plot only those points which are actually on the screen.)

How do you think your code for creating simple disks would compare, speed wise, with plotting a disk to the screen, doing a GRABSPRITE of that disk, and then using STRETCHSPRITE to scale the disk up or down to the diameter needed? You could even draw the disk transparent and use the sprite as a mask to stamp colored disks out from a DRAWRECT.

If the speed is favorable, I also wonder if a speed gain could be made by plotting 25% of a disk, as you suggested, and then rotating the sprite around to create the rest of the disk from which the GRABSPRITE could be taken.

I like your more complex disks and  circles, with Alpha set and with the feathered edges, very much. Yeah, they take a little longer to render, but they are worth it. Very stylish.

-Cheers!
-CW



   

sf-in-sf:
Hi CW,

Just run a test on 100-10000 pieces in a row, without randomness, with my method then with yours. compare the total time and see.

Addition to drawcircle() : on the line d2= ... you can multiply the x or y part with zz >=1 to see a pseudo ellipse.
I just posted a dedicated drawellipse() Fn. See and have fun!

CW:
Fair enough, sf. I'll add it to my to-do list.  =D
-CW

Navigation

[0] Message Index

[#] Next page

Go to full version