Error when drawing grid, grid lines a bit too short

Hello, as I've mentioned in some other post I'm making a simple "Game of 
  Life" with a small, fixed-sized grid. Anyway, the function I used for 
drawing the actual grid was written ages ago when doing some pure Win32 
programming and it was full of magic numbers, assuming a 16*16 grid. I 
tried to rewrite it without magic numbers and to take the actual size 
into consideration. Right now each cell in the grid is 20*20 and I have 
horizontal and vertical bars that are four pixels wide. The x and y 
offset is 20 pixels.

Hope I explained it properly, here's the code:

void MyView::DrawGrid(CDC *dc)
{
    static const int cell_width  = 20;
    static const int cell_height = 20;

    static const int initial_x_offset = 20;
    static const int initial_y_offset = 20;

    static const int grid_bar_thickness = 4;
    static CPen pen(PS_SOLID, grid_bar_thickness, RGB(0x00, 0x00, 0xFF));

    dc->SelectObject(&pen);

    /* Drawing vertical lines. */
    int x = initial_x_offset;
    int y = initial_y_offset;

    for (int i = 0; i < (num_cols_ + 1); ++i)
    {
       dc->MoveTo(x, y);
       dc->LineTo(x, grid_bar_thickness * (num_rows_ + 1) + num_rows_ * 
cell_height);

       x += cell_width + grid_bar_thickness;
    }

    /* Drawing horizontal lines. */
    x = initial_x_offset;
    y = initial_y_offset;

    for (int i = 0; i < (num_rows_ + 1); ++i)
    {
       dc->MoveTo(x, y);
       dc->LineTo(grid_bar_thickness * (num_cols_ + 1) + num_cols_ * 
cell_width, y);

       y += cell_height + grid_bar_thickness;
    }
}

I'm testing a grid with 16 rows and 18 columns. I suspect I'm missing to 
take something into account when calling LineTo() because the grid lines 
are not as long as they should be, neither vertically nor horizontally.
Here's a screenshot of how it looks:
http://student.stunet.se/hivemind/grid.png

Where am I going wrong here? I've made sure the values of num_rows_ and 
num_cols_ are correct using the debugger. Also, I'm getting the cells 
coordinates correct I just have problems with the grid lines. :)

- Eric
0
7/2/2007 7:30:03 PM
vc.mfc 33608 articles. 0 followers. Follow

3 Replies
462 Views

Similar Articles

[PageSpeed] 23

Ah, I forgot to take the x and y offsets into account. So I need add the 
offset and subtract the width of the grid line. So the code changes into:
for vertical grid lines:
dc->LineTo(x, (grid_bar_width * (num_rows_ + 1) + num_rows_ * 
cell_height) + initial_y_offset - grid_bar_width);
for horizontal grid lines:
dc->LineTo((grid_bar_width * (num_cols_ + 1) + num_cols_ * cell_width) + 
initial_x_offset - grid_bar_width, y);

renamed grid_bar_thickness to grid_bar_width.

- Eric

