示例#1
0
 //Added by Dozed
 internal VEdge(VPoint start, VPoint end, FortuneSite left, FortuneSite right)
 {
     Start = start;
     End   = end;
     Left  = left;
     Right = right;
 }
示例#2
0
        internal VEdge(VPoint start, FortuneSite left, FortuneSite right)
        {
            Start = start;
            Left  = left;
            Right = right;

            //for bounding box edges
            if (left == null || right == null)
            {
                return;
            }

            //from negative reciprocal of slope of line from left to right
            //ala m = (left.y -right.y / left.x - right.x)
            SlopeRise = left.X - right.X;
            SlopeRun  = -(left.Y - right.Y);
            Intercept = null;

            if (SlopeRise.ApproxEqual(0) || SlopeRun.ApproxEqual(0))
            {
                return;
            }
            Slope     = SlopeRise / SlopeRun;
            Intercept = start.Y - Slope * start.X;
        }
示例#3
0
        public void Initialize(VPoint start, FortuneSite left, FortuneSite right)
        {
            Start     = start;
            End       = VPoint.Default;
            Left      = left;
            Right     = right;
            IsClipped = false;
            Neighbor  = null;

            //for bounding box edges
            if (left == null || right == null)
            {
                return;
            }

            //from negative reciprocal of slope of line from left to right
            //ala m = (left.y -right.y / left.x - right.x)
            SlopeRise = left.X - right.X;
            SlopeRun  = -(left.Y - right.Y);
            Intercept = null;

            if (SlopeRise.ApproxEqual(0) || SlopeRun.ApproxEqual(0))
            {
                return;
            }
            Slope     = SlopeRise / SlopeRun;
            Intercept = start.Y - Slope * start.X;
        }
示例#4
0
        private static VPoint FindCentroid(IReadOnlyList <VPoint> vertices)
        {
            var point = new VPoint(0d, 0d);
            var area  = 0d;

            for (var i = 0; i < vertices.Count; i++)
            {
                var nextI = (i + 1) % vertices.Count;
                var x0    = vertices[i].X;
                var y0    = vertices[i].Y;
                var x1    = vertices[nextI].X;
                var y1    = vertices[nextI].Y;

                var a = (x0 * y1) - (x1 * y0);
                area    += a;
                point.X += (x0 + x1) * a;
                point.Y += (y0 + y1) * a;
            }

            if (!area.ApproxEqual(0d))
            {
                area    *= 3d;
                point.X /= area;
                point.Y /= area;
            }

            return(point);
        }
示例#5
0
文件: Program.cs 项目: rimever/CodeIQ
        /// <summary>
        ///
        /// </summary>
        /// <param name="times"></param>
        /// <param name="log">開始時はnullを指定してください。</param>
        /// <returns></returns>
        private static IEnumerable <List <VPoint> > Answers(int times, List <VPoint> log = null)
        {
            if (log == null)
            {
                log = new List <VPoint>()
                {
                    new VPoint(0, 0)
                };
            }
            var now = log.Last();

            foreach (var move in moves)
            {
                var next = new VPoint(now.X + move.X, now.Y + move.Y);
                if (!log.Contains(next))
                {
                    var nextLog = new List <VPoint>(log);
                    nextLog.Add(next);
                    if (nextLog.Count == times + 1)
                    {
                        yield return(nextLog);
                    }
                    else
                    {
                        foreach (var item in Answers(times, nextLog))
                        {
                            yield return(item);
                        }
                    }
                }
            }
        }
示例#6
0
        protected override void DrawLine(VPoint a, VPoint b)
        {
            var triangle = new Triangle(a, b, b);

            //Console.WriteLine($"DrawLine({a}, {b})");
            TriangleRasterizer.RasterizeLine(a.P, b.P, triangle);
        }
示例#7
0
        private static VEdge AddEdgeForBoundingBox(VPoint startPoint, VPoint otherPoint, FortuneSite site, bool left)
        {
            var newEdge = new VEdge(startPoint, left ? site : null, left ? null : site)
            {
                End = otherPoint
            };

            site.Cell.Add(newEdge);
            return(newEdge);
        }
示例#8
0
 public Line(VPoint p0, VPoint p1)
 {
     // Sort the points so that y0 <= y1 <= y2
     if (p1.P.Y < p0.P.Y)
     {
         Swap(ref p1, ref p0);
     }
     P0 = p0;
     P1 = p1;
 }
示例#9
0
        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            {
                Exit();
            }
            var newKeys  = Keyboard.GetState();
            var newMouse = Mouse.GetState();

            if (keyboard.IsKeyDown(Keys.H) && newKeys.IsKeyUp(Keys.H))
            {
                showHelp = !showHelp;
            }
            if (keyboard.IsKeyDown(Keys.G) && newKeys.IsKeyUp(Keys.G))
            {
                GeneratePoints();
            }
            if (keyboard.IsKeyDown(Keys.C) && newKeys.IsKeyUp(Keys.C))
            {
                ClearPoints();
            }
            if (keyboard.IsKeyDown(Keys.W) && newKeys.IsKeyUp(Keys.W))
            {
                wiggle = !wiggle;
            }
            if (keyboard.IsKeyDown(Keys.V) && newKeys.IsKeyUp(Keys.V))
            {
                showVoronoi = !showVoronoi;
            }
            if (keyboard.IsKeyDown(Keys.B) && newKeys.IsKeyUp(Keys.B))
            {
                showCells = !showCells;
            }
            if (keyboard.IsKeyDown(Keys.D) && newKeys.IsKeyUp(Keys.D))
            {
                showDelaunay = !showDelaunay;
            }
            if (mouse.LeftButton == ButtonState.Pressed && newMouse.LeftButton == ButtonState.Released)
            {
                AddPoint(mouse.X, mouse.Y);
            }
            if (mouse.RightButton == ButtonState.Pressed && newMouse.RightButton == ButtonState.Released)
            {
                testPoint = new VPoint(mouse.X, mouse.Y);
            }
            if (wiggle && points.Count > 0)
            {
                WigglePoints();
            }
            keyboard = newKeys;
            mouse    = newMouse;
            ////mouse = newMouse;
            base.Update(gameTime);
        }
示例#10
0
    private VPoint PQ_min()
    {
        VPoint answer = new VPoint();

        while (PQhash[PQmin].PQnext == null)
        {
            PQmin++;
        }

        answer.x = PQhash[PQmin].PQnext.vertex.coord.x;
        answer.y = PQhash[PQmin].PQnext.ystar;
        return(answer);
    }
示例#11
0
        public static void Demo()
        {
            VPoint vp = new VPoint {
                X = 10, Y = -10
            };
            RPoint rp = new RPoint {
                X = 10, Y = -10
            };

            ClearPoints(vp, rp);
            Console.WriteLine($"VPoint: X={vp.X}, Y={vp.Y}");             // VPoint: X=10, Y=-10
            Console.WriteLine($"RPoint: X={rp.X}, Y={rp.Y}");             // RPoint: X=0, Y=0
        }
示例#12
0
            public Triangle(VPoint p0, VPoint p1, VPoint p2)
            {
                // Sort the points so that y0 <= y1 <= y2
                if (p1.P.Y < p0.P.Y)
                {
                    Swap(ref p1, ref p0);
                }
                if (p2.P.Y < p0.P.Y)
                {
                    Swap(ref p2, ref p0);
                }
                if (p2.P.Y < p1.P.Y)
                {
                    Swap(ref p2, ref p1);
                }


                P0 = p0;
                P1 = p1;
                P2 = p2;
            }
示例#13
0
        /// <summary>
        /// Returns the best path between the given start point (sole element of currentPath) and the endpoint within the voronoiGraph
        /// </summary>
        private static List <VPoint> GetShortestPath(List <VPoint> currentPath, VPoint endPoint, Dictionary <VPoint, List <VPoint> > voronoiGraph)
        {
            VPoint currentPoint = currentPath.Last();

            if (voronoiGraph[currentPoint].Contains(endPoint))
            {
                List <VPoint> nextPath = new List <VPoint>();
                nextPath.AddRange(currentPath);
                nextPath.Add(endPoint);
                return(nextPath);
            }

            else if (voronoiGraph[currentPoint].All(x => currentPath.Contains(x)))
            {
                return(null);
            }
            else
            {
                List <VPoint> shortestPath     = null;
                float         shortestDistance = float.MaxValue;

                foreach (VPoint nextPoint in voronoiGraph[currentPoint].Where(x => !currentPath.Contains(x)))
                {
                    List <VPoint> nextPath = new List <VPoint>();
                    nextPath.AddRange(currentPath);
                    nextPath.Add(nextPoint);
                    List <VPoint> nextPointPath = GetShortestPath(nextPath, endPoint, voronoiGraph);
                    if (nextPointPath != null)
                    {
                        float nextPointPathDistance = GetPathDistance(nextPointPath, 0f);
                        if (nextPointPathDistance < shortestDistance)
                        {
                            shortestDistance = nextPointPathDistance;
                            shortestPath     = nextPointPath;
                        }
                    }
                }
                return(shortestPath);
            }
        }
 private void treeView_points_AfterSelect(object sender, TreeViewEventArgs e)
 {
     try
     {
         if (e.Node.Text.StartsWith(TB.L.Phrase["Form_Dialog_Edit.StartOfCont"]))
         {
             var a = new GraphicsPath(FillMode.Winding);
             a.AddPolygon(Vector.PointexToPoint(dat.BaseData.RawData[e.Node.Index]));
             SelectedContour = e.Node.Index;
             parent.RenderEX(Color.Violet, a);
         }
         else
         {
             SelectedContour = -1;
             var    a   = new GraphicsPath(FillMode.Winding);
             VPoint pnt = dat.BaseData.RawData[e.Node.Parent.Index][e.Node.Index].BasePoint;
             a.AddEllipse((float)pnt.Y, (float)pnt.X, 5, 5);
             parent.RenderEX(Color.Blue, a);
         }
     }
     catch { }
 }
示例#15
0
    public int Compare(Site p1, Site p2)
    {
        VPoint s1 = p1.coord;
        VPoint s2 = p2.coord;

        if (s1.y < s2.y)
        {
            return(-1);
        }
        if (s1.y > s2.y)
        {
            return(1);
        }
        if (s1.x < s2.x)
        {
            return(-1);
        }
        if (s1.x > s2.x)
        {
            return(1);
        }
        return(0);
    }
示例#16
0
        private static List <VPoint> SmoothLine(List <VPoint> line)
        {
            List <VPoint> smoothLine = new List <VPoint>();

            smoothLine.Add(line[0]);
            for (int i = 1; i < line.Count - 1; i++)
            {
                List <VPoint> avgPoints = new List <VPoint>();
                if (i > 0)
                {
                    avgPoints.Add(line[i - 1]);
                }
                avgPoints.Add(line[i]);
                if (i < line.Count - 1)
                {
                    avgPoints.Add(line[i + 1]);
                }

                VPoint smoothenedPoint = new VPoint(avgPoints.Average(x => x.X), avgPoints.Average(x => x.Y));
                smoothLine.Add(smoothenedPoint);
            }
            smoothLine.Add(line.Last());
            return(smoothLine);
        }
示例#17
0
        private static bool ClipRay(VEdge edge, double minX, double minY, double maxX, double maxY)
        {
            var start = edge.Start;

            //horizontal ray
            if (edge.SlopeRise.ApproxEqual(0))
            {
                if (!Within(start.Y, minY, maxY))
                {
                    return(false);
                }
                if (edge.SlopeRun > 0 && start.X > maxX)
                {
                    return(false);
                }
                if (edge.SlopeRun < 0 && start.X < minX)
                {
                    return(false);
                }
                if (Within(start.X, minX, maxX))
                {
                    if (edge.SlopeRun > 0)
                    {
                        edge.End = new VPoint(maxX, start.Y);
                    }
                    else
                    {
                        edge.End = new VPoint(minX, start.Y);
                    }
                }
                else
                {
                    if (edge.SlopeRun > 0)
                    {
                        edge.Start = new VPoint(minX, start.Y);
                        edge.End   = new VPoint(maxX, start.Y);
                    }
                    else
                    {
                        edge.Start = new VPoint(maxX, start.Y);
                        edge.End   = new VPoint(minX, start.Y);
                    }
                }
                return(true);
            }
            //vertical ray
            if (edge.SlopeRun.ApproxEqual(0))
            {
                if (start.X < minX || start.X > maxX)
                {
                    return(false);
                }
                if (edge.SlopeRise > 0 && start.Y > maxY)
                {
                    return(false);
                }
                if (edge.SlopeRise < 0 && start.Y < minY)
                {
                    return(false);
                }
                if (Within(start.Y, minY, maxY))
                {
                    if (edge.SlopeRise > 0)
                    {
                        edge.End = new VPoint(start.X, maxY);
                    }
                    else
                    {
                        edge.End = new VPoint(start.X, minY);
                    }
                }
                else
                {
                    if (edge.SlopeRise > 0)
                    {
                        edge.Start = new VPoint(start.X, minY);
                        edge.End   = new VPoint(start.X, maxY);
                    }
                    else
                    {
                        edge.Start = new VPoint(start.X, maxY);
                        edge.End   = new VPoint(start.X, minY);
                    }
                }
                return(true);
            }

            //works for outside
            Debug.Assert(edge.Slope != null, "edge.Slope != null");
            Debug.Assert(edge.Intercept != null, "edge.Intercept != null");
            var topX    = new VPoint(CalcX(edge.Slope.Value, maxY, edge.Intercept.Value), maxY);
            var bottomX = new VPoint(CalcX(edge.Slope.Value, minY, edge.Intercept.Value), minY);
            var leftY   = new VPoint(minX, CalcY(edge.Slope.Value, minX, edge.Intercept.Value));
            var rightY  = new VPoint(maxX, CalcY(edge.Slope.Value, maxX, edge.Intercept.Value));

            //reject intersections not within bounds
            var candidates = new List <VPoint>();

            if (Within(topX.X, minX, maxX))
            {
                candidates.Add(topX);
            }
            if (Within(bottomX.X, minX, maxX))
            {
                candidates.Add(bottomX);
            }
            if (Within(leftY.Y, minY, maxY))
            {
                candidates.Add(leftY);
            }
            if (Within(rightY.Y, minY, maxY))
            {
                candidates.Add(rightY);
            }

            //reject candidates which don't align with the slope
            for (var i = candidates.Count - 1; i > -1; i--)
            {
                var candidate = candidates[i];
                //grab vector representing the edge
                var ax = candidate.X - start.X;
                var ay = candidate.Y - start.Y;
                if (edge.SlopeRun * ax + edge.SlopeRise * ay < 0)
                {
                    candidates.RemoveAt(i);
                }
            }

            //if there are two candidates we are outside the closer one is start
            //the further one is the end
            if (candidates.Count == 2)
            {
                var ax = candidates[0].X - start.X;
                var ay = candidates[0].Y - start.Y;
                var bx = candidates[1].X - start.X;
                var by = candidates[1].Y - start.Y;
                if (ax * ax + ay * ay > bx * bx + by * by)
                {
                    edge.Start = candidates[1];
                    edge.End   = candidates[0];
                }
                else
                {
                    edge.Start = candidates[0];
                    edge.End   = candidates[1];
                }
            }

            //if there is one candidate we are inside
            if (candidates.Count == 1)
            {
                edge.End = candidates[0];
            }

            //there were no candidates
            return(edge.End != null);
        }
示例#18
0
 public static Vector2 ToVector2(this VPoint site)
 {
     return(new Vector2((float)site.X, (float)site.Y));
 }
示例#19
0
        protected override void DrawTriangle(VPoint a, VPoint b, VPoint c)
        {
            var triangle = new Triangle(a, b, c);

            TriangleRasterizer.RasterizeTriangle(triangle.P0.P, triangle.P1.P, triangle.P2.P, triangle);
        }
示例#20
0
 public void Initialize(VPoint lowest, double yCenter, RBTreeNode <BeachSection> toDelete)
 {
     Lowest   = lowest;
     YCenter  = yCenter;
     ToDelete = toDelete;
 }
示例#21
0
 public Tile(VPoint point, Texture2D texture, Rectangle source, bool isPassable = true) : this(point.X, point.Y, point.Type, texture, source, isPassable)
 {
 }
