CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 13 of 13
  1. #1
    Join Date
    Mar 2009
    Posts
    166

    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.

  2. #2
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    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).

  3. #3
    Join Date
    Mar 2009
    Posts
    166

    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(&region, &blueBrush);
    		   }
    		}
    Any idea what is wrong?

    Thanks!

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: How to draw a 2D array of data in MFC

    Code:
    CPoint pts[4];
    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!
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    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 ?

    Name:  circle.jpg
Views: 1412
Size:  72.2 KB

  6. #6
    Join Date
    Mar 2009
    Posts
    166

    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

  7. #7
    Join Date
    Mar 2009
    Posts
    166

    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.

  8. #8
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    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.

  9. #9
    Join Date
    Mar 2009
    Posts
    166

    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!

  10. #10
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    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(&region, &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.

  11. #11
    Join Date
    Mar 2009
    Posts
    166

    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!
    Last edited by ekhule; June 3rd, 2013 at 06:28 PM.

  12. #12
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    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.
    Attached Files Attached Files

  13. #13
    Join Date
    Mar 2009
    Posts
    166

    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(&region, &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(&region, &blueBrush);
    I am guessing that this happens as dcMemory can only work with functions such as BitBlt?

    Thanks!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured