GLBasic forum

Codesnippets => 2D-snippets => Topic started by: sf-in-sf on 2013-Feb-20

Title: 2D drawdisc() drawcircle()
Post by: sf-in-sf on 2013-Feb-20
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 [Select]
// --------------------------------- //
// 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.

 
Title: Re: 2D drawdisc() drawcircle()
Post by: Wampus on 2013-Feb-26
Thanks. This came in handy tonight when I was coding.
Title: Re: 2D drawdisc() drawcircle()
Post by: CW on 2013-Mar-18
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



   
Title: Re: 2D drawdisc() drawcircle()
Post by: sf-in-sf on 2013-Mar-23
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!
Title: Re: 2D drawdisc() drawcircle()
Post by: CW on 2013-Mar-24
Fair enough, sf. I'll add it to my to-do list.  =D
-CW
Title: Re: 2D drawdisc() drawcircle()
Post by: sf-in-sf on 2013-Mar-25
I find the alpha plotting too slow. To go fast, we would need to be more direct and use a pointer to the drawing surface memory location. Then the symetry trick would make sense, I think.
I don't know how to do it in practice. In GLb are we allowed to go down to such a low level C procedure? Would android -in java- accept it?
Title: Re: 2D drawdisc() drawcircle()
Post by: fuzzy70 on 2013-Mar-25
SETPIXEL is the problem with regards to being the major speed killer.

I have been looking at your code & thinking of ways of how to speed it up, not got down to writing code as of yet but trying out things in my head. Symmetry would speed things up but with various degrees of increase, for example the increase would be at it's maximum effect if the whole object fitted on the screen whereas the minimum increase would be something like only a quarter of the circle being visible (defeats the point of symmetry if none of it gets seen or plotted).

As it stands with your code you check at the start of the function what is visible & only plot what's going to be visible on screen. To me that would have to be modified or removed for it to work with symmetry, or possibly kept & the symmetry points checked at runtime to see if they are visible. The problem with the latter approach is that the extra checks (4 checks for 4 point symmetry & 8 checks for 8 point) will eat into the gains of symmetry thanks to the extra code, by how much I do not know until I test it for real but I think it will still be faster than non-symmetric circles.

Sorting out the plotting speed might possibly be solved by either using MEM2SPRITE or openGL. The 1st I have used numerous times before & while the MEM2SPRITE command does have an overhead I have not come across a time yet where it has been slower than plotting pixels using SETPIXEL. Check my post http://www.glbasic.com/forum/index.php?topic=8670.0 (http://www.glbasic.com/forum/index.php?topic=8670.0) with a simple test I done with drawing a mandelbrot with colour cycling. My 1st version of that used SETPIXEL & seriously struggled to hit 5FPS I think it was, may have been slightly faster or slower I can't remember but was nowhere near as fast as the MEM2SPRITE  version.

I can't really help on the openGL side of things or if you would gain any kind of speed increase but only mentioned it in case someone reading this with knowledge of using it can confirm or deny if it would benefit it's use.

Hopefully in the next couple of days I will be able to play around with a MEM2SPRITE version, a symmetry version & probably a combo of both to see if/how much a speed increase can be made.

Lee
Title: Re: 2D drawdisc() drawcircle()
Post by: bigsofty on 2013-Mar-25
In GLb are we allowed to go down to such a low level C procedure? Would android -in java- accept it?

Yes, GLBasic uses C, even on Android. Just remember to stick within the constraints of GLES 1.1 API when the target is a mobile platform.
Title: Re: 2D drawdisc() drawcircle()
Post by: Brick Redux on 2013-Apr-26
SETPIXEL is the problem with regards to being the major speed killer.