示例#22
0
        public ImageSource GetKingdomMap(string kingdomName)
        {
            if (mapPerlin == null)
            {
                GenPerlinMap();
            }
            Bitmap bmp = new Bitmap(mapPerlin);

            Kingdom currentK = this.kingdoms.Where(e => e.Name == kingdomName).First();

            using (Graphics g = Graphics.FromImage(bmp))
            {
                List <Point> frontier = new List <Point>();

                foreach (Region site in currentK.regions)
                {
                    List <VEdge> tmp = new List <VEdge>();
                    int          i   = 0;
                    tmp.Add(site.Cell.First());
                    site.Cell.Remove(site.Cell.First());
                    while (!site.Cell.IsEmpty() && i < site.Cell.Count)
                    {
                        VEdge ve = site.Cell.ElementAt(i);
                        VEdge t  = tmp.Last();
                        if (t.End == ve.Start)
                        {
                            tmp.Add(ve);
                            site.Cell.Remove(ve);
                            i = 0;
                        }
                        else if (t.End == ve.End)
                        {
                            VPoint vp = ve.End;
                            ve.End   = ve.Start;
                            ve.Start = vp;

                            tmp.Add(ve);
                            site.Cell.Remove(ve);
                            i = 0;
                        }
                        else
                        {
                            i++;
                        }
                    }
                    site.Cell = tmp;

                    List <Point> points = new List <Point>();
                    foreach (var edge in site.Cell)
                    {
                        points.Add(new Point((int)edge.Start.X, (int)edge.Start.Y));
                        points.Add(new Point((int)edge.End.X, (int)edge.End.Y));
                    }

                    Point[] tab   = points.ToArray();
                    Color   color = Color.FromArgb(150,
                                                   site.Kingdom.Color.R,
                                                   site.Kingdom.Color.G,
                                                   site.Kingdom.Color.B);


                    g.FillPolygon(new SolidBrush(color), tab);

                    if (site.City)
                    {
                        if (!site.Capital)
                        {
                            g.FillEllipse(new SolidBrush(Color.White),
                                          (float)(site.X - 2), (float)(site.Y - 2),
                                          5f, 5f);
                        }
                        else
                        {
                            g.FillEllipse(new SolidBrush(Color.Yellow),
                                          (float)(site.X - 2), (float)(site.Y - 2),
                                          5f, 5f);
                        }
                    }
                }

                g.FillRectangle(new SolidBrush(Color.FromArgb(50, 255, 255, 255)), 0, 0, this.mapWidth, this.mapHeight);
            }

            return(ImageSourceFromBitmap(bmp));
        }
示例#23
0
        public ImageSource GetGodMap(string godString)
        {
            God currentG = this.pantheon.Gods.Where(e => e.ToString() == godString).First();

            if (!currentG.Forgot)
            {
                if (mapPerlin == null)
                {
                    GenPerlinMap();
                }
                Bitmap bmp = new Bitmap(mapPerlin);


                using (Graphics g = Graphics.FromImage(bmp))
                {
                    foreach (Region site in currentG.Followers)
                    {
                        List <VEdge> tmp = new List <VEdge>();
                        int          i   = 0;
                        tmp.Add(site.Cell.First());
                        site.Cell.Remove(site.Cell.First());
                        while (!site.Cell.IsEmpty() && i < site.Cell.Count)
                        {
                            VEdge ve = site.Cell.ElementAt(i);
                            VEdge t  = tmp.Last();
                            if (t.End == ve.Start)
                            {
                                tmp.Add(ve);
                                site.Cell.Remove(ve);
                                i = 0;
                            }
                            else if (t.End == ve.End)
                            {
                                VPoint vp = ve.End;
                                ve.End   = ve.Start;
                                ve.Start = vp;

                                tmp.Add(ve);
                                site.Cell.Remove(ve);
                                i = 0;
                            }
                            else
                            {
                                i++;
                            }
                        }
                        site.Cell = tmp;

                        List <Point> points = new List <Point>();
                        foreach (var edge in site.Cell)
                        {
                            points.Add(new Point((int)edge.Start.X, (int)edge.Start.Y));
                            points.Add(new Point((int)edge.End.X, (int)edge.End.Y));
                        }

                        Point[] tab   = points.ToArray();
                        Color   color = Color.FromArgb(150,
                                                       site.God.Color.R,
                                                       site.God.Color.G,
                                                       site.God.Color.B);


                        g.FillPolygon(new SolidBrush(color), tab);

                        if (site.City)
                        {
                            if (site == site.God.Capitale)
                            {
                                g.FillEllipse(new SolidBrush(Color.White),
                                              (float)(site.X - 2), (float)(site.Y - 2),
                                              5f, 5f);
                            }
                            else
                            {
                                g.FillEllipse(new SolidBrush(Color.Yellow),
                                              (float)(site.X - 2), (float)(site.Y - 2),
                                              5f, 5f);
                            }
                        }
                    }

                    g.FillRectangle(new SolidBrush(Color.FromArgb(50, 255, 255, 255)), 0, 0, this.mapWidth, this.mapHeight);
                }

                return(ImageSourceFromBitmap(bmp));
            }
            else
            {
                return(this.ImageSourceFromBitmap((Bitmap)Bitmap.FromFile("Assets/Background/BackgroundTemple.jpg")));
            }
        }
