예제 #1
0
        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
                }
            }
        }
예제 #2
0
        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*/
                }
            }
        }