Eric Lilja wrote:
> Hello, as I've mentioned in some other post I'm making a simple "Game of 
>  Life" with a small, fixed-sized grid. Anyway, the function I used for 
> drawing the actual grid was written ages ago when doing some pure Win32 
> programming and it was full of magic numbers, assuming a 16*16 grid. I 
> tried to rewrite it without magic numbers and to take the actual size 
> into consideration. Right now each cell in the grid is 20*20 and I have 
> horizontal and vertical bars that are four pixels wide. The x and y 
> offset is 20 pixels.
> 
> Hope I explained it properly, here's the code:
> 
> void MyView::DrawGrid(CDC *dc)
> {
>    static const int cell_width  = 20;
>    static const int cell_height = 20;
> 
>    static const int initial_x_offset = 20;
>    static const int initial_y_offset = 20;
> 
>    static const int grid_bar_thickness = 4;
>    static CPen pen(PS_SOLID, grid_bar_thickness, RGB(0x00, 0x00, 0xFF));
> 
>    dc->SelectObject(&pen);
> 
>    /* Drawing vertical lines. */
>    int x = initial_x_offset;
>    int y = initial_y_offset;
> 
>    for (int i = 0; i < (num_cols_ + 1); ++i)
>    {
>       dc->MoveTo(x, y);
>       dc->LineTo(x, grid_bar_thickness * (num_rows_ + 1) + num_rows_ * 
> cell_height);
> 
>       x += cell_width + grid_bar_thickness;
>    }
> 
>    /* Drawing horizontal lines. */
>    x = initial_x_offset;
>    y = initial_y_offset;
> 
>    for (int i = 0; i < (num_rows_ + 1); ++i)
>    {
>       dc->MoveTo(x, y);
>       dc->LineTo(grid_bar_thickness * (num_cols_ + 1) + num_cols_ * 
> cell_width, y);
> 
>       y += cell_height + grid_bar_thickness;
>    }
> }
> 
> I'm testing a grid with 16 rows and 18 columns. I suspect I'm missing to 
> take something into account when calling LineTo() because the grid lines 
> are not as long as they should be, neither vertically nor horizontally.
> Here's a screenshot of how it looks:
> http://student.stunet.se/hivemind/grid.png
> 
> Where am I going wrong here? I've made sure the values of num_rows_ and 
> num_cols_ are correct using the debugger. Also, I'm getting the cells 
> coordinates correct I just have problems with the grid lines. :)
> 
> - Eric
0
7/2/2007 8:11:46 PM
See below...
On Mon, 02 Jul 2007 21:30:03 +0200, Eric Lilja <mindcoolerremoveme@gmail.com> wrote:

>Hello, as I've mentioned in some other post I'm making a simple "Game of 
>  Life" with a small, fixed-sized grid. Anyway, the function I used for 
>drawing the actual grid was written ages ago when doing some pure Win32 
>programming and it was full of magic numbers, assuming a 16*16 grid. I 
>tried to rewrite it without magic numbers and to take the actual size 
>into consideration. Right now each cell in the grid is 20*20 and I have 
>horizontal and vertical bars that are four pixels wide. The x and y 
>offset is 20 pixels.
>
>Hope I explained it properly, here's the code:
>
>void MyView::DrawGrid(CDC *dc)
>{
>    static const int cell_width  = 20;
>    static const int cell_height = 20;
>
>    static const int initial_x_offset = 20;
>    static const int initial_y_offset = 20;
>
>    static const int grid_bar_thickness = 4;
>    static CPen pen(PS_SOLID, grid_bar_thickness, RGB(0x00, 0x00, 0xFF));
>
>    dc->SelectObject(&pen);
>
>    /* Drawing vertical lines. */
>    int x = initial_x_offset;
>    int y = initial_y_offset;
>
>    for (int i = 0; i < (num_cols_ + 1); ++i)
>    {
>       dc->MoveTo(x, y);
>       dc->LineTo(x, grid_bar_thickness * (num_rows_ + 1) + num_rows_ * 
>cell_height);
****
Note that lines do not include the endpoint of the drawing.  So if you do a Lineto(10,20)
you will get a line to (9,19).  The debate about inclusive vs. exclusive has been going on
for years, and ultimately it is a coin-toss.  The inclusive drawing gives a *different*
set of problems and so you end up doing a lot of -1 adjustments for that choice, and a lot
of +1 adjustments for the exclusive technique.  The decision can easily be decided by
tossing a coin because whatever the outcome, there will be serious issues.
*****
>
>       x += cell_width + grid_bar_thickness;
>    }
>
>    /* Drawing horizontal lines. */
>    x = initial_x_offset;
>    y = initial_y_offset;
>
>    for (int i = 0; i < (num_rows_ + 1); ++i)
>    {
>       dc->MoveTo(x, y);
>       dc->LineTo(grid_bar_thickness * (num_cols_ + 1) + num_cols_ * 
>cell_width, y);
>
>       y += cell_height + grid_bar_thickness;
>    }
>}
>
>I'm testing a grid with 16 rows and 18 columns. I suspect I'm missing to 
>take something into account when calling LineTo() because the grid lines 
>are not as long as they should be, neither vertically nor horizontally.
>Here's a screenshot of how it looks:
>http://student.stunet.se/hivemind/grid.png
****
It looks like cumulative error caused by the off-by-1 issue.
*****
>
>Where am I going wrong here? I've made sure the values of num_rows_ and 
>num_cols_ are correct using the debugger. Also, I'm getting the cells 
>coordinates correct I just have problems with the grid lines. :)
>
>- Eric
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
0
newcomer (15975)
7/2/2007 8:23:17 PM
Thanks for the quick reply, Joseph, see below and my reply to myself 
that I wrote before I saw this.

