0

I need to draw a solid polygon in memory (into a 2D array) and 'fill' the polygon with numeric values (say '3').

I wish to do this in C#.

I'm getting the solid polygons from Shapefiles using Catfood's Shapefile reader (very good).

Any ideas?


I'm attaching a small portion of this 2D array after I've already 'mapped' 16,000 polylines that represent that road network around San Diego (they appear as the number '9'). I wish to do the same thing by uploading a shapefile of solid polygons and 'drawing' with the number '3'. Small section of the 'Terrain Map' in memory

zetar
  • 1,225
  • 2
  • 20
  • 45
  • 8
    What is a polygon that is not rendered? If it is not on screen how do you draw it? It doesn't make sense. – Oded Feb 27 '13 at 20:59
  • 1
    how is your polygon represented in the first place? – Sam I am says Reinstate Monica Feb 27 '13 at 21:02
  • @Oded It seems pretty clear that zetar is asking how to render to an image (and maybe save it to a file, for example) instead of rendering it directly to the screen. – Timothy Shields Feb 27 '13 at 21:05
  • @TimothyShields Yes, it's almost obvious, also I suppose that he wants to draw maps for GIS but he didn't state his problem well since we can't guess where he stores data and numbers, or how big images should be? What are the Geometries he uses etc. – Nikola Davidovic Feb 27 '13 at 21:09
  • Apparently I was too vague. I'm building, in memory, a map of the topography that is on the screen. I'm loading a number of shapefiles. One of these shapefiles, for example, contains 16,000 roads. This I 'drew' into memory (using the Bresenham algorithm) writing a value that represents roads. Next, I need to load a shapefile that contains solid polygons. I will extrapolate, like I did for the road polylines, into the 2D array and write a value where ever it appears in the 2D array. – zetar Feb 27 '13 at 21:15
  • @TimothyShields - Drawing or rendering implies a surface to draw on or render. If the OP wishes to _represent_ a solid polygon in memory, that's a different issue, though the question still doesn't contains near enough information to assist with that. – Oded Feb 27 '13 at 21:16
  • @zetar - Please take that comment and _edit_ it into the question. Comments here can be deleted and important information in comments should be put in the question. – Oded Feb 27 '13 at 21:16
  • @zetar You could check this post http://stackoverflow.com/questions/356968/good-algorithm-for-drawing-solid-2-dimensional-polygons it seems that you can easily implement that polygon fill algorithm. – Nikola Davidovic Feb 27 '13 at 21:31
  • @NikolaDavidovic: thanks for the link the good ol' poly fill algorithm. Couldn't find it anywhere. – zetar Feb 27 '13 at 21:44
  • @zetar Check the answer, I presented you some workaround from the top of my head, if you want to do this only once to create some data for further use, I think you won't need to implement your own polygon fill. Only in the case if your polygons are bigger than the Bitmap size limit. Cheers – Nikola Davidovic Feb 27 '13 at 21:48

4 Answers4

1

in C# you can use the Bitmap class to do offscreen drawing of whatever you wish.

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
  • Using a Bitmap is an interesting idea... that just might work. – zetar Feb 27 '13 at 21:12
  • Yeah, but when I blit the bitmap to memory won't it wipe out anything else that was there? I can't remember if there's support for a transparent bitmap or did I have to write my own years ago. – zetar Feb 27 '13 at 21:31
1

Create a Bitmap, get a Graphics from it, call FillPolygon on the Graphics.

Timothy Shields
  • 75,459
  • 18
  • 120
  • 173
  • The polygons are coming in via a shapefile. It would have to be a transparent blit from the bitmap... I don't want to overwrite other data that isn't inside the solid poly. – zetar Feb 27 '13 at 21:27
  • It wouldn't overwrite other data that isn't inside the polygon. It would overwrite the data that is inside the polygon. – Timothy Shields Feb 27 '13 at 21:42
1

Go grab the WriteableBitmapEx Extension. That will allow you to draw just about anything you want into the image memory.

Alternatively, you can make a DrawingVisual, draw whatever you want with it, then render to an image target; See: This example

if you want to go via the System.Drawing route;

using System.Drawing;

Bitmap bmp = new Bitmap(200, 100);
Graphics g = Graphics.FromImage(bmp);
g.DrawLine(Pens.Black, 10, 10, 180, 80);

REF:(Henk Holterman) Drawing C# graphics without using Windows Forms

But I suspect (based on the wording) this is homework, and you've been told to do it manually;

So; for lines you want Bresenham's Line Algorithm, and then fill them with a fill Algorithm; See This

Community
  • 1
  • 1
Meirion Hughes
  • 24,994
  • 12
  • 71
  • 122
  • 1
    Yeah, I used Bresenham for the polylines (see above). No, this is not homework. It would have made a good assignment years ago. I can't, for the life of me, find an algorithm for drawing a solid poly. It's been 20+ years since I wrote a seed fill (would rather not do that again, either). – zetar Feb 27 '13 at 21:24
  • Check out this repository: You want the function: FillPolygon in trunk/Source/WritableBitmapEx/WriteableBitmapFillExtensions.cs at http://writeablebitmapex.codeplex.com/SourceControl/changeset/view/98508#1157213 – Meirion Hughes Feb 28 '13 at 08:30
0

Since you are drawing in the 2D array of ints (as far as I can see after you have edited your question) it seems like you should implement your own polygon fill that is storing the numbers in the 2D array. For this purpose you could use this post Good algorithm for drawing solid 2-dimensional polygons?

The other solution is a little workaround. You could use the already implemented PolygonFill that fills polygons in the Bitmap. Check this out. I must warn you that getting bitmap pixel is very slow and for that purposes you can use some FastBitmap implementation. Here I will use regular Bitmap.

Bitmap bmp = new Bitmap(0,0,mostRightPoint.X - mostLeftPoint.X, mostUpperPoint.Y - mostLowerPoint.Y);
//this implies that you are on the northern hemisphere
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.White); //clear the whole bitmap into white color
int [] points = new points[nmbOfPoints];

for(int i = 0;i<nmbOfPoints;i++)
{
      //put the points in the points array
}
g.FillPolygon(Brushes.Black, points);
g.Dispose();

Now you should iterate through the Bitmap, on those places where the pixel is black, put the number 3 in your 2D array, somethink like this.

for(int i = 0;i<bmp.Width;i++)
for(int j = 0;j<bmp.Height;j++)
if(Bitmap.GetPixel(i,j) == Color.Black)
{
     2DArray[mostLeftPoint.X + i, mostLowerPoint.Y + j] = 3;
}

I think you got the sense of the problem and a possible solution.

Community
  • 1
  • 1
Nikola Davidovic
  • 8,556
  • 1
  • 27
  • 33