How to draw a 2D array of data in MFC
Hello,
I have a circle of data that is represented as:
vector<vector <unsigned char> >* data;
The first dimension of this vector is the angle of the data so there are 360 angles, and the second dimension is the bins of the data in which there are 512 bins per angle. Each bin has a value from 0 to 15 to determine the intensity of the bin. So basically, when this is all display, there will be a circle of data, with varying colors of intensity at each bin.
What is the best approach to doing this in MFC? Can anyone provide sample code on how they would draw this on the screen?
Regards,
Ellay K.
Re: How to draw a 2D array of data in MFC
If I understood what you want, the basic idea would be to calculate
the points of the polygon for each angle/bin, and fill it with the
appropriate color. The code below should calculate the points:
Code:
const int n_angles = 360;
const int n_bins = 512;
const double radius = 100.0; // size of circle on screen
const double angle_inc = 2.0 * 3.14159 / static_cast<double>(n_angles);
const double bin_inc = radius / static_cast<double>(n_bins);
for (int i=0; i<n_angles; ++i)
{
for (int j=0; j<n_bins; ++j)
{
double angle1 = angle_inc * i;
double angle2 = angle_inc * (i+1);
double r1 = bin_inc * j;
double r2 = bin_inc * (j+1);
double x1 = r1 * cos(angle1);
double y1 = r1 * sin(angle1);
double x2 = r2 * cos(angle1);
double y2 = r2 * sin(angle1);
double x3 = r2 * cos(angle2);
double y3 = r2 * sin(angle2);
double x4 = r1 * cos(angle2);
double y4 = r1 * sin(angle2);
// fill in the polygon consisting of the points:
// (x1,y1) , (x2,y2) , (x3,y3) , (x4,y4)
}
}
It can be made a bit more efficient, since the code above re-calculates
some sin/cos values more than it needs to.
(Code not tested).
Re: How to draw a 2D array of data in MFC
Thanks for the response. I took this code, and I tried to make it work, but nothing was displaying on the screen. So I started debugging the points, and here is an example of my 4 points:
(0, 0)
(1, 0)
(1, 0)
(0, 0)
So I guess something is incorrect with the math.
Here is my code:
Code:
for(int i=0; i<angles; ++i)
{
for(int j=0; j<bins; ++j)
{
double angle1 = angle_inc * i;
double angle2 = angle_inc * (i+1);
double r1 = bin_inc * j;
double r2 = bin_inc * (j+1);
CPoint pts[4];
pts[0].x = r1 * cos(angle1);
pts[0].y = r1 * sin(angle1);
pts[1].x = r2 * cos(angle1);
pts[1].y = r2 * sin(angle1);
pts[2].x = r2 * cos(angle2);
pts[2].y = r2 * sin(angle2);
pts[3].x = r1 * cos(angle2);
pts[3].y = r1 * sin(angle2);
// fill in the polygon consisting of the points:
// (x1,y1) , (x2,y2) , (x3,y3) , (x4,y4)
CRgn region;
region.CreatePolygonRgn(pts, 4, ALTERNATE);
CBrush blueBrush;
blueBrush.CreateSolidBrush(RGB(0, 0, 255));
dcMemory.FillRgn(®ion, &blueBrush);
}
}
Any idea what is wrong?
Thanks!
Re: How to draw a 2D array of data in MFC
CPoint stores x and y values as type ints. The result of
Code:
pts[0].x = r1 * cos(angle1);
is a double which is then stored into an int! If you look at the first few values actually calculated as double before being stored, they have values between about 0 and 1 - so are stored in pts as 0 and 1 when converted to int!
1 Attachment(s)
Re: How to draw a 2D array of data in MFC
As 2kaud mentioned, there will be some problems with int versus double.
What are your values for angles , bins , bin_inc , and , angle_inc ?
I am a bit concerned that with that many bins/angle combinations, you
could get a number of points which should be distinct (as double) becoming
the same when converted to int.
Attached is a sample image I made using OpenGL() graphics with 25 angles
and 25 bins and using random colors. Is this the type of plot you want ?
Attachment 31487
Re: How to draw a 2D array of data in MFC
What type should I use then to pass to CreatePolygonRgn() ? It takes LPPOINT's which are longs. Can I pass doubles to them?
Thanks
Re: How to draw a 2D array of data in MFC
Hello Phillip,
The data I am attempting to plot is coming from a radar, if that helps.
Re: How to draw a 2D array of data in MFC
From my previous post :
What are your values for angles , bins , bin_inc , and , angle_inc ?
I used your code with a few minor changes and it worked.
1) I did not use dcMemory
2) I offset the circle by the radius, since it looks like (0,0) is the
top left corner of the window using the default graphics.
Re: How to draw a 2D array of data in MFC
Can you post the code that has the changes you made?
I don't have my code here to post those values for the variables, but I will post them as soon as I can.
Thanks!
Re: How to draw a 2D array of data in MFC
Code:
void CMyView::OnDraw(CDC* pDC)
{
CviewDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: add draw code for native data here
int angles = 360;
int bins = 512;
const double radius = 100.0; // size of circle on screen
const double angle_inc = 2.0*3.14159267 / static_cast<double>(angles);
const double bin_inc = radius / static_cast<double>(bins);
const double xcenter = radius;
const double ycenter = radius;
for(int i=0; i<angles; ++i)
{
for(int j=0; j<bins; ++j)
{
double angle1 = angle_inc * i;
double angle2 = angle_inc * (i+1);
double r1 = bin_inc * j;
double r2 = bin_inc * (j+1);
CPoint pts[4];
pts[0].x = xcenter + r1 * cos(angle1);
pts[0].y = ycenter + r1 * sin(angle1);
pts[1].x = xcenter + r2 * cos(angle1);
pts[1].y = ycenter + r2 * sin(angle1);
pts[2].x = xcenter + r2 * cos(angle2);
pts[2].y = ycenter + r2 * sin(angle2);
pts[3].x = xcenter + r1 * cos(angle2);
pts[3].y = ycenter + r1 * sin(angle2);
// fill in the polygon consisting of the points:
// (x1,y1) , (x2,y2) , (x3,y3) , (x4,y4)
CRgn region;
region.CreatePolygonRgn(pts, 4, ALTERNATE);
CBrush blueBrush;
blueBrush.CreateSolidBrush(RGB(0, 0, 255));
pDC->FillRgn(®ion, &blueBrush);
}
}
}
This is very slow. I assume that using dcMemory speeds it up considerably.
If not, you might consider a higher performance graphics system.
You mentioned radar. That could mean a lot of things when it comes to
visualization. One way to speed it up. Just draw the basic outline, and
only draw the pixels that have something in it.
Re: How to draw a 2D array of data in MFC
Hello Philip,
Is it possible you can zip up your sample project and post it here? For some reason nothing is displaying correctly for me.
I also sent you a private message if you get a chance to read it.
I really appreciate your help.
By the way here are the values you asked for:
window size is 973, so radius is 973/2
#bins: 1024
#angles: 360
j = 0
angle1 = 0.00000000000000000
angle2 = 0.017453292611111112
r1 = 0.00000000000000000
r2 = 0.47460937500000000
pts: (486,486), (486,486), (486,486), (486,486)
j = 1
angle1 = 0.00000000000000000
angle2 = 0.017453292611111112
r1 = 0.47460937500000000
r2 = 0.94921875000000000
pts: (486,486), (486,486), (486,486), (486,486)
j = 2
angle1 = 0.00000000000000000
angle2 = 0.017453292611111112
r1 = 0.94921875000000000
r2 = 1.4238281250000000
pts: (486,486), (487,486), (487,486), (486,486)
j = 3
angle1 = 0.00000000000000000
angle2 = 0.017453292611111112
r1 = 1.4238281250000000
r2 = 1.8984375000000000
pts: (487,486), (487,486), (487,486), (487,486)
Do these seem correct?
Thanks!
1 Attachment(s)
Re: How to draw a 2D array of data in MFC
Attached.
Why not try angles = 25 and bins = 25 ? This will check that
CreatePolygonRgn/FillRgn can handle degenerate polygons.
I would guess that you would not use the full 360 x 1024 anyway.
You can plot a subset and get good results.
Re: How to draw a 2D array of data in MFC
Hello Philip,
Ok I made some progress. I got it to display if I use dc, but not when I use dcMemory. So this code works:
Code:
CPaintDC dc(this);
...
CRgn region;
region.CreatePolygonRgn(pts, 4, ALTERNATE);
CBrush blueBrush;
blueBrush.CreateSolidBrush(RGB(0, 0, 255));
dc.FillRgn(®ion, &blueBrush);
While this code does not draw anything:
Code:
CPaintDC dc(this);
CDC dcMemory;
dcMemory.CreateCompatibleDC(&dc);
...
CRgn region;
region.CreatePolygonRgn(pts, 4, ALTERNATE);
CBrush blueBrush;
blueBrush.CreateSolidBrush(RGB(0, 0, 255));
dcMemory.FillRgn(®ion, &blueBrush);
I am guessing that this happens as dcMemory can only work with functions such as BitBlt?
Thanks!