Solved

Help on graphics

Posted on 2000-03-01
12
172 Views
Last Modified: 2013-11-20
I'm writting an application in which I have to plot a 2D array. The first
approach I took was to scan each row and to display the value of each column:

for (i=0;i<nrows;i++)
{      
      pDC->MoveTo(x,y);
      for (j=0;j<ncols;j++)
      {      
            value=data[i][j];
            pDC->LineTo(x,y);
      }
}

This method works fine but I get a representation like the following:



-----------------------
---*-------------------
---*------------*------
--*-*----------*-*-----
--*-*---------*---*----
------*------*-----*---
-----*-*---------------
-----*-*---------------
-----------*-----------
----------*-*----------
---------*---*---------
-------*------*--------


and what I need is to get something like this:


-----------------------
---*-------------------
---*------------*------
--* *----------* *-----
--* *---------*   *----
------*------*     *---
-----* *---------------
-----* *---------------
-----------*-----------
----------* *----------
---------*   *---------
-------*      *--------

Can any one give me some light? I think I should use some hidden surface
algorithm but I don't know how to implement it.

TIA
0
Comment
Question by:qocarlos
  • 4
  • 3
  • 2
  • +3
12 Comments
 
LVL 8

Expert Comment

by:gelbert
ID: 2574032
Try to use CDC::PolyPolygon(). They would draw whatever shape you have based on array and fill in with specified color.The current polygon-filling mode can be retrieved or set by using the GetPolyFillMode and SetPolyFillMode member functions.

 
0
 
LVL 1

Expert Comment

by:Binder
ID: 2574039
 Hello,

     I dont´t think you need a hidden surface algorithm here. You can
solve this problem by verifiyng that each opening * has a corresponding
closing *. Between them you don´t need to draw your lines.
0
 
LVL 8

Expert Comment

by:gelbert
ID: 2574044
I could not find samples for PolyPolygon() but you can take a look at MFC samples DRAWCLI(drawvw.cpp) & OLEVIEW(shadow.cpp) which use Polygon()
0
 
LVL 3

Author Comment

by:qocarlos
ID: 2574371
Thanks for the comments.
I will try the PolyPolygon() function.
Please, check out the following page:
http://qobrue.usc.es/graphics/graphic.htm

I've put there two graphics showing what I'm trying to do.
I think the difference between both plots is evident.
The effect shown in plot labeled "WhiteWash" is what I need to get.

Thanks again for all your help


0
 
LVL 8

Expert Comment

by:VinExpert
ID: 2575532
Hi,

I feel the only difference is the lines in between the starts, That U dont want right?.
If yes, then, have one more storage area which tells U that, that perticular row is having more than one * to plot. U can get that by scanning the array once. Then, if u need to plot more than one * per row, and if already one * has been plotted, then dont call LineTo till another * is plotted. This U can do using a simple flag.

The extra array will indicate whether that row contains more than one *, right?. Then whenver U plot *, set that flag to TRUE, then dont call LineTo if it is TRUE, then When U plot the next *, set it back to FALSE......
like that the logic goes.

Try it out.

VinExpert
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 2575688
Hi qocarlos,

I do not think that CDC::Polygon() allone will solve this, because you don't want a closed polygon to be drawn. So, I would suggest you to use CDC::Polygon() to 'undraw' before drawing with your code like this:

....
CPen *pOldPen;
CArray <POINT, POINT&> points;
points.SetSize( nCol );
for (i=0;i<nrows;i++)
{
 pOldPen = pDC->SelectStockObject( NULL_PEN );
 for (j=0;j<ncols;j++)
 {
  value=data[i][j];
  points[j].x = //here calculate x
  points[j].y = //and y from value
 }
 pDC->Polygon( points.GetData(), point.GetSize() );

 pDC->SelectObject( pOldPen );
// since here it's your previous code
 pDC->MoveTo(x,y);
 for (j=0;j<ncols;j++)
 {
  value=data[i][j];
  pDC->LineTo(x,y);
 }
}

hope that helps,

ZOPPO
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 31

Expert Comment

by:Zoppo
ID: 2575698
excuse me, I forgot the brush:

....
CBrush *pOldBrush = (CBrush*)pDC->SelectStockObject( NULL_BRUSH );
pDC->Polygon( points.GetData(), point.GetSize() );
pDC->SelectObject( pOldBrush );
....

and even forgot that you'll have to cast the pen like this:

....
pOldPen = (CPen*)pDC->SelectStockObject( NULL_PEN );
....

sorry,

ZOPPO
0
 
LVL 1

Expert Comment

by:ElmerFud
ID: 2576281
The only real way to do this is to draw the lines from the top down.

I would go with the hidden surface algorithm.

First, start a second CDC object.  Then draw a large rectangle on the unseen CDC.  Next, draw one of the array traces.  Fill the upper part of the divided rectange with an odd color that you don't wish to you.  Finally bitblt the unseen object ontop of the seen object and specify that the odd color is to be trasparent.

It may sound quite complicated, but I know it could be done.  For the 500 points, I'd be willing to work on your project with you.  I don't expect it would take more than an hour to add to what you've got.  If you're interested email me at roberthamilton@usa.com
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 2577136
Hi,

I've tested my previous suggestion some time and made some corrections:

CPen *pOldPen;
CArray <POINT, POINT&> points;
points.SetSize( nCol+2 );
for (i=0;i<nrows;i++)
{
 pOldPen = pDC->SelectStockObject( NULL_PEN );
 for (j=0;j<ncols;j++)
 {
  value=data[i][j];
  points[j+1].x = //here calculate x
  points[j+1].y = //and y from value
 }
 points[0].x = 0;
 points[0].y = ymin; // set this y min to the y coordinate of the lower edge of the window
 points[ncols+1].x = point[ncols].x;
 points[ncols+1].y = ymin;

 CBrush *pOldBrush = (CBrush*)pDC->SelectStockObject( WHITE_BRUSH ); // we need a white brush instead a null brush of course...
 pDC->Polygon( points.GetData(), point.GetSize() );
 pDC->SelectObject( pOldBrush );
 pDC->SelectObject( pOldPen );
 // since here it's your previous code
 pDC->MoveTo(x,y);
 for (j=0;j<ncols;j++)
 {
  value=data[i][j];
  pDC->LineTo(x,y);
 }
}

ZOPPO
0
 
LVL 3

Author Comment

by:qocarlos
ID: 2577297
Hi,
Thanks to all for your really useful comments. I have implemented Zoppo solution and it worked really great.
So, Zoppo, I will award you the points. Just drop a blank answer and the points will be yours. Thanks a lot.
I have used your first comments but I didn't select any brush into the device context and used Polyline() rather than LineTo and MoveTo because it's much faster.
If I select a white brush, it also works. Do you know if this presents any advantage?

Thanks again,
Carlos
0
 
LVL 31

Accepted Solution

by:
Zoppo earned 500 total points
ID: 2579273
Hi qocarlos,

I think it doesn't mind as long a white brush is the default brush of a dc with white backgroud ... perhaps better way would be to retrieve the backgroud color of the device context and create a brush and a pen with this color and use these to undraw the area before drawing the line itself...

ZOPPO
0
 
LVL 3

Author Comment

by:qocarlos
ID: 2581068
Hi Zoppo,
Thanks a lot for all your help.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now