示例#24
0
        public ImageSource GetVoronoiGraph(bool delaunay = false)
        {
            if (mapPerlin == null)
            {
                GenPerlinMap();
            }
            Bitmap bmp = new Bitmap(mapPerlin);


            using (Graphics g = Graphics.FromImage(bmp))
            {
                int seed = -1;

                foreach (Region site in sites)
                {
                    seed++;

                    if (site.Kingdom != null && affSite)
                    {
                        List <VEdge> tmp = new List <VEdge>();
                        int          i   = 0;
                        tmp.Add(site.Cell.First());
                        site.Cell.Remove(site.Cell.First());
                        while (!site.Cell.IsEmpty() && i < site.Cell.Count)
                        {
                            VEdge ve = site.Cell.ElementAt(i);
                            VEdge t  = tmp.Last();
                            if (t.End == ve.Start)
                            {
                                tmp.Add(ve);
                                site.Cell.Remove(ve);
                                i = 0;
                            }
                            else if (t.End == ve.End)
                            {
                                VPoint vp = ve.End;
                                ve.End   = ve.Start;
                                ve.Start = vp;

                                tmp.Add(ve);
                                site.Cell.Remove(ve);
                                i = 0;
                            }
                            else
                            {
                                i++;
                            }
                        }
                        site.Cell = tmp;

                        List <Point> points = new List <Point>();
                        foreach (var edge in site.Cell)
                        {
                            points.Add(new Point((int)edge.Start.X, (int)edge.Start.Y));
                            points.Add(new Point((int)edge.End.X, (int)edge.End.Y));
                        }

                        Point[] tab   = points.ToArray();
                        Random  rand  = new Random(seed);
                        Color   color = Color.FromArgb(90,
                                                       site.Kingdom.Color.R,
                                                       site.Kingdom.Color.G,
                                                       site.Kingdom.Color.B);


                        g.FillPolygon(new SolidBrush(color), tab);
                    }

                    if (site.God != null && this.croyance)
                    {
                        List <VEdge> tmp = new List <VEdge>();
                        int          i   = 0;
                        tmp.Add(site.Cell.First());
                        site.Cell.Remove(site.Cell.First());
                        while (!site.Cell.IsEmpty() && i < site.Cell.Count)
                        {
                            VEdge ve = site.Cell.ElementAt(i);
                            VEdge t  = tmp.Last();
                            if (t.End == ve.Start)
                            {
                                tmp.Add(ve);
                                site.Cell.Remove(ve);
                                i = 0;
                            }
                            else if (t.End == ve.End)
                            {
                                VPoint vp = ve.End;
                                ve.End   = ve.Start;
                                ve.Start = vp;

                                tmp.Add(ve);
                                site.Cell.Remove(ve);
                                i = 0;
                            }
                            else
                            {
                                i++;
                            }
                        }
                        site.Cell = tmp;

                        List <Point> points = new List <Point>();
                        foreach (var edge in site.Cell)
                        {
                            points.Add(new Point((int)edge.Start.X, (int)edge.Start.Y));
                            points.Add(new Point((int)edge.End.X, (int)edge.End.Y));
                        }

                        Point[] tab   = points.ToArray();
                        Random  rand  = new Random(seed);
                        Color   color = Color.FromArgb(90,
                                                       site.God.Color.R,
                                                       site.God.Color.G,
                                                       site.God.Color.B);


                        g.FillPolygon(new SolidBrush(color), tab);
                    }


                    if (site.City)
                    {
                        if (!site.Capital)
                        {
                            g.FillEllipse(new SolidBrush(Color.Crimson),
                                          (float)(site.X - 2), (float)(site.Y - 2),
                                          5f, 5f);
                        }
                        else
                        {
                            g.FillEllipse(new SolidBrush(Color.Yellow),
                                          (float)(site.X - 2), (float)(site.Y - 2),
                                          5f, 5f);
                        }
                    }

                    if (delaunay)
                    {
                        foreach (var neighbor in site.Neighbors)
                        {
                            g.DrawLine(new System.Drawing.Pen(Color.Blue),
                                       (float)site.X,
                                       (float)site.Y,
                                       (float)neighbor.X,
                                       (float)neighbor.Y);
                        }
                    }
                }

                if (voronoi)
                {
                    foreach (VEdge vedge in vedges)
                    {
                        g.DrawLine(new System.Drawing.Pen(System.Drawing.Color.Black),
                                   new System.Drawing.Point((int)vedge.Start.X, (int)vedge.Start.Y),
                                   new System.Drawing.Point((int)vedge.End.X, (int)vedge.End.Y));
                    }
                }
            }

            return(ImageSourceFromBitmap(bmp));
        }
