public void FillPolygon(PortableColor color, PointInt32[] points) { var clone = new Point[points.Length]; for (var i = 0; i < points.Length; i++) { clone[i] = new Point(points[i].X, points[i].Y); } _graphics.FillPolygon(new SolidBrush(color.ToColor()), clone); }
private void DrawTriangle(IGraphics g, PortableColor c, Corner c1, Corner c2, Center center) { var points = new PointInt32[] { new PointInt32((int)center.loc.X, (int)center.loc.Y), new PointInt32((int)c1.loc.X, (int)c1.loc.Y), new PointInt32((int)c2.loc.X, (int)c2.loc.Y), }; g.DrawPolygon(c, points); }
//also records the area of each voronoi cell public void Paint(IGraphics g, bool drawBiomes, bool drawRivers, bool drawSites, bool drawCorners, bool drawDelaunay) { int numSites = centers.Count; PortableColor[] defaultColors = null; if (!drawBiomes) { defaultColors = new PortableColor[numSites]; for (int i = 0; i < defaultColors.Length; i++) { defaultColors[i] = new PortableColor(255, (byte)r.Next(255), (byte)r.Next(255), (byte)r.Next(255)); } } using (var pixelCenterGraphics = pixelCenterMap.GetGraphics()) { //draw via triangles foreach (Center c in centers) { DrawPolygon(g, c, drawBiomes ? GetColor(c.biome) : defaultColors[c.index]); DrawPolygon(pixelCenterGraphics, c, PortableColor.FromUInt32((uint)c.index)); } } foreach (var e in edges) { if (drawDelaunay) { g.DrawLine(PortableColor.Yellow, (int)e.d0.loc.X, (int)e.d0.loc.Y, (int)e.d1.loc.X, (int)e.d1.loc.Y); } if (drawRivers && e.river > 0) { g.DrawLine(River, (int)e.v0.loc.X, (int)e.v0.loc.Y, (int)e.v1.loc.X, (int)e.v1.loc.Y); } } if (drawSites) { centers.ForEach((s) => { g.FillEllipse(PortableColor.Black, (int)(s.loc.X - 2), (int)(s.loc.Y - 2), 4, 4); }); } if (drawCorners) { corners.ForEach((c) => { g.FillEllipse(PortableColor.White, (int)(c.loc.X - 2), (int)(c.loc.Y - 2), 4, 4); }); } g.DrawRectangle(PortableColor.White, (int)bounds.x, (int)bounds.y, (int)bounds.width, (int)bounds.height); }
private void AddTriangle <T>(Vector3D a, Vector3D b, Vector3D c, PortableColor color, IVertexFactory <T> factory, List <T> vertexBuffer) { var normal = GetNormal(a, b, c); if (normal.Y >= 0) { var xchg = b; b = c; c = xchg; normal = GetNormal(a, b, c); } vertexBuffer.Add(factory.CreateVertex(a, normal, color)); vertexBuffer.Add(factory.CreateVertex(b, normal, color)); vertexBuffer.Add(factory.CreateVertex(c, normal, color)); }
public VertexPositionColor CreateVertex(Vector3D position, Vector3D normal, PortableColor color) { return(new VertexPositionColor(new Vector3(position.X, position.Y, position.Z), new Color(color.R, color.G, color.B))); }
public static Color ToColor(this PortableColor color) { return(Color.FromArgb(color.A, color.R, color.G, color.B)); }
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*/ } } }
public void FillEllipse(PortableColor color, int x, int y, int width, int height) { _graphics.FillEllipse(new SolidBrush(color.ToColor()), x, y, width, height); }
public void DrawRectangle(PortableColor color, int x, int y, int width, int height) { _graphics.DrawRectangle(new Pen(color.ToColor()), x, y, width, height); }
public void DrawLine(PortableColor color, int x1, int y1, int x2, int y2) { _graphics.DrawLine(new Pen(color.ToColor()), x1, y1, x2, y2); }