Drawline seemed to speed things up(instead of Setpixel) when I was using MEM2SPRITE for image editing. Even when plotting a single point. The only other solution on offer seemed to be Inline code that turns off Setpixels Safe mode.  Playbasic for example has a fast fill command that uses this. (But its limited in its use.)
Title: Re: 2D drawdisc() drawcircle()
Post by: sf-in-sf on 2013-May-25
Code: GLBasic [Select]
// We need something like
POKE 53280, 0
im_loc% = VARPTR(my_foot_image_73052)
// same with VARSEG
POKE im_loc, 0xB787

Hi guys!
As the bear says, "sorry for the long paws!"... :D...  Eventually I'm back after a test of MEM2SPRITE. Good news: yes it speeds things up. I get a constant 2.2 fps at 1.1 GHz or so, and a 800x600 window -no double glazing, sorry.
But the constant fps is not normal, regardless whether a huge circle/ellipse or a tiny dot has been printed. It means that the plotting job to the array[] is very fast (only tested with no alpha, oh lazy me), but the rest is slow. Can DRAWSPRITE be so slow? Mmmh... I don't think so but need to check. If not, MEM2SPRITE would be the slow element (?...).
//*******
Anyway, I'd like to find a fast way to do it, for an app. Please can anyone help us? How can I find (in inline C) the pointer to the back buffer, so that I can plot directly into it instead of {into the array[], then MEM2SPRITE, then DRAWSPRITE, then SHOWSCREEN}?
If this question was tricky or cheeky, here is another option: 1) with CREATESCREEN I create a sprite to the right size. 2) Again, what is the pointer to that sprite? Pleeeeeeease!...
And thanks in advance.
Title: Re: 2D drawdisc() drawcircle()
Post by: sf-in-sf on 2013-May-25
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, [...]

Hi cw!
I never use GRABSPRITE, it doesn't work on iOS and android. It returns a white square on android. See Gernot's introduction to iOS in the online manual.
Title: Re: 2D drawdisc() drawcircle()
Post by: CW on 2013-May-30
Hi sf!

I don't have a smart phone, so I've never had the opportunity to play with GLbasic on one. Nope, I just program for my laptop system.
I look forward to being able to write my own apps for a smartphone. When I do, knowing what GRABSPITE can and can't do will be handy; so I'll keep that problem with GRABSPITE in mind.

Thanks!
-CW
Title: Re: 2D drawdisc() drawcircle()
Post by: Brick Redux on 2013-Jul-28
Perhaps pre-calculating the math into an array is one way to speed things up - if limited in its use...You have an idea on the size of a disc needed and then read from a FOR/NEXT DIM loop to display it instead of doing calculations in real time?
Title: Re: 2D drawdisc() drawcircle()
Post by: Brick Redux on 2013-Jul-29
Because were all at different levels in development here.

So calm down, take a deep breath and post and example instead of venting your pointless frustration.

Your Ocean is not a calm place right now :D
Title: Re: 2D drawdisc() drawcircle()
Post by: kanonet on 2013-Jul-29
Maybe you also want to have a look at this code: http://www.glbasic.com/forum/index.php?topic=4498.msg49701#msg49701
Title: Re: 2D drawdisc() drawcircle()
Post by: kanonet on 2013-Jul-29
Its even possible to do this without Sin/Cos, if you use the Pythagorean theorem.
Title: Re: 2D drawdisc() drawcircle()
Post by: Brick Redux on 2013-Jul-29
Because were all at different levels in development here.

So calm down, take a deep breath and post and example instead of venting your pointless frustration.

Your Ocean is not a calm place right now :D

I am calm, if I were not calm, I would have reduxed bricks to dust, with my bare hands... ;)
My post was merely an enquiry about whether I might have been missing a point...   But I'll take your challenge and come back with some code sometime the next couple of days...

Oooooh! :)

Theres no challenge needed Ocean, as Im sure you can do it.

And on that note I feel a song is called for to clear the air.(Cough)


...EBONY AND IVORY,

LIVE TOGETHER IN PERFECT HARMONY,

SIDE BY SIDE ON MY LAPTOP, PC,

OH, LORD, WHY DON'T WE?....  :D

