Pie and Piefilled drawing is distorted
Jump to navigation
Jump to search
Description
Pie and Piefilled drawing is distorted in two ways. Firstly the angles are not drawn precisely and are skewed. Secondly when the diameter of the Pie is greater than or equal to 656 then the graphics will not flush and redraw correctly. Running this code the red Pie segments are drawn by Piefilled and the black lines by formula. The black lines are in the correct positions for the angles requested, you will note that the pie segments are all skewed by a varying amount depending on the angle drawn.
Also if you set the radius variable to 656, let the graphics draw then minimize and restore the window you will see the graphics are completely destroyed.
Example code to demonstrate the bug.
nomainwin open "test" for graphics_nsb_fs as #gr #gr "trapclose [quit]" #gr "home" #gr "posxy x y" #gr "down" radius = 600 'radius = 656 #gr "color red" #gr "line ";x+radius/2;" ";y;" ";x;" ";y for angle = 0 to 360 step 30 #gr "backcolor red ; color yellow" #gr "piefilled ";radius;" ";radius;" ";angle;" ";15 next for angle = 0 to 360 step 15 r=radius/2 fi=angle/180*acs(-1) xx=x+r*cos(fi) yy=y+r*sin(fi) #gr "color black" #gr "line ";xx;" ";yy;" ";x;" ";y next #gr "flush" wait [quit] close #gr
Example code to work around the bug.
'By tsh73
nomainwin
WindowWidth = 630
WindowHeight = 640
UpperLeftX = (DisplayWidth-WindowWidth)/2
UpperLeftY = (DisplayHeight-WindowHeight)/2
graphicbox #1.g, 10,10,600,600
open "Graph" for graphics_nf_nsb as #1
print #1, "trapclose [quit]"
global graphicboxDC
graphicboxDC=GetDC(hwnd(#1.g))
print #1.g, "home ; down ; fill white"
#1.g "posxy x y"
h = 600
#1.g "color red"
#1.g "backcolor yellow"
#1.g "line ";x+h/2;" ";y;" ";x;" ";y
for t = 0 to 360 step 5
#1.g "color black"
' #gr "pie ";h;" ";h;" ";t;" ";1
ret=piefilled("#1.g",h,h,t,1)
'1 degree pie sector
'line should run along starting side of sector.
r=h/2
fi=t/180*acs(-1)
xx=x+r*cos(fi)
yy=y+r*sin(fi)
#1.g "color red"
#1.g "line ";xx;" ";yy;" ";x;" ";y
call pause
next
'and one example of non-filled pie
#1.g "color blue; size 2"
ret=pie("#1.g",600,600,n,10)
wait
[quit]
close #1
end
sub pause
timer 100, [up]
wait
[up]
timer 0
end sub
'=============================Window and DC functions=================================
Function GetDC(hWnd)
CallDLL #user32, "GetDC",_
hWnd As Ulong,_ 'window or control handle
GetDC As Ulong 'returns device context
End Function
Function piefilled(h$,w,h,ang1,ang2)
#h$ "posxy x y"
ulX=int(x-w/2)
ulY=int(y-h/2)
lrX=int(ulX+w)
lrY=int(ulY+h)
'in LB, ang2 is delta. Goes clockwise if >0, backwards if <
ang2 = ang1+ang2
'it looks it works only if ang1>ang2 (GDI draw counterclockwise)?: hence hack:
if ang1<ang2 then tmp = ang1:ang1=ang2:ang2=tmp
w2=w/2
h2=h/2
a1=ang1/180*acs(-1)
xxS=int(x+w2*cos(a1))
yyS=int(y+h2*sin(a1))
a2=ang2/180*acs(-1)
xxE=int(x+w2*cos(a2))
yyE=int(y+h2*sin(a2))
CallDll #gdi32, "Pie",_
graphicboxDC as ulong,_ 'device context
ulX as long,_ 'upper left x origin
ulY as long,_ 'upper left y origin
lrX as long,_ 'lower right x extent point
lrY as long,_ 'lower right y extent point
xxS as long,_ 'start arc here X
yyS as long,_ 'start arc here Y
xxE as long,_ 'end arc here X
yyE as long,_ 'end arc here Y
result as boolean 'nonzero if successful
end function
Function pie(h$,w,h,ang1,ang2)
#h$ "posxy x y"
ulX=int(x-w/2)
ulY=int(y-h/2)
lrX=int(ulX+w)
lrY=int(ulY+h)
'in LB, ang2 is delta. Goes clockwise if >0, backwards if <
ang2 = ang1+ang2
'it looks it works only if ang1>ang2 (GDI draw counterclockwise)?: hence hack:
if ang1<ang2 then tmp = ang1:ang1=ang2:ang2=tmp
w2=w/2
h2=h/2
a1=ang1/180*acs(-1)
xxS=int(x+w2*cos(a1))
yyS=int(y+h2*sin(a1))
a2=ang2/180*acs(-1)
xxE=int(x+w2*cos(a2))
yyE=int(y+h2*sin(a2))
#h$ "line ";xxS;" ";yyS;" ";x;" ";y
#h$ "line ";xxE;" ";yyE;" ";x;" ";y
CallDll #gdi32, "Arc",_
graphicboxDC as ulong,_ 'device context
ulX as long,_ 'upper left x origin
ulY as long,_ 'upper left y origin
lrX as long,_ 'lower right x extent point
lrY as long,_ 'lower right y extent point
xxS as long,_ 'start arc here X
yyS as long,_ 'start arc here Y
xxE as long,_ 'end arc here X
yyE as long,_ 'end arc here Y
result as boolean 'nonzero if successful
end function