bob323
Jan 23rd, 2002, 10:35 PM
strange question...
I want to create a piechart of 42 equal, individual sections, I need to use 42 calls to pie() rather than a pie chart control for some very strange reasons! The pie chart should take up the whole windowIf anyone has any ideas how to do this in a nice loop I would love to hear it, I have been mulling over my geometry book for the last while...
CornedBee
Jan 24th, 2002, 08:06 AM
There is a Pie function in API. I'll try to write something to demonstrate it's uses.
CornedBee
Jan 24th, 2002, 10:53 AM
Finished. I attached the cpp file. Basically it's C code but with some C++ syntax, so it won't compile on a C compiler.
This is of course only a rude example. You should add color (maybe an array of COLORREF values that go along with the pies) and description.
bob323
Jan 24th, 2002, 03:45 PM
cool this makes sense... but one small problem I want to create * degree sections that means 360/8= 45 pieces, but when I put in:
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
{
// an array of percentages
float ar[45];
for(i=0;i<=45;i++)
ar[i]= 8f;
I get like 21 sections, any idea how to fix that one?
CornedBee
Jan 25th, 2002, 03:08 AM
Syntactical error!!!
for(i=0;i<=45;i+)
is wrong! The highest allowed index is always the size of the array - 1 (in your case 44). You must use <45, not <=45.
And as I said, the array contains percentual values! If you want 45 pieces, you must use 100/45 (= 2.222222f) as values for the array members.
bob323
Jan 27th, 2002, 10:43 PM
humm I get what you did and made it a little more object oriented, (just so I could be sure I understood it :)) I made the individual sections objects.
One last question, how do I shrink or expand individual sections of the pie, I want to randomly make them longer or shorter? I know this is a bit of a strange idea, I have made a few tries at it but I'm not getting it all it does for me is change the width.
Any ideas how to change the length of sections?
#define STRICT
#include <windows.h>
#include <math.h>
#include <time.h>
#define CSECTSIZE 2.22222222f
#define NUMOFSEC 45
class CSect {
private:
int vect1x;
int vect1y;
int vect2x;
int vect2y;
int recttx;
int rectty;
int rectbx;
int rectby;
HBRUSH hbrush;
public:
SetRect(int,int,int,int);
SetVect(int,int,int,int);
DecVect();
IncVect();
SetBrush(COLORREF);
DrawSect(HDC*);
};
CSect::SetBrush(COLORREF Color){
LOGBRUSH logbrush;
logbrush.lbStyle = BS_SOLID;
logbrush.lbColor = Color;
hbrush = CreateBrushIndirect(&logbrush);
}
CSect::SetVect(int x1,int y1, int x2,int y2){
vect1x = x1;
vect1y = y1;
vect2x = x2;
vect2y = y2;
}
CSect::SetRect(int tx,int ty, int bx, int by){
recttx = tx;
rectty = ty;
rectbx = bx;
rectby = by;
}
CSect::IncVect(){
vect1y+=5;
vect2y+=5;
}
CSect::DecVect(){
vect1y-=5;
vect2y-=5;
}
CSect::DrawSect(HDC *hdc){
SelectObject(*hdc, hbrush);
Pie(*hdc,recttx, rectty, rectbx, rectby,
vect2x, vect2y, vect1x, vect1y);
}
typedef struct tagFPOINT{
float x, y;
} FPOINT, *PFPOINT;
template<class T>
inline T tmin(T a, T b){
return (a < b) ? a : b;
}
template<>
inline char* tmin(char* a, char* b){
return (lstrcmp(a, b) > 0) ? b : a;
}
const float PI = 3.1415926535f;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void SectInitVects(float arfPiePercents, RECT rcArea, CSect sections[]);
void SetSection(CSect sections[], float *lastAngle,FPOINT ptMid,float radius,int i);
LPCSTR szClassName = "Mod- 5";
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR szCmdLine, int iShowCmd){
MSG msg;
HWND hWnd;
WNDCLASS wc;
memset(&wc, 0, sizeof(WNDCLASS));
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = szClassName;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
hWnd = CreateWindow(szClassName, szClassName, WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, iShowCmd);
UpdateWindow(hWnd);
while(GetMessage(&msg, NULL, 0, 0) > 0){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (msg.wParam);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
PAINTSTRUCT ps;
HDC hdc;
int i;
static RECT rc;
static CSect sections [NUMOFSEC];
static BOOLEAN sized;
static COLORREF Color;
switch(message){
case WM_CREATE:
GetClientRect(hwnd, &rc);
// an array of percentages
for(i=0;i<NUMOFSEC;i++){
sections[i].SetRect(rc.left, rc.top, rc.right, rc.bottom);
Color= RGB(rand() % 255,rand() % 255,rand() % 255);
sections[i].SetBrush(Color);
}
SectInitVects(CSECTSIZE, rc, sections);
SetTimer(hwnd,1,1000,NULL);
return (0);
case WM_TIMER:
srand(time(NULL));
sections[(rand()% NUMOFSEC)].IncVect();
sections[(rand()% NUMOFSEC)].DecVect();
InvalidateRect(hwnd,NULL,TRUE);
return(0);
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
{
for(i=0;i<NUMOFSEC;i++)
sections[i].DrawSect(&hdc);
}
EndPaint(hwnd, &ps);
return (0);
case WM_DESTROY:
PostQuitMessage(0);
return (0);
}
return (DefWindowProc(hwnd, message, wParam, lParam));
}
// disable the "double to float conversion" warning
#pragma warning(push)
#pragma warning(disable: 4244)
void SectInitVects(float arfPiePercents, RECT rcArea, CSect sections[]){
float radius;
float lastAngle =0.0f;// the two angles that make up the pie
SIZE sizeArea;
FPOINT ptMid;
int i;
// calculate the size of the rectangle
sizeArea.cx = rcArea.right - rcArea.left;
sizeArea.cy = rcArea.bottom - rcArea.top;
// calculate the center of the area
ptMid.x = rcArea.left + sizeArea.cx / 2;
ptMid.y = rcArea.top + sizeArea.cy / 2;
// radius of ellpise
radius = (float)(rcArea.right - rcArea.left) / 2;
/*Draw the pie sections*/
for(i = 0; i < NUMOFSEC; i++)
SetSection(sections,&lastAngle,ptMid,radius,i);
}
void SetSection(CSect sections[], float *lastAngle,FPOINT ptMid,float radius,int i){
static float nextAngle;
static FPOINT fptStart, fptEnd;// start point and end point of pie, actually the
// calculate next radian
// it is old radian + radians that next pie needs
// those are full circle * (percentage/100)
nextAngle = *lastAngle + ((2 * PI) * (CSECTSIZE / 100.0f));
// calculate x and y of start point
fptStart.x = ptMid.x + (cos(*lastAngle) * radius);
fptStart.y = ptMid.y + (sin(*lastAngle) * radius);
// and of end point
fptEnd.x = ptMid.x + (cos(nextAngle) * radius);
fptEnd.y = ptMid.y + (sin(nextAngle) * radius);
sections[i].SetVect((int)fptStart.x, (int)fptStart.y,
(int)fptEnd.x, (int)fptEnd.y);
// now set new angles
*lastAngle = nextAngle;
}
#pragma warning(pop)
CornedBee
Jan 28th, 2002, 07:47 AM
You mean that they sort of "come out" of the chart? Like a pie piece that is taken away from the whole thing? You'd need to make the bounding rectangle bigger for this special pie. For example:
// add this function to your CSect class:
void CSect::MoveOut()
{
recttx -= 10;
rectty -= 10;
rectbx += 10;
rectby += 10;
}
Then redraw the chart.