Drawing A Pie Chart
Here's an example show a way to drawing a pie chart. The first builds a direction table from 0 to 360 degrees. When we render the chart we step through the 2D array of pixels and computes the direction between the middle of the graphic and the current point. The angle is then used to grab the colour from the table so we can plot the segment colour. Simple enough and gives a fairly reasonable result.
Another method is to use polygons to draw pie fragments, then mask the excess off the same way.
GetAngle Version
[pbcode]
// ------------------------------------------------------------------------
// --[SETUP]----------------------------------------------------------------
// ------------------------------------------------------------------------
#include "blitimage"
loadfont "veranda",1,28
; Create an image we'll be renderinb the chart on to
Image=NewImage(256,256,2)
MaskImage=NewIMage(256,256,2)
IMageMaskCOlour MaskIMage,$ff000000
; create a circle mask. This is used to shape the final
; chart image. Saves having to compute the spans yourself
rendertoimage MaskImage
cls 0
circlec 128,128,128,true,$ffffffff
; each direction (0 to 359) is mapped with a colour in that direction
; so the render loop just computes the angle between the current point
; and the middle of the chart. Then it uses this angle to grab the
; the colour from this table..
Dim ColourDirection(360)
Setfps 5
// ------------------------------------------------------------------------
// --[MAIN]----------------------------------------------------------------
// ------------------------------------------------------------------------
Do
// Render the screen
rendertoscreen
cls $304050
// randomly create the direction table and render the percentages
// Each segement in the chart and be between 5 and 90 degrees.
Segments=0
Angle=0
repeat
SegmentSize=rndrange(5,90)
ThisColour=RndRGB()
AngleEnd=cliprange(Angle+SegmentSize,0,360)
SegmentSize=AngleEnd-Angle
Info$="#"+digits$(Segments,2)+" = %"+str$(360.0/SegmentSize)
Ypos1=100+GetTextHeight("|")*Segments
Ypos2=100+GetTextHeight("|")*(Segments+1)
Text 400,Ypos1,Info$
boxc 400,ypos1,400+(ypos2-ypos1),ypos2,true,ThisCOlour
For lp=Angle to AngleEnd
ColourDirection(lp)=ThisColour
next
Angle=AngleEnd
Segments++
until Angle=>360
rendertoimage Image
Cx=128
Cy=128
lockbuffer
thispoint=Point(0,0)
For ylp=0 to 255
For xlp=0 to 255
Angle=getangle2d(xlp,ylp,cx,cy)
fastDot xlp,ylp,ColourDirection(Angle)
next
next
unlockbuffer
// mult the RGB values from the MASK image over the chart image
BlitImageAlphaMultImage(Image,0,0,MaskIMage)
// set output to the screen
rendertoscreen
// draw the Pie chart
drawimage image,100,100,true
// draw a message under it
centertext 100+GetImageWidth(Image)/2,100+GetIMageHeight(image)+10,"Pie Chart"
Sync
loop
[/pbcode]
Polygon Version
[pbcode]
// ------------------------------------------------------------------------
// --[SETUP]----------------------------------------------------------------
// ------------------------------------------------------------------------
#include "blitimage"
loadfont "veranda",1,28
; Create an image we'll be renderinb the chart on to
Image=NewImage(256,256,2)
MaskImage=NewIMage(256,256,2)
IMageMaskCOlour MaskIMage,$ff000000
; create a circle mask. This is used to shape the final
; chart image. Saves having to compute the spans yourself
rendertoimage MaskImage
cls 0
circlec 128,128,128,true,$ffffffff
// ------------------------------------------------------------------------
// --[SEGMENT LIST]--------------------------------------------------------
// ------------------------------------------------------------------------
Type SegmentInfo
Size
Colour
endtype
Dim Segs(360) as segmentINfo
Setfps 5
// ------------------------------------------------------------------------
// --[MAIN]----------------------------------------------------------------
// ------------------------------------------------------------------------
Do
// Render the screen
rendertoscreen
cls $304050
// randomly create the direction table and render the percentages
// randomly make the chart so each segment in the is between 5 and 90 degrees.
Segments=0
Angle=0
repeat
SegmentSize =rndrange(5,90)
ThisColour =RndRGB()
AngleEnd =cliprange(Angle+SegmentSize,0,360)
SegmentSize =AngleEnd-Angle
Segs(Segments).size=SegmentSize
Segs(Segments).colour=ThisColour
Info$="#"+digits$(Segments,2)+" = %"+str$(360.0/SegmentSize)
Ypos1=100+GetTextHeight("|")*Segments
Ypos2=100+GetTextHeight("|")*(Segments+1)
Text 400,Ypos1,Info$
boxc 400,ypos1,400+(ypos2-ypos1),ypos2,true,ThisCOlour
Angle=AngleEnd
Segments++
until Angle=>360
rendertoimage Image
lockbuffer
Angle=0
x1=128+Cos(Angle)*300
y1=128+Sin(Angle)*300
For lp =0 to Segments
Size =Segs(lp).size
ThisColour =Segs(lp).colour
Angle+=Size
x2=128+Cos(Angle)*300
y2=128+Sin(Angle)*300
tric 128,128,x1,y1,x2,y2,ThisCOlour
x1=x2
y1=y2
next
unlockbuffer
// mult the RGB values from the MASK image over the chart image
BlitImageAlphaMultImage(Image,0,0,MaskIMage)
// set output to the screen
rendertoscreen
// draw the Pie chart
drawimage image,100,100,true
// draw a message under it
centertext 100+GetImageWidth(Image)/2,100+GetIMageHeight(image)+10,"Pie Chart"
Sync
loop
[/pbcode]
Related Articles:
* Kaleidoscope (optimized) (http://www.underwaredesign.com/forums/index.php?topic=4111.0)