private void DrawPolygon(IGraphics g, Center c, PortableColor color) { //only used if Center c is on the edge of the graph. allows for completely filling in the outer polygons Corner edgeCorner1 = null; Corner edgeCorner2 = null; c.area = 0; foreach (Center n in c.neighbors) { Edge e = EdgeWithCenters(c, n); if (e.v0 == null) { //outermost voronoi edges aren't stored in the graph continue; } //find a corner on the exterior of the graph //if this Edge e has one, then it must have two, //finding these two corners will give us the missing //triangle to render. this special triangle is handled //outside this for loop Corner cornerWithOneAdjacent = e.v0.border ? e.v0 : e.v1; if (cornerWithOneAdjacent.border) { if (edgeCorner1 == null) { edgeCorner1 = cornerWithOneAdjacent; } else { edgeCorner2 = cornerWithOneAdjacent; } } DrawTriangle(g, color, e.v0, e.v1, c); c.area += Math.Abs(c.loc.X * (e.v0.loc.Y - e.v1.loc.Y) + e.v0.loc.X * (e.v1.loc.Y - c.loc.Y) + e.v1.loc.X * (c.loc.Y - e.v0.loc.Y)) / 2; } //handle the missing triangle if (edgeCorner2 != null) { //if these two outer corners are NOT on the same exterior edge of the graph, //then we actually must render a polygon (w/ 4 points) and take into consideration //one of the four corners (either 0,0 or 0,height or width,0 or width,height) //note: the 'missing polygon' may have more than just 4 points. this //is common when the number of sites are quite low (less than 5), but not a problem //with a more useful number of sites. //TODO: find a way to fix this if (CloseEnough(edgeCorner1.loc.X, edgeCorner2.loc.X, 1)) { DrawTriangle(g, color, edgeCorner1, edgeCorner2, c); } else { var points = new PointInt32[] { new PointInt32((int)c.loc.X, (int)c.loc.Y), new PointInt32((int)edgeCorner1.loc.X, (int)edgeCorner1.loc.Y), new PointInt32((int)((CloseEnough(edgeCorner1.loc.X, bounds.x, 1) || CloseEnough(edgeCorner2.loc.X, bounds.x, .5)) ? bounds.x : bounds.right), (int)((CloseEnough(edgeCorner1.loc.Y, bounds.y, 1) || CloseEnough(edgeCorner2.loc.Y, bounds.y, .5)) ? bounds.y : bounds.bottom)), new PointInt32((int)edgeCorner2.loc.X, (int)edgeCorner2.loc.Y), }; g.FillPolygon(color, points); c.area += 0; //TODO: area of polygon given vertices } } }
private void DrawPolygon3D <T>(Center c, PortableColor color, IVertexFactory <T> factory, List <T> vertexBuffer) { //only used if Center c is on the edge of the graph. allows for completely filling in the outer polygons Corner edgeCorner1 = null; Corner edgeCorner2 = null; foreach (Center n in c.neighbors) { var e = EdgeWithCenters(c, n); if (e.v0 == null) { //outermost voronoi edges aren't stored in the graph continue; } //find a corner on the exterior of the graph //if this Edge e has one, then it must have two, //finding these two corners will give us the missing //triangle to render. this special triangle is handled //outside this for loop var cornerWithOneAdjacent = e.v0.border ? e.v0 : e.v1; if (cornerWithOneAdjacent.border) { if (edgeCorner1 == null) { edgeCorner1 = cornerWithOneAdjacent; } else { edgeCorner2 = cornerWithOneAdjacent; } } var p = Transform((float)c.loc.X, (float)c.loc.Y, (float)c.elevation); var q = Transform((float)e.v0.loc.X, (float)e.v0.loc.Y, (float)e.v0.elevation); var r = Transform((float)e.v1.loc.X, (float)e.v1.loc.Y, (float)e.v1.elevation); AddTriangle(p, r, q, color, factory, vertexBuffer); } //handle the missing triangle if (edgeCorner2 != null) { //if these two outer corners are NOT on the same exterior edge of the graph, //then we actually must render a polygon (w/ 4 points) and take into consideration //one of the four corners (either 0,0 or 0,height or width,0 or width,height) //note: the 'missing polygon' may have more than just 4 points. this //is common when the number of sites are quite low (less than 5), but not a problem //with a more useful number of sites. //TODO: find a way to fix this if (CloseEnough(edgeCorner1.loc.X, edgeCorner2.loc.X, 1)) { var p = Transform((float)c.loc.X, (float)c.loc.Y, (float)c.elevation); var q = Transform((float)edgeCorner1.loc.X, (float)edgeCorner1.loc.Y, (float)edgeCorner1.elevation); var r = Transform((float)edgeCorner2.loc.X, (float)edgeCorner2.loc.Y, (float)edgeCorner2.elevation); AddTriangle(p, r, q, color, factory, vertexBuffer); } else { /* * var points = new PointInt32[] { * new PointInt32((int)c.loc.X, (int)c.loc.Y), * new PointInt32((int)edgeCorner1.loc.X, (int)edgeCorner1.loc.Y), * new PointInt32((int)((CloseEnough(edgeCorner1.loc.X, bounds.x, 1) || CloseEnough(edgeCorner2.loc.X, bounds.x, .5)) ? bounds.x : bounds.right), (int)((CloseEnough(edgeCorner1.loc.Y, bounds.y, 1) || CloseEnough(edgeCorner2.loc.Y, bounds.y, .5)) ? bounds.y : bounds.bottom)), * new PointInt32((int)edgeCorner2.loc.X, (int)edgeCorner2.loc.Y), * }; * * g.FillPolygon(color, points); * c.area += 0; //TODO: area of polygon given vertices*/ } } }