Title: Re: 2D drawdisc() drawcircle()
Post by: kanonet on 2013-Aug-05
Nice one! You can use Polyvector instead of native OpenGL, this way you can only draw a filled circle, but you could compile it for moblie devices too.
Title: Re: 2D drawdisc() drawcircle()
Post by: fuzzy70 on 2013-Aug-05
While the subject has sidetracked a tad with it moving towards how to draw a quick circle via GL or polyvectors, do either of these solutions bring about a speed increase or can be implemented in the original post?.

The reason setpixel was used originally was because the output of the program produced (bad description coming up time  :D) non flat boring single coloured circles/discs.

So in essence is there any way that openGL or even polyvectors could be used to speed up the output of the original program replacing the setpixel slowcoach method.

Lee
Title: Re: 2D drawdisc() drawcircle()
Post by: fuzzy70 on 2013-Aug-06
Lee,

the fun part is that with either method (POLYVECTOR or direct OpenGL) you can use texture bitmaps to create circles with a colour or texture frenzy.  Excuse me for not mentioning this before, I thought this was self-evident, as this is a basic feature of polyvectors.

Your very nice bitmap shows circles that are slightly out of focus, indicating (or simulating?) the usage of depth, i.e. 3D.   If that is what you're after, there are two more methods to use, as you could create 3D-circle objects on your graphics card's memory and tell OpenGL where you want to have them drawn.  This is faster still, as only the very first drawing cycle these objects are moved to the graphics card.  And yes, 3D-objects can use texture bitmaps too...

cheers
Ocean

Cheers Ocean, gives me something to investigate & tbh a good excuse for me to finally get my arse in gear with regards to learning OpenGL as I am sure there are some routines of mine that could really benefit from it.

As for the bitmap I attached that is the output from the original post by the author of this topic & they are after suggestions/alternatives to the awful slow setpixel command currently used to create them. They have tried MEM2SPRITE & gained a minor speed increase, symmetry is another option for a boost but direct access to the buffer would provide the ultimate speed I think & that is something we are unable to as far as I'm aware.

Excuse my ignorance & lack of OpenGL knowledge but is it possible to draw pixels in OpenGL as that might be one option that may give an increase in speed.

Another option that has literally just sprung to mind while typing this is that it might be feasible to use your circle routine (not the filled one) by getting the colour & alpha for each part of the radius the plotting with your routine, for example if the disc is 30 pixels thick then call your routine 30 times with the relevant colour/aplha values at each radii. Just a thought & may be worth a try although the segments would have to be quite high to prevent any pixel holes.

Hmm, plenty of food for thought there for me  :D

Lee
Title: Re: 2D drawdisc() drawcircle()
Post by: fuzzy70 on 2013-Aug-06
Thanks Ocean, I now have a few options to sink my teeth into & experiment/learn with.

As a thought, would it be possible to sweep a texture around a disc?. For example the above circles/discs in the bitmap I attached are essentially 1 pixel wide & whatever the thickness of the disc is high. I use a similar approach in 3D packages to create rings around a planet which is normally just a case of selecting the right texture mapping option, although I have no idea how I would go about that from a programming point of view.

Lee
Title: Re: 2D drawdisc() drawcircle()
Post by: Slydog on 2013-Aug-07
My 'Rolling Hills' example may have some code / ideas to start you off:
http://www.glbasic.com/forum/index.php?topic=8118.msg68247#msg68247 (http://www.glbasic.com/forum/index.php?topic=8118.msg68247#msg68247)

It is POLYVECTOR based.  The function 'AddPoint()' (in the 'types.gbas' file, near the bottom) has the fancy math that calculates the curves.  It should be modifiable to create circles instead, double textured (inner / outer) if needed.

Title: Re: 2D drawdisc() drawcircle()
Post by: fuzzy70 on 2013-Aug-07
Thanks Slydog, that is definitely worth a look into as I am thinking of going more towards the polyvector route rather than OpenGL at the moment due to sf-in-sf mentioning mobile.