Joseph M. Newcomer wrote:
> See below...
> On Mon, 02 Jul 2007 21:30:03 +0200, Eric Lilja <mindcoolerremoveme@gmail.com> wrote:
> 
>> Hello, as I've mentioned in some other post I'm making a simple "Game of 
>>  Life" with a small, fixed-sized grid. Anyway, the function I used for 
>> drawing the actual grid was written ages ago when doing some pure Win32 
>> programming and it was full of magic numbers, assuming a 16*16 grid. I 
>> tried to rewrite it without magic numbers and to take the actual size 
>> into consideration. Right now each cell in the grid is 20*20 and I have 
>> horizontal and vertical bars that are four pixels wide. The x and y 
>> offset is 20 pixels.
>>
>> Hope I explained it properly, here's the code:
>>
>> void MyView::DrawGrid(CDC *dc)
>> {
>>    static const int cell_width  = 20;
>>    static const int cell_height = 20;
>>
>>    static const int initial_x_offset = 20;
>>    static const int initial_y_offset = 20;
>>
>>    static const int grid_bar_thickness = 4;
>>    static CPen pen(PS_SOLID, grid_bar_thickness, RGB(0x00, 0x00, 0xFF));
>>
>>    dc->SelectObject(&pen);
>>
>>    /* Drawing vertical lines. */
>>    int x = initial_x_offset;
>>    int y = initial_y_offset;
>>
>>    for (int i = 0; i < (num_cols_ + 1); ++i)
>>    {
>>       dc->MoveTo(x, y);
>>       dc->LineTo(x, grid_bar_thickness * (num_rows_ + 1) + num_rows_ * 
>> cell_height);
> ****
> Note that lines do not include the endpoint of the drawing.  So if you do a Lineto(10,20)
> you will get a line to (9,19).  The debate about inclusive vs. exclusive has been going on
> for years, and ultimately it is a coin-toss.  The inclusive drawing gives a *different*
> set of problems and so you end up doing a lot of -1 adjustments for that choice, and a lot
> of +1 adjustments for the exclusive technique.  The decision can easily be decided by
> tossing a coin because whatever the outcome, there will be serious issues.
> *****
>>       x += cell_width + grid_bar_thickness;
>>    }
>>
>>    /* Drawing horizontal lines. */
>>    x = initial_x_offset;
>>    y = initial_y_offset;
>>
>>    for (int i = 0; i < (num_rows_ + 1); ++i)
>>    {
>>       dc->MoveTo(x, y);
>>       dc->LineTo(grid_bar_thickness * (num_cols_ + 1) + num_cols_ * 
>> cell_width, y);
>>
>>       y += cell_height + grid_bar_thickness;
>>    }
>> }
>>
>> I'm testing a grid with 16 rows and 18 columns. I suspect I'm missing to 
>> take something into account when calling LineTo() because the grid lines 
>> are not as long as they should be, neither vertically nor horizontally.
>> Here's a screenshot of how it looks:
>> http://student.stunet.se/hivemind/grid.png
> ****
> It looks like cumulative error caused by the off-by-1 issue.

Good point about LineTo() not drawing that endpoint, I can see it causes 
problems and I will try to remember to account for that when I use it 
next time. But say if everything else was correct wouldn't that mean in 
my case that my grid lines were one pixel too short? I don't see the 
accumulation taking place here. I did however forget to take into 
account the x and y offsets if you see my reply to myself. Also had to 
withdraw width of the grid line from the offset for it to look OK.


> *****
>> Where am I going wrong here? I've made sure the values of num_rows_ and 
>> num_cols_ are correct using the debugger. Also, I'm getting the cells 
>> coordinates correct I just have problems with the grid lines. :)
>>
>> - Eric
> Joseph M. Newcomer [MVP]
> email: newcomer@flounder.com
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm
0
7/2/2007 8:46:14 PM
Reply:

Similar Artilces: