## Project3: Visibility on terrains

Grids

The goal of this project is to compute the viewshed of a point on a grid terrain.

• The input: Your code will take as input the name of an elevation grid, in ascii form, the coordinates (r,c) of the viewpoint, and the name of the output viewshed grid. For example,
[ltoma@dover:\~] ./viewshed test2.asc test2vis.asc 5 7

This will read elevation grid test2.asc, compute the viewshed of viewpoint at row=5 and col=7 and save it as grid test2vis.asc.

The elevation grid is assumed to be in the asciiformat.

• The output: Your code will compute and output the viewshed of the given viewpoint. The viewshed grid has the same size as the elevation grid. A point in the viewshed grid can have one or three values:

• NODATA (if the input point is NODATA)
• 0 if the point is not visible
• 1 if the point is visible.

The output viewshed grid (in the exampel above, test2vis.asc) has to be written in the ascii format as well.

• Algorithm: Implement the (straightforward) O(n \sqrt n) algorithm discussed in class, with linear interpolation.

## Outline

I have a couple of suggestions for how to organize your code.
• Have a function that creates and initializes a viewshed grid of the same size as the elevation grid. This function could also initialize the viewshed grid with NODATA (if the elevation of that point is NODATA), and the remaining values with, say, 0 (i.e. by default everything is invisible).

• For this assignment we'll use the row-major layout, so you could set the data_blocked to be NULL; however design your code so that you could easily switch to using the blocked layout at a later date (such as, in project 4).

For example, write your code to use a function get(g, i, j) any time you need to access element [i][j], which you could define as:

 float get(Grid* g, int i, int j) {

get_rowmajor(g, i, j);

}

In other words, your code should not assume a particular layout, but instead should use a getter to get the element at [i][j]. Later when we want to use a different layout, we'll simply swap another getter:
 float get(Grid* g, int i, int j) {

//get_rowmajor(g, i, j);
get_blocked(g, i, j);

}

• Split the viewshed function into (at least) two functions: one that computes whether point (k,l) is visible from a point (i,j); and one that calls this function for every point in the grid to determine if it is visible from the viewpoint.

/*
return NODATA if g[i][j] or g[k][l] is NODATA;
return 0 if (k,l) is not visible from (i,j)
return 1 if (k,l) otherwie (is visible from (i,j))
*/
float is_visible(Grid *g, int i, int j, int k, int l);


void compute_viewshed (Grid* eg, Grid * vg, int vprow, int vpcol) {
...
for (i=0; i< g->nrows; i++)  {
for (j=0; j< g-> ncols; j++) {

set (vg, i, j) = is_visible(eg, vprow, vpcol, i, j);

}//for j
}//for i
...
}

• The algorithm is pretty straightfirward at a high level, but the details can get messy and it's hard to debug. I suggest the following approach.

1. start by considering only the first quadrant wrt vp (ie the points that are to the right and above vp); and, consider only the inersections of the LOS with the vertical grid lines. Get this case right first.

3. The viewshed will look very close to the final one. Now you can add the final level of detail, the horizontal grid lines: For every point p that's currently set as visible from v, compute the intersections of the LOS vp with the horizontal lines and check if any of these make p invisible.

• Finally, a warning that this project is significantly harder than the previous project, so plan accordingly.

## Testing

I am including the output for set1.asc from vp=(100,100) here and from vp=(250,250) here. Here is what they look like:

I rendered the viewshed ascii files using some old render code, which you can find here. Run as:

cd render
make
./render2d set1.asc
(press q to quit)

./render2d set1vis.100.100.asc
(pree q to quit)

If you need more sample viewsheds for any of the test grids, I can generate them, just ask.

## What to turn in:

In additon to pushing the code to your GitHub repo, please bring to class and hand in:

• a sheet of paper with the http of your repository, and whether this is an individual project, or a pair-programming project (and the names)

• screenshots of the output of your code on some test files: set1.asc with vp=(100,100) and vp=(250, 250). [WE MAY ADD MORE TESTS FILES, FOLLOW PIAZZA ]

So for example, if I were to turn in my helloworld project I would hand in one sheet with:

Laura Toma

Worked alone

To clone: https://github.com/lauratoma/helloworld.git