2D drawdisc() drawcircle()

Previous topic - Next topic

kanonet

Its even possible to do this without Sin/Cos, if you use the Pythagorean theorem.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

Brick Redux

Quote from: Ocean on 2013-Jul-29
Quote from: 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

A mournful owner of a HP HDX18 Laptop that has died...FECK!

kanonet

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.
Lenovo Thinkpad T430u: Intel i5-3317U, 8GB DDR3, NVidia GeForce 620M, Micron RealSSD C400 @Win7 x64

fuzzy70

#18
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
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

fuzzy70

Quote from: Ocean 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
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

fuzzy70

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
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

Slydog

My 'Rolling Hills' example may have some code / ideas to start you off:
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.

My current project (WIP) :: TwistedMaze <<  [Updated: 2015-11-25]

fuzzy70

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
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

fuzzy70

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
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

sf-in-sf

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
On the day the atom is a cube I will start believing in the square pixel.

fuzzy70

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

"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

sf-in-sf

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.
On the day the atom is a cube I will start believing in the square pixel.

Elemee

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.

Ian Price

Try both examples above by fuzzy70 and sf-in-sf. There are other alternatives to using POLYVECTOR commands too.
I came. I saw. I played.