示例#25
0
        public ImageSource GetVoronoiGraph(System.Windows.Point position, bool delaunay = false)
        {
            if (mapPerlin == null)
            {
                GenPerlinMap();
            }
            Bitmap bmp = new Bitmap(mapPerlin);


            using (Graphics g = Graphics.FromImage(bmp))
            {
                int    seed    = -1;
                Region info    = (Region)this.sites.First();
                double distMin = this.mapWidth * 2;

                foreach (Region site in this.sites)
                {
                    seed++;

                    if (site.Kingdom != null && this.affSite)
                    {
                        List <VEdge> tmp = new List <VEdge>();
                        int          i   = 0;
                        tmp.Add(site.Cell.First());
                        site.Cell.Remove(site.Cell.First());
                        while (!site.Cell.IsEmpty() && i < site.Cell.Count)
                        {
                            VEdge ve = site.Cell.ElementAt(i);
                            VEdge t  = tmp.Last();
                            if (t.End == ve.Start)
                            {
                                tmp.Add(ve);
                                site.Cell.Remove(ve);
                                i = 0;
                            }
                            else if (t.End == ve.End)
                            {
                                VPoint vp = ve.End;
                                ve.End   = ve.Start;
                                ve.Start = vp;

                                tmp.Add(ve);
                                site.Cell.Remove(ve);
                                i = 0;
                            }
                            else
                            {
                                i++;
                            }
                        }
                        site.Cell = tmp;

                        List <Point> points = new List <Point>();
                        foreach (var edge in site.Cell)
                        {
                            points.Add(new Point((int)edge.Start.X, (int)edge.Start.Y));
                            points.Add(new Point((int)edge.End.X, (int)edge.End.Y));
                        }

                        Point[] tab   = points.ToArray();
                        Random  rand  = new Random(seed);
                        Color   color = Color.FromArgb(90,
                                                       site.Kingdom.Color.R,
                                                       site.Kingdom.Color.G,
                                                       site.Kingdom.Color.B);


                        g.FillPolygon(new SolidBrush(color), tab);
                    }

                    if (site.God != null && this.croyance)
                    {
                        List <VEdge> tmp = new List <VEdge>();
                        int          i   = 0;
                        tmp.Add(site.Cell.First());
                        site.Cell.Remove(site.Cell.First());
                        while (!site.Cell.IsEmpty() && i < site.Cell.Count)
                        {
                            VEdge ve = site.Cell.ElementAt(i);
                            VEdge t  = tmp.Last();
                            if (t.End == ve.Start)
                            {
                                tmp.Add(ve);
                                site.Cell.Remove(ve);
                                i = 0;
                            }
                            else if (t.End == ve.End)
                            {
                                VPoint vp = ve.End;
                                ve.End   = ve.Start;
                                ve.Start = vp;

                                tmp.Add(ve);
                                site.Cell.Remove(ve);
                                i = 0;
                            }
                            else
                            {
                                i++;
                            }
                        }
                        site.Cell = tmp;

                        List <Point> points = new List <Point>();
                        foreach (var edge in site.Cell)
                        {
                            points.Add(new Point((int)edge.Start.X, (int)edge.Start.Y));
                            points.Add(new Point((int)edge.End.X, (int)edge.End.Y));
                        }

                        Point[] tab   = points.ToArray();
                        Random  rand  = new Random(seed);
                        Color   color = Color.FromArgb(90,
                                                       site.God.Color.R,
                                                       site.God.Color.G,
                                                       site.God.Color.B);


                        g.FillPolygon(new SolidBrush(color), tab);
                    }

                    double dist = Math.Sqrt(Math.Pow(site.X - position.X, 2) + Math.Pow(site.Y - position.Y, 2));
                    if (distMin > dist)
                    {
                        info    = site;
                        distMin = dist;
                    }

                    if (site.City)
                    {
                        if (!site.Capital)
                        {
                            g.FillEllipse(new SolidBrush(Color.Crimson),
                                          (float)(site.X - 2), (float)(site.Y - 2),
                                          5f, 5f);
                        }
                        else
                        {
                            g.FillEllipse(new SolidBrush(Color.Yellow),
                                          (float)(site.X - 2), (float)(site.Y - 2),
                                          5f, 5f);
                        }
                    }

                    if (delaunay)
                    {
                        foreach (var neighbor in site.Neighbors)
                        {
                            g.DrawLine(new System.Drawing.Pen(Color.Blue),
                                       (float)site.X,
                                       (float)site.Y,
                                       (float)neighbor.X,
                                       (float)neighbor.Y);
                        }
                    }
                }

                if (info != null && (this.croyance || this.affSite))
                {
                    string str = "";
                    if (this.affSite)
                    {
                        if (info.Kingdom == null)
                        {
                            str = "Les régions sauvages";
                        }
                        else
                        {
                            str = info.Kingdom.Name;
                        }
                    }
                    else if (this.croyance)
                    {
                        if (info.God == null)
                        {
                            str = "Non croyant";
                        }
                        else
                        {
                            str = info.God.ToString();
                        }
                    }

                    Font font = new Font(System.Drawing.FontFamily.GenericMonospace, 12f, GraphicsUnit.Pixel);

                    var width = str.Length * 7.5f;

                    g.FillRectangle(new SolidBrush(Color.White),
                                    (position.X < this.mapWidth - width ? (float)(position.X) : (float)(position.X - width * 2)),
                                    (float)(position.Y - 10), width, font.Size + 2);
                    g.DrawString(str,
                                 font,
                                 new SolidBrush(Color.Black),
                                 (position.X < this.mapWidth - width ? (float)(position.X) : (float)(position.X - width * 2)), (float)(position.Y - 10));
                }

                if (voronoi)
                {
                    foreach (VEdge vedge in vedges)
                    {
                        g.DrawLine(new System.Drawing.Pen(System.Drawing.Color.Black),
                                   new System.Drawing.Point((int)vedge.Start.X, (int)vedge.Start.Y),
                                   new System.Drawing.Point((int)vedge.End.X, (int)vedge.End.Y));
                    }
                }
            }

            return(ImageSourceFromBitmap(bmp));
        }
