### Author Topic: 2Ddrawellipse()  (Read 2025 times)

#### sf-in-sf

• Mr. Drawsprite
• Posts: 93
• Artist F.P. Brixey
##### 2Ddrawellipse()
« on: 2013-Mar-23 »
Read, use, enjoy! (I haven't tried your version yet, Gernot, you've been quicker than me.)
I'm surprised that the plotting with alpha seems to take much longer than the calculations and area scanning.
Any idea to improve that?

Code: (glbasic) [Select]
`// --------------------------------- //// Project: ellipse1// Start: Saturday, March 16, 2013// IDE Version: 10.244// SETCURRENTDIR("Media") // go to media files// --------------------------------- //// Project: circle1// Start: Sunday, February 03, 2013// IDE Version: 10.244// SETCURRENTDIR("Media") // go to media filesGLOBAL scrx%=666, scry%=666 //your custom size.// For PC use menu;project;options;GETSCREENSIZE scrx, scrySETSCREEN scrx,scry,0    // Size matters.CREATESCREEN 1,1,scrx,scry // the drawing surface.GLOBAL cnt%CONSTANT framing=0.12 // i.e. 12%//****************************************************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 = 2.2 +13*RND(3) LOCAL thickness=3*RND(9) // (0 means filled ellipse, in 2nd Fn).// USESCREEN 1//define the x,y of the 2 centers:GLOBAL c1x%=scrx*framing+RND(scrx*(1-framing-framing))GLOBAL c2x%=scrx*framing+RND(scrx*(1-framing-framing))GLOBAL c1y%=scry*framing+RND(scry*(1-framing-framing))GLOBAL c2y%=scry*framing+RND(scry*(1-framing-framing))GLOBAL rr_=SQR((c1x-c2x)*(c1x-c2x)+(c1y-c2y)*(c1y-c2y))*(1.03+RND(800)*0.001)// rr_ is the length of the string stretched between the 2 centers.// As you draw, keep the string tentioned with the pen.// Try at home with 2 pins on a piece of cardboard.IF TRUE //RND(1) >0// Choose which Fn:// drawellipse1(c1x,c1y,c2x,c2y,SQR((c1x-c2x)*(c1x-c2x)+(c1y-c2y)*(c1y-c2y))*(1.03+RND(800)*0.001),color, alpha)//, smoothedge) drawellipse2(c1x,c1y,c2x,c2y,rr_, thickness,color, alpha, smoothedge)ENDIF //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 999WEND//****************************************************// On the day the atom is a cube I will believe in the square pixel.//__________________________________________________________________________________FUNCTION drawellipse1:c1x%,c1y%,c2x%,c2y%,r%,col%,a //raw, filled shape, fast Fn no smoothing.LOCAL r2% = r*r //?LOCAL bx1%,bx2%,by1%,by2%IF r <SQR((c1x-c2x)*(c1x-c2x)+(c1y-c2y)*(c1y-c2y)) THEN RETURN 0 //impossible to draw, string is too short.USESCREEN 1IF c1x >=c2x bx2 = c2x +r //(approx.) bx1 = c1x -rELSE bx2 = c1x +r bx1 = c2x -rENDIFIF c1y >=c2y by2 = c2y +r by1 = c1y -rELSE by2 = c1y +r by1 = c2y -rENDIFALPHAMODE aFOR x%=bx1 TO bx2FOR y%=by1 TO by2 IF SQR((x-c1x)*(x-c1x) +(y-c1y)*(y-c1y)) +SQR((x-c2x)*(x-c2x) +(y-c2y)*(y-c2y)) <= r THEN SETPIXEL x,y,colNEXTNEXTRETURN 1ENDFUNCTIONFUNCTION drawellipse2:c1x%,c1y%,c2x%,c2y%,r,thick,col%,a,smoo //raw shapeIF r <SQR((c1x-c2x)*(c1x-c2x)+(c1y-c2y)*(c1y-c2y)) THEN RETURN 0 //impossible to draw, string is too short.IF smoo <0 THEN smoo =0smoo=smoo*1.8 // approx.correctionLOCAL halfsmoo =smoo*0.5LOCAL th =thick*0.5LOCAL smoooo =smoo+smooLOCAL rs1 =r+smooooLOCAL ra  = (r+halfsmoo+th)LOCAL rb  = (r+th) //LOCAL rc  = (r-th) //LOCAL rd  = (r-th-halfsmoo)LOCAL d,d2LOCAL r2 =r*rLOCAL w_out =ra-(r+th) +0.000001//r2_ -r2LOCAL w_in  =(r-th)-rd +0.000001LOCAL w_out_plain =rs1-(r) +0.000001LOCAL bx1%,by1%,bx2%,by2%USESCREEN 1IF c1x >=c2x bx2 = c2x +r +th +smoooo //(approx.) bx1 = c1x -r -th -smooooELSE bx2 = c1x +r +th+smoooo bx1 = c2x -r -th-smooooENDIFIF c1y >=c2y by2 = c2y +r +th+smoooo//(approx.) by1 = c1y -r -th-smooooELSE by2 = c1y +r +th+smoooo by1 = c2y -r -th-smooooENDIFFOR x%=bx1 TO bx2FOR y%=by1 TO by2//FOR x%=0 TO scrx//FOR y%=0 TO scryLOCAL d=SQR((x-c1x)*(x-c1x) +(y-c1y)*(y-c1y)) +SQR((x-c2x)*(x-c2x) +(y-c2y)*(y-c2y))IF thick=0 // elliptic disc IF d <= r ALPHAMODE a SETPIXEL x,y,col //print it plain ELSEIF d <= rs1 // then interpolate the alpha. ALPHAMODE (rs1-d)*a/smoooo SETPIXEL x,y,col ENDIFELSE // outlined ellipse IF d <= r //internal IF d >= rc //plot it plain. ALPHAMODE a SETPIXEL x,y,col ELSEIF d <=  rd // ignore it ELSE // interpolate, blend it. ALPHAMODE (d -rd)*a/w_in SETPIXEL x,y,col ENDIF ELSE //external IF d < rb //plot it plain. ALPHAMODE a SETPIXEL x,y,col ELSEIF d >=  ra // ignore it ELSE // interpolate, blend it. ALPHAMODE (ra -d)*a/w_out SETPIXEL x,y,col ENDIF ENDIFENDIFNEXTNEXTRETURN 1 // Smooth operation hopefullyENDFUNCTION// P.S. On the day the atom is a cube I will believe in the square pixel.`
On the day the atom is a cube I will start believing in the square pixel.

#### bigsofty

• Community Developer
• Prof. Inline
• Posts: 2668
##### Re: 2Ddrawellipse()
« Reply #1 on: 2013-Mar-25 »
Very nice!

In OpenGL in general switching the drawing state too regularly is to be avoided as its a slow operation. So if you could move ALPHAMODE outside of your loops, it may be quicker. Also, I have found that doing some OpenGL inline can be a bit quicker too as you have more control over the low level drawing operations. As mentioned by Fuzzy70, MEM2SPRITE can also be a good way to draw lots of pixels fast.
Cheers,

Ian.

“It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration.”
(E. W. Dijkstra)