@Ocean. I will still have a look at OpenGL afterwards as it is something that interests me & has been put on hold for to long really  :D. As mobile was mentioned I don't really want to get into GLES or whatever the mobile version is called until I have at least a basic grounding in OpenGL. Mobile development is very low on my list of priority's at the present time due to not having any real decent kit to experiment on. My mobile is a HTC Wildfire cyanogen modded so I could run Android 2.3 so is far from current tech or power but it does do the "Use as a phone" part very well  =D.

Lee
Title: Re: 2D drawdisc() drawcircle()
Post by: fuzzy70 on 2013-Aug-11
Sorry for the double post  :whip:

Here is my initial polyvector disc based from Ocean's OpenGL code posted earlier as a straight forward function. Please refer to Ocean's code for a more indepth description of the algorithm involved as no point in me explaining something that's already been said  :D.

At the present moment the function just draws a disc with an inner & outer radius, the texture side of things is still to be implemented & things will change as I develop the function. For example I may change the outer radius variable to be a thickness one instead as that seems more logical plus other additions. Once it is completed I will post the full function into the 2d snippets section of the forum.

Next job is extracting a 1 pixel wide texture from sf-in-sf's original post to sweep around the disc & hopefully produce the same results as the initial post with a nice boost in speed  =D.

Lee

Code: GLBasic [Select]
// --------------------------------- //
// Project: poly_disc
// Start: Sunday, August 11, 2013
// IDE Version: 10.283


// SETCURRENTDIR("Media") // go to media files
// Fuzzys polyvector disc based/inspired by Ocean's circle experiments (ogl_circle)


LOCAL x%,y%
LOCAL radius%, blue%

radius = 30
x = 320
y = 240

WHILE TRUE
               
        drawdisc(x,y,radius,radius+20)
        INC radius, 1
        radius = MOD (radius, 320)

        SHOWSCREEN

        //KEYWAIT

WEND
       

FUNCTION drawdisc: x%,y%,radius_inner%,radius_outer%,id%=-1,colour%=RGB(255,255,255)
       
        LOCAL segments%, theta#, c#, s#, t_inner#, t_outer#, lx_outer#, ly_outer#, lx_inner#, ly_inner#
        LOCAL start_x_outer#, start_y_outer#, start_x_inner#, start_y_inner#
        LOCAL idx%

        IF radius_inner > radius_outer          // Make sure inner radius is
                SWAP radius_inner,radius_outer  // smaller than the outer radius
        ENDIF
       
        segments = INTEGER(10 * SQR(radius_inner))
        theta = 360.0 / segments
        c = COS(theta)
        s = SIN(theta)
        lx_inner = radius_inner
        ly_inner = 0
        lx_outer = radius_outer
        ly_outer = 0

        idx = 0


        STARTPOLY id,2

        start_x_inner = lx_inner + x            // Store the initial points
        start_y_inner = ly_inner + y            // to close the polyvector
        start_x_outer = lx_outer + x            // at the end
        start_y_outer = ly_outer + y

        WHILE (idx < segments)

                POLYVECTOR lx_inner + x, ly_inner + y ,0,0, colour%
                POLYVECTOR lx_outer + x, ly_outer + y ,0,0, colour%

                t_inner = lx_inner
                t_outer = lx_outer

                lx_inner = c * lx_inner - s * ly_inner
                ly_inner = s * t_inner  + c * ly_inner
                lx_outer = c * lx_outer - s * ly_outer
                ly_outer = s * t_outer  + c * ly_outer

                INC idx, 1
               
        WEND
       
        POLYVECTOR start_x_inner,start_y_inner,0,0,colour%              // Close the polyvector
        POLYVECTOR start_x_outer,start_y_outer,0,0,colour%

       
        ENDPOLY
               
ENDFUNCTION
 