示例#26
0
    /*
     * implicit parameters: nsites, sqrt_nsites, xmin, xmax, ymin, ymax, deltax,
     * deltay (can all be estimates). Performance suffers if they are wrong;
     * better to make nsites, deltax, and deltay too big than too small. (?)
     */
    private bool voronoi_bd()
    {
        Site     newsite, bot, top, temp, p;
        Site     v;
        VPoint   newintstar = null;
        int      pm;
        Halfedge lbnd, rbnd, llbnd, rrbnd, bisector;
        Edge     e;

        PQinitialize();
        ELinitialize();

        bottomsite = nextone();
        newsite    = nextone();
        while (true)
        {
            if (!PQempty())
            {
                newintstar = PQ_min();
            }
            // if the lowest site has a smaller y value than the lowest vector
            // intersection,
            // process the site otherwise process the vector intersection

            if (newsite != null && (PQempty() ||
                                    newsite.coord.y < newintstar.y ||
                                    (newsite.coord.y == newintstar.y &&
                                     newsite.coord.x < newintstar.x)))
            {
                /* new site is smallest -this is a site event */
                // get the first HalfEdge to the LEFT of the new site
                lbnd = ELleftbnd((newsite.coord));
                // get the first HalfEdge to the RIGHT of the new site
                rbnd = ELright(lbnd);
                // if this halfedge has no edge,bot =bottom site (whatever that
                // is)
                bot = rightreg(lbnd);
                // create a new edge that bisects
                e = bisect(bot, newsite);

                // create a new HalfEdge, setting its ELpm field to 0
                bisector = HEcreate(e, LE);
                // insert this new bisector edge between the left and right
                // vectors in a linked list
                ELinsert(lbnd, bisector);

                // if the new bisector intersects with the left edge,
                // remove the left edge's vertex, and put in the new one
                if ((p = intersect(lbnd, bisector)) != null)
                {
                    PQdelete(lbnd);
                    PQinsert(lbnd, p, dist(p, newsite));
                }
                lbnd = bisector;
                // create a new HalfEdge, setting its ELpm field to 1
                bisector = HEcreate(e, RE);
                // insert the new HE to the right of the original bisector
                // earlier in the IF stmt
                ELinsert(lbnd, bisector);

                // if this new bisector intersects with the new HalfEdge
                if ((p = intersect(bisector, rbnd)) != null)
                {
                    // push the HE into the ordered linked list of vertices
                    PQinsert(bisector, p, dist(p, newsite));
                }
                newsite = nextone();
            }
            else if (!PQempty())
            /* intersection is smallest - this is a vector event */
            {
                // pop the HalfEdge with the lowest vector off the ordered list
                // of vectors
                lbnd = PQextractmin();
                // get the HalfEdge to the left of the above HE
                llbnd = ELleft(lbnd);
                // get the HalfEdge to the right of the above HE
                rbnd = ELright(lbnd);
                // get the HalfEdge to the right of the HE to the right of the
                // lowest HE
                rrbnd = ELright(rbnd);
                // get the Site to the left of the left HE which it bisects
                bot = leftreg(lbnd);
                // get the Site to the right of the right HE which it bisects
                top = rightreg(rbnd);

                v = lbnd.vertex; // get the vertex that caused this event
                makevertex(v);   // set the vertex number - couldn't do this
                                 // earlier since we didn't know when it would be processed
                endpoint(lbnd.ELedge, lbnd.ELpm, v);
                // set the endpoint of
                // the left HalfEdge to be this vector
                endpoint(rbnd.ELedge, rbnd.ELpm, v);
                // set the endpoint of the right HalfEdge to
                // be this vector
                ELdelete(lbnd); // mark the lowest HE for
                                // deletion - can't delete yet because there might be pointers
                                // to it in Hash Map
                PQdelete(rbnd);
                // remove all vertex events to do with the right HE
                ELdelete(rbnd); // mark the right HE for
                                // deletion - can't delete yet because there might be pointers
                                // to it in Hash Map
                pm = LE;        // set the pm variable to zero

                if (bot.coord.y > top.coord.y)
                // if the site to the left of the event is higher than the
                // Site
                { // to the right of it, then swap them and set the 'pm'
                  // variable to 1
                    temp = bot;
                    bot  = top;
                    top  = temp;
                    pm   = RE;
                }
                e = bisect(bot, top);       // create an Edge (or line)
                                            // that is between the two Sites. This creates the formula of
                                            // the line, and assigns a line number to it
                bisector = HEcreate(e, pm); // create a HE from the Edge 'e',
                                            // and make it point to that edge
                                            // with its ELedge field
                ELinsert(llbnd, bisector);  // insert the new bisector to the
                                            // right of the left HE
                endpoint(e, RE - pm, v);    // set one endpoint to the new edge
                                            // to be the vector point 'v'.
                                            // If the site to the left of this bisector is higher than the
                                            // right Site, then this endpoint
                                            // is put in position 0; otherwise in pos 1

                // if left HE and the new bisector intersect, then delete
                // the left HE, and reinsert it
                if ((p = intersect(llbnd, bisector)) != null)
                {
                    PQdelete(llbnd);
                    PQinsert(llbnd, p, dist(p, bot));
                }

                // if right HE and the new bisector intersect, then
                // reinsert it
                if ((p = intersect(bisector, rrbnd)) != null)
                {
                    PQinsert(bisector, p, dist(p, bot));
                }
            }
            else
            {
                break;
            }
        }

        for (lbnd = ELright(ELleftend); lbnd != ELrightend; lbnd = ELright(lbnd))
        {
            e = lbnd.ELedge;
            clip_line(e);
        }

        return(true);
    }
示例#27
0
    /* returns true if p is to right of halfedge e */
    private bool right_of(Halfedge el, VPoint p)
    {
        Edge   e;
        Site   topsite;
        bool   right_of_site;
        bool   above, fast;
        double dxp, dyp, dxs, t1, t2, t3, yl;

        e       = el.ELedge;
        topsite = e.reg[1];

        if (p.x > topsite.coord.x)
        {
            right_of_site = true;
        }
        else
        {
            right_of_site = false;
        }

        if (right_of_site && el.ELpm == LE)
        {
            return(true);
        }
        if (!right_of_site && el.ELpm == RE)
        {
            return(false);
        }

        if (e.a == 1.0)
        {
            dxp  = p.x - topsite.coord.x;
            dyp  = p.y - topsite.coord.y;
            fast = false;

            if ((!right_of_site & (e.b < 0.0)) | (right_of_site & (e.b >= 0.0)))
            {
                above = dyp >= e.b * dxp;
                fast  = above;
            }
            else
            {
                above = p.x + p.y * e.b > e.c;
                if (e.b < 0.0)
                {
                    above = !above;
                }
                if (!above)
                {
                    fast = true;
                }
            }
            if (!fast)
            {
                dxs   = topsite.coord.x - (e.reg[0]).coord.x;
                above = e.b * (dxp * dxp - dyp * dyp)
                        < dxs * dyp * (1.0 + 2.0 * dxp / dxs + e.b * e.b);

                if (e.b < 0)
                {
                    above = !above;
                }
            }
        }
        else // e.b == 1.0
        {
            yl    = e.c - e.a * p.x;
            t1    = p.y - yl;
            t2    = p.x - topsite.coord.x;
            t3    = yl - topsite.coord.y;
            above = t1 * t1 > t2 * t2 + t3 * t3;
        }
        return(el.ELpm == LE ? above : !above);
    }
示例#28
0
    private Halfedge ELleftbnd(VPoint p)
    {
        int      bucket;
        Halfedge he;

        /* Use hash table to get close to desired halfedge */
        // use the hash function to find the place in the hash map that this
        // HalfEdge should be
        bucket = (int)((p.x - xmin) / deltax * ELhashsize);

        // make sure that the bucket position is within the range of the hash
        // array
        if (bucket < 0)
        {
            bucket = 0;
        }
        if (bucket >= ELhashsize)
        {
            bucket = ELhashsize - 1;
        }

        he = ELgethash(bucket);

        // if the HE isn't found, search backwards and forwards in the hash map
        // for the first non-null entry
        if (he == null)
        {
            for (int i = 1; i < ELhashsize; i++)
            {
                if ((he = ELgethash(bucket - i)) != null)
                {
                    break;
                }
                if ((he = ELgethash(bucket + i)) != null)
                {
                    break;
                }
            }
        }

        /* Now search linear list of halfedges for the correct one */
        if (he == ELleftend || (he != ELrightend && right_of(he, p)))
        {
            // keep going right on the list until either the end is reached, or
            // you find the 1st edge which the point isn't to the right of
            do
            {
                he = he.ELright;
            }while (he != ELrightend && right_of(he, p));
            he = he.ELleft;
        }
        else
        // if the point is to the left of the HalfEdge, then search left for
        // the HE just to the left of the point
        {
            do
            {
                he = he.ELleft;
            }while (he != ELleftend && !right_of(he, p));
        }

        /* Update hash table and reference counts */
        if (bucket > 0 && bucket < ELhashsize - 1)
        {
            ELhash[bucket] = he;
        }

        return(he);
    }
示例#29
0
        private static void AddBoundingBoxEdges(LinkedList <VEdge> edges, double minX, double minY, double maxX, double maxY)
        {
            // TODO: Need to clean this up....

            var edgesCopy = edges.ToList();
            var leftEdges = edgesCopy
                            .Where(edge => edge.Start.X.ApproxEqual(minX) || edge.End.X.ApproxEqual(minX))
                            .Select(edge => new BoundingBoxInfo {
                Edge = edge, Vertex = edge.Start.X.ApproxEqual(minX) ? edge.Start : edge.End, Start = edge.Start.X.ApproxEqual(minX)
            })
                            .OrderBy(info => info.Vertex.Y)
                            .ToArray();

            var topLeftPoint     = new VPoint(minX, minY);
            var topRightPoint    = new VPoint(maxX, minY);
            var bottomLeftPoint  = new VPoint(minX, maxY);
            var bottomRightPoint = new VPoint(maxX, maxY);

            var startPoint = topLeftPoint;

            for (var i = 0; i < leftEdges.Length; i++)
            {
                var currentEdge = leftEdges[i];
                var site        = currentEdge.Start ? currentEdge.Edge.Left : currentEdge.Edge.Right;
                edges.AddLast(AddEdgeForBoundingBox(startPoint, currentEdge.Vertex, site, true));

                startPoint = currentEdge.Vertex;

                if (i < leftEdges.Length - 1)
                {
                    continue;
                }

                site = currentEdge.Start ? currentEdge.Edge.Right : currentEdge.Edge.Left;
                edges.AddLast(AddEdgeForBoundingBox(startPoint, bottomLeftPoint, site, false));
            }

            var topEdges = edgesCopy
                           .Where(edge => edge.Start.Y.ApproxEqual(minY) || edge.End.Y.ApproxEqual(minY))
                           .Select(edge => new BoundingBoxInfo {
                Edge = edge, Vertex = edge.Start.Y.ApproxEqual(minY) ? edge.Start : edge.End, Start = edge.Start.Y.ApproxEqual(minY)
            })
                           .OrderBy(info => info.Vertex.X)
                           .ToArray();

            startPoint = topLeftPoint;
            for (var i = 0; i < topEdges.Length; i++)
            {
                var currentEdge = topEdges[i];
                var site        = currentEdge.Start ? currentEdge.Edge.Right : currentEdge.Edge.Left;
                edges.AddLast(AddEdgeForBoundingBox(startPoint, currentEdge.Vertex, site, false));

                startPoint = currentEdge.Vertex;

                if (i < topEdges.Length - 1)
                {
                    continue;
                }

                site = currentEdge.Start ? currentEdge.Edge.Left : currentEdge.Edge.Right;
                edges.AddLast(AddEdgeForBoundingBox(startPoint, topRightPoint, site, true));
            }

            var rightEdges = edgesCopy
                             .Where(edge => edge.Start.X.ApproxEqual(maxX) || edge.End.X.ApproxEqual(maxX))
                             .Select(edge => new BoundingBoxInfo {
                Edge = edge, Vertex = edge.Start.X.ApproxEqual(maxX) ? edge.Start : edge.End, Start = edge.Start.X.ApproxEqual(maxX)
            })
                             .OrderBy(info => info.Vertex.Y)
                             .ToArray();

            startPoint = topRightPoint;
            for (var i = 0; i < rightEdges.Length; i++)
            {
                var currentEdge = rightEdges[i];
                var site        = currentEdge.Start ? currentEdge.Edge.Right : currentEdge.Edge.Left;
                edges.AddLast(AddEdgeForBoundingBox(startPoint, currentEdge.Vertex, site, false));

                startPoint = currentEdge.Vertex;

                if (i < rightEdges.Length - 1)
                {
                    continue;
                }

                site = currentEdge.Start ? currentEdge.Edge.Left : currentEdge.Edge.Right;
                edges.AddLast(AddEdgeForBoundingBox(startPoint, bottomRightPoint, site, true));
            }

            var bottomEdges = edgesCopy
                              .Where(edge => edge.Start.Y.ApproxEqual(maxY) || edge.End.Y.ApproxEqual(maxY))
                              .Select(edge => new BoundingBoxInfo {
                Edge = edge, Vertex = edge.Start.Y.ApproxEqual(maxY) ? edge.Start : edge.End, Start = edge.Start.Y.ApproxEqual(maxY)
            })
                              .OrderBy(info => info.Vertex.X)
                              .ToArray();

            startPoint = bottomLeftPoint;
            for (var i = 0; i < bottomEdges.Length; i++)
            {
                var currentEdge = bottomEdges[i];
                var site        = currentEdge.Start ? currentEdge.Edge.Left : currentEdge.Edge.Right;
                edges.AddLast(AddEdgeForBoundingBox(startPoint, currentEdge.Vertex, site, false));

                startPoint = currentEdge.Vertex;

                if (i < bottomEdges.Length - 1)
                {
                    continue;
                }

                site = currentEdge.Start ? currentEdge.Edge.Right : currentEdge.Edge.Left;
                edges.AddLast(AddEdgeForBoundingBox(startPoint, bottomRightPoint, site, true));
            }
        }
示例#30
0
 public Site()
 {
     coord = new VPoint();
 }