Title: Re: 2D drawdisc() drawcircle()
Post by: sf-in-sf on 2013-Sep-14
Fuzzy, I didn't try your code but it looks fine. Here is my version. Polyvector is definitely fast. For large circles increase the gon value, and reduce it for small circles, for best appearance and speed.
Code: GLBasic [Select]
// --------------------------------- //
// Project: drawcirc-polyv
// Start: Saturday, September 14, 2013
// IDE Version: 10.283

SETSCREEN 800,600,0 //whatever
GLOBAL gon%, r%, th%, col%, cx%,cy%

here:
        r=50+RND(200)
        th=1+33*RND(2)
        col=RGB(255*RND(1),255*RND(1),255*RND(1))
        cx=RND(800) ; cy=RND(600)
        IF RND(1)=1 // 50% odds.
                gon=120 // steps nb, reduce for v.small circles.
        ELSE
                gon=3+RND(5) // n-gon.
        ENDIF
drawcircpolyv(gon,cx,cy,r,th,col)
USEASBMP // ad lib
SHOWSCREEN
GOTO here
//END

FUNCTION drawcircpolyv: g%,cx%,cy%,r%,t%,c%
LOCAL sin1,sin2,cos1,cos2
        STARTPOLY -1,2 // no texture, strip mode.
        //(use or generate a texture with blended edges
        // to skip alpha values interpolation. Donate to inkscape).
        // 0___2___4__
        //  \ / \ / \
        //   1___3___5 etc
        // parallelograms are 0-1-2-3, 2-3-4-5, 4-5-6-7, etc.
       
        FOR i% =0 TO g-1
                sin1=SIN(i*360/g) ; cos1=COS(i*360/g)
                sin2=SIN((i+1)*360/g) ; cos2=COS((i+1)*360/g)
                POLYVECTOR cx +cos1*(r-t*0.5), cy+sin1*(r-t*0.5), 0,0,c //0, inbound
                POLYVECTOR cx +cos1*(r+(t+1)*0.5), cy+sin1*(r+(t+1)*0.5), 0,0,c //1, outbound
                POLYVECTOR cx +cos2*(r-t*0.5), cy+sin2*(r-t*0.5), 0,0,c //2, inbound
                POLYVECTOR cx +cos2*(r+(t+1)*0.5), cy+sin2*(r+(t+1)*0.5), 0,0,c //3, outbound
                // (t+1) allows thickness =1.
        NEXT
        ENDPOLY
ENDFUNCTION
Title: Re: 2D drawdisc() drawcircle()
Post by: fuzzy70 on 2013-Sep-14
The thing about the one I posted based on ocean's code is that it only requires 1 call each to sin & cos, also it automatically increases the amount of  segments the larger the circles get.

Glad you got a version working that's faster than the original pixel plotting one :-)

Lee

Sent from my Xperia Z using Tapatalk 2

Title: Re: 2D drawdisc() drawcircle()
Post by: sf-in-sf on 2013-Sep-17
It took me a while to learn and experiment with POLYVECTOR.
The code could be faster: I just noticed that each segment calculates 2 sin and 2 cos, i.e. 2x too much.... the new point's coordinates must be kept in memory (static for example) and used later for the next segment, as the old point. No need to calculate twice.
I'm busy now. Please have a go and see if that new version is really faster. If it goes very fast then SHOWSCREEN will set a limit of 60 objects per second, which isn't right. I'll be back next week or so.
Title: Re: 2D drawdisc() drawcircle()
Post by: Elemee on 2015-Nov-17
I am brand new to GLB, and am trying to recode a game I created in SiMPLE Basic that happens to make use of built in 2D primitives in that language. like Solidcircle().  Is there no built-in graphics primitive in GLB to do circles, ellipses, or other figures?  Is that is why this thread exists?  If so, would you be so kind as to point me to the simplest way to code a filled circle in GLB?  Your help would be much appreciated.
Title: Re: 2D drawdisc() drawcircle()
Post by: Ian Price on 2015-Nov-17
Try both examples above by fuzzy70 and sf-in-sf. There are other alternatives to using POLYVECTOR commands too.