예제 #1
0
파일: View.cs 프로젝트: raikoss/SnakeUnmess
        public void UpdatePoint(Models.Point point, string pointType = "")
        {
            switch (pointType)
            {
            case "Tail":
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.SetCursorPosition(point.X, point.Y);
                Console.Write("0");
                break;

            case "Head":
                Console.SetCursorPosition(point.X, point.Y);
                Console.Write("@");
                break;

            case "Apple":
                Console.ForegroundColor = ConsoleColor.Green;
                Console.SetCursorPosition(point.X, point.Y);
                Console.Write("$");
                break;

            default:
                Console.SetCursorPosition(point.X, point.Y);
                Console.Write(" ");
                break;
            }
        }
 public Connection(Models.Point start, Models.Point end)
 {
     Points = new List <Models.Point>()
     {
         start, end
     };
 }
        public ConnectorOrientation CalculateOrientation(IInput item, Models.Point relativeCoords)
        {
            var coords = new List <Models.Point>
            {
                new Models.Point(0, item.Height / 2),          // LEFT
                new Models.Point(item.Width / 2, 0),           // TOP
                new Models.Point(item.Width, item.Height / 2), // RIGHT
                new Models.Point(item.Width / 2, item.Height)  // BOTTOM
            };

            var    closestPoint           = new Models.Point();
            double closestDistanceSquared = double.MaxValue;

            foreach (var point in coords)
            {
                var distanceSquared = Math.Pow(point.X - relativeCoords.X, 2) + Math.Pow(point.Y - relativeCoords.Y, 2);

                if (distanceSquared < closestDistanceSquared)
                {
                    closestDistanceSquared = distanceSquared;
                    closestPoint           = point;
                }
            }

            var orientation = coords.IndexOf(closestPoint);

            return((ConnectorOrientation)Enum.Parse(typeof(ConnectorOrientation), orientation.ToString()));
        }
예제 #4
0
 /// <summary>
 /// 创建 <see cref="ProductPage"/>
 /// </summary>
 /// <param name="point">已经查询好的据点对象</param>
 /// <param name="currentUserId">当前登录用户 ID</param>
 /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
 /// <param name="cachedData"><see cref="CachedDataProvider"/></param>
 /// <returns><see cref="ProductPage"/></returns>
 public static async Task <ProductPage> CreateAsync(Models.Point point, string currentUserId,
                                                    KeylolDbContext dbContext, CachedDataProvider cachedData)
 {
     return(new ProductPage
     {
         Products = await ProductPointList.CreateAsync(currentUserId, point.Id, dbContext, cachedData)
     });
 }
        private void AddNode(Models.Point data)
        {
            Node node = new Node(data.X, data.Y);

            if (this._graph.Find(data.X, data.Y) == null)
            {
                this._graph.AddNode(node);
            }
        }
예제 #6
0
        public static void Draw(Graphics g, Models.Point point)
        {
            using (var brush = new SolidBrush(point.Color))
            {
                var x = point.Position.X - (point.Size.Width / 2);
                var y = point.Position.Y - (point.Size.Height / 2);

                g.FillEllipse(brush, new RectangleF(new System.Drawing.PointF(x, y), point.Size));
            }
        }
예제 #7
0
        public void updatePoint(Models.Point point)
        {
            //string svgPath = $"{AppRoot.GetApplicationRoot()}{point.Scheme}.svg";
            //svgViewBox.Source = new Uri(svgPath);
            lblPointInfo.Content = point.Name;
            var uri    = new Uri($"{AppRoot.GetApplicationRoot()}PNG\\{point.Id}.png");
            var bitmap = new BitmapImage(uri);

            imgPoint.Source = bitmap;
            task.Point      = point;
        }
예제 #8
0
        private static void ConvertPerimeterPointsToTurnString(
            IReadOnlyList <PointInt> points,
            out PointInt start,
            out PointInt initialDirection,
            out string turns)
        {
            // a single pixel mask should induce four perimeter points
            if (points.Count < 4)
            {
                throw new ArgumentException("Too few points, expected at least four.", nameof(points));
            }

            using (var stringWriter = new StringWriter())
            {
                var previous  = points.Last();
                var direction = new PointInt(points[0].X - previous.X, points[0].Y - previous.Y);

                previous = points[0];

                for (int i = 1; i <= points.Count; i++)
                {
                    var j     = i >= points.Count ? i - points.Count : i;
                    var delta = new PointInt(points[j].X - previous.X, points[j].Y - previous.Y);

                    if (delta.X == direction.X && delta.Y == direction.Y)
                    {
                        stringWriter.Write(TurtleForward);
                    }
                    else if (delta.X == -direction.Y && delta.Y == direction.X)
                    {
                        stringWriter.Write(TurtleLeft);
                    }
                    else if (delta.X == direction.Y && delta.Y == -direction.X)
                    {
                        stringWriter.Write(TurtleRight);
                    }
                    else
                    {
                        // Contour has doubled back on itself
                        throw new ArgumentException($"Degenerate contour: delta = {delta}, direction = {direction}", nameof(points));
                    }

                    previous  = points[j];
                    direction = delta;
                }

                turns = stringWriter.ToString();
            }

            start = points[0];
            var last = points[points.Count - 1];

            initialDirection = new PointInt(start.X - last.X, start.Y - last.Y);
        }
예제 #9
0
        /// <summary>
        /// 创建 <see cref="BriefReviewList"/>
        /// </summary>
        /// <param name="point">据点对象</param>
        /// <param name="currentUserId">当前登录用户 ID</param>
        /// <param name="page">分页页码</param>
        /// <param name="returnCount">是否返回总数</param>
        /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
        /// <param name="cachedData"><see cref="CachedDataProvider"/></param>
        /// <returns>Item1 表示 <see cref="BriefReviewList"/>,Item2 表示总数,Item3 表示总页数</returns>
        public static async Task <Tuple <BriefReviewList, int, int> > CreateAsync(Models.Point point, string currentUserId,
                                                                                  int page, bool returnCount, KeylolDbContext dbContext, CachedDataProvider cachedData)
        {
            var queryResult = await(from activity in dbContext.Activities
                                    where activity.TargetPointId == point.Id && activity.Rating != null &&
                                    activity.Archived == ArchivedState.None && activity.Rejected == false
                                    orderby dbContext.Likes
                                    .Count(l => l.TargetId == activity.Id && l.TargetType == LikeTargetType.Activity) descending
                                    select new
            {
                Count = returnCount
                        ? dbContext.Activities.Count(
                    a => a.TargetPointId == point.Id && a.Rating != null && a.Archived == ArchivedState.None)
                        : 1,
                activity.Id,
                activity.AuthorId,
                AuthorIdCode      = activity.Author.IdCode,
                AuthorAvatarImage = activity.Author.AvatarImage,
                AuthorUserName    = activity.Author.UserName,
                activity.SidForAuthor,
                activity.Rating,
                activity.Content
            }).TakePage(page, RecordsPerPage).ToListAsync();

            var result = new BriefReviewList(queryResult.Count);

            foreach (var a in queryResult)
            {
                result.Add(new BriefReview
                {
                    Id                = a.Id,
                    AuthorIdCode      = a.AuthorIdCode,
                    AuthorAvatarImage = a.AuthorAvatarImage,
                    AuthorUserName    = a.AuthorUserName,
                    AuthorPlayedTime  = point.SteamAppId == null
                        ? null
                        : (await dbContext.UserSteamGameRecords
                           .Where(r => r.UserId == a.AuthorId && r.SteamAppId == point.SteamAppId)
                           .SingleOrDefaultAsync())?.TotalPlayedTime,
                    SidForAuthor = a.SidForAuthor,
                    Rating       = a.Rating,
                    LikeCount    = await cachedData.Likes.GetTargetLikeCountAsync(a.Id, LikeTargetType.Activity),
                    Liked        = string.IsNullOrWhiteSpace(currentUserId)
                        ? (bool?)null
                        : await cachedData.Likes.IsLikedAsync(currentUserId, a.Id, LikeTargetType.Activity),
                    Content = a.Content
                });
            }
            var firstRecord = queryResult.FirstOrDefault();

            return(new Tuple <BriefReviewList, int, int>(result,
                                                         firstRecord?.Count ?? 0,
                                                         (int)Math.Ceiling(firstRecord?.Count / (double)RecordsPerPage ?? 1)));
        }
예제 #10
0
 /// <summary>
 /// Creates a new instance of the class.
 /// </summary>
 /// <param name="points"></param>
 /// <param name="voxelCounts"></param>
 /// <param name="insideOfPolygon"></param>
 /// <param name="isBackground"></param>
 /// <param name="startPointMinimumY"></param>
 public PolygonPoints(
     PointInt[] points,
     VoxelCounts voxelCounts,
     ushort insideOfPolygon,
     bool isInside,
     PointInt startPointMinimumY)
 {
     Points             = points ?? throw new ArgumentNullException(nameof(points));
     VoxelCounts        = voxelCounts ?? throw new ArgumentNullException(nameof(voxelCounts));
     InsideOfPolygon    = insideOfPolygon;
     IsInnerContour     = isInside;
     StartPointMinimumY = startPointMinimumY;
 }
        private void AddEdge(Models.Point sourcePoint, Models.Point destinationPoint)
        {
            var  source = this._graph.Find(sourcePoint.X, sourcePoint.Y);
            var  dest   = this._graph.Find(destinationPoint.X, destinationPoint.Y);
            Edge edge   = new Edge
            {
                Source      = source,
                Destination = dest,
                Weight      = Distance(new Models.Point(sourcePoint.X, sourcePoint.Y), new Models.Point(destinationPoint.X, destinationPoint.Y))
            };

            this._graph.AddEdge(source, dest, edge);
        }
예제 #12
0
        private void TouchMove(float x, float y)
        {
            float dx = Math.Abs(x - mX);
            float dy = Math.Abs(y - mY);

            if (dx >= 4 || dy >= 4)
            {
                Models.Point point1 = new Models.Point(x, y);
                Models.Point point2 = new Models.Point((x + mX) / 2, (y + mY) / 2);
                serializablePath.QuadTo(point1, point2);

                mX = x;
                mY = y;
            }
        }
예제 #13
0
 private void Circle_GotFocus(object sender, RoutedEventArgs e)
 {
     (sender as Ellipse).Stroke = Brushes.Red;
     (sender as Ellipse).Fill   = Brushes.Red;
     pointSelected        = departSelected.Point.Where(p => p.Id.ToString() == (string)(sender as Ellipse).Tag).FirstOrDefault();
     lblPointInfo.Content = $"Точка: {pointSelected.Name}";
     foreach (Ellipse ellispe in svgCanvas.Children)
     {
         if ((string)ellispe.Tag != pointSelected.Id.ToString())
         {
             ellispe.Stroke = Brushes.Blue;
             ellispe.Fill   = Brushes.Blue;
         }
     }
 }
예제 #14
0
 /// <summary>
 /// 创建 <see cref="StylePage"/>
 /// </summary>
 /// <param name="point">据点对象</param>
 /// <returns><see cref="StylePage"/></returns>
 public static StylePage Create(Models.Point point)
 {
     if (point.Type != PointType.Game && point.Type != PointType.Hardware)
     {
         return new StylePage
                {
                    Nothing = true
                }
     }
     ;
     return(new StylePage
     {
         MediaHeaderImage = point.MediaHeaderImage,
         ThumbnailImage = point.ThumbnailImage
     });
 }
예제 #15
0
 public EachKey(XmlElement node)
 {
     try {
         leftUp = new Models.Point(float.Parse(
                                       node.FirstChild.NextSibling.FirstChild.InnerText),
                                   float.Parse(node.FirstChild.NextSibling.FirstChild.NextSibling.InnerText));
         rightDown = new Models.Point(float.Parse(
                                          node.FirstChild.NextSibling.NextSibling.FirstChild.InnerText),
                                      float.Parse(node.FirstChild.NextSibling.NextSibling.FirstChild.NextSibling.InnerText));
         content = node.FirstChild.NextSibling.NextSibling.NextSibling.InnerText;
     } catch {
         Debug.WriteLine("XML格式出错");
     } finally {
         Debug.WriteLine(node.FirstChild.NextSibling.FirstChild.InnerText);
         Debug.WriteLine(node.FirstChild.NextSibling.FirstChild.NextSibling.InnerText);
         Debug.WriteLine(node.FirstChild.NextSibling.NextSibling.FirstChild.InnerText);
         Debug.WriteLine(node.FirstChild.NextSibling.NextSibling.FirstChild.NextSibling.InnerText);
         Debug.WriteLine(node.FirstChild.NextSibling.NextSibling.NextSibling.InnerText);
     }
 }
예제 #16
0
        /// <summary>
        /// Finds the index of the PointF such that the line from points[index] to points[index+1]
        /// intersects the vertical line at start.X, and where the Y coordinate is smaller than
        /// start.Y. If there are multiple intersections, return
        /// the one with maximum Y coordinate if <paramref name="searchForHighestY"/> is true.
        /// This is used to search for the lowest PointF (highest Y) in a parent contour that is
        /// above the child contour.
        /// If <paramref name="searchForHighestY"/> is false, find the intersection with minimum Y coordinate,
        /// without constraints on start.Y.
        /// </summary>
        /// <param name="points"></param>
        /// <param name="x"></param>
        /// <returns></returns>
        public static int FindIntersectingPoints(IReadOnlyList <PointF> points, PointInt start, bool searchForHighestY)
        {
            float?bestY     = null;
            var   bestIndex = -1;
            var   startX    = start.X;

            // When merging a child contour with a parent contour: Points is the parent contour, start
            // is the search start PointF of the inner (child) contour.
            // Search for the line segment of the parent that is closest above the child start PointF.
            // The child is assumed to be fully contained in the parent, hence such a PointF must exist.
            // Among those points, search for the PointF that is closest to the child contour, above the child contour.
            var PointF = points[0];

            for (var index = 1; index <= points.Count; index++)
            {
                var nextPoint = index == points.Count ? points[0] : points[index];

                // A line segment above the start PointF can come from either side, depending on the winding of the parent
                // contour
                if ((PointF.X <= startX && nextPoint.X > startX) ||
                    (nextPoint.X < startX && PointF.X >= startX))
                {
                    var isAboveStart = PointF.Y <= start.Y || nextPoint.Y <= start.Y;
                    if ((searchForHighestY && isAboveStart && (bestY == null || PointF.Y > bestY)) ||
                        (!searchForHighestY && (bestY == null || PointF.Y < bestY)))
                    {
                        bestIndex = index - 1;
                        bestY     = PointF.Y;
                    }
                }

                PointF = nextPoint;
            }

            if (bestIndex < 0)
            {
                throw new ArgumentException($"Inconsistent arguments: The polygon does not contain a line segment that intersects at X = {startX}.", nameof(points));
            }

            return(bestIndex);
        }
예제 #17
0
        // create dummy data
        private void InitSeries()
        {
            Random random = new Random((int)DateTime.Now.Ticks & 0x0000FFFF);


            // data for the first half. x range 36-64
            for (int i = 0; i < 1; i++)
            {
                var rssiPoint = new Models.Point();
                rssiPoint.x = 38;
                rssiPoint.y = 16;

                var aPoint = new Models.Point();
                aPoint.x = 45;
                aPoint.y = 12;

                var bPoint = new Models.Point();
                bPoint.x = 55;
                bPoint.y = 10;

                var dPoint = new Models.Point();
                dPoint.x = 59;
                dPoint.y = 14;

                var ePoint = new Models.Point();
                ePoint.x = 60;
                ePoint.y = 13;

                var curve = new Curve();

                curve.Points.Add(aPoint);
                curve.Points.Add(bPoint);
                curve.Points.Add(rssiPoint);
                curve.Points.Add(dPoint);
                curve.Points.Add(ePoint);

                Series.Add(curve);
            }
        }
예제 #18
0
        public double TotalPerimeter(double dl, double psize, bool show)
        {
            List <Models.Point> newPoints = new List <Models.Point>();


            foreach (Models.Figure myfig in Figures)
            {
                foreach (Point3D p in myfig.DropPointsOnPerimeter(dl))
                {
                    Models.Point newPoint = new Models.Point()
                    {
                        Id       = -9,
                        Radius   = psize,
                        Color    = Colors.Green,
                        Position = new Point3D(p.X, p.Y, 0.01),
                    };

                    foreach (Models.Figure fig in Figures)
                    {
                        if (fig != myfig)
                        {
                            if (fig.Hitted(newPoint))
                            {
                                newPoint.Color = Colors.Orange;
                            }
                        }
                    }

                    newPoints.Add(newPoint);
                }
            }
            if (show)
            {
                Figures.AddRange(newPoints);
            }

            return(newPoints.Where(p => p.Color == Colors.Green).Count() * dl);
        }
예제 #19
0
        private async void _OpcProcessor_LapCompleted(bool fromHome)
        {
            cycleCount++;
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                                      () =>
            {
                CycleCount.Text = cycleCount.ToString();
            });

            if (cycleCount == 1)
            {
                return;
            }

            await Task.Delay(_Delay + 100).ContinueWith(async(h) =>
            {
                var list = new List <Models.Point>();
                MainLineCollection.ToList().ForEach(x =>
                {
                    list.Add(new Models.Point(x.X, x.Y));
                });
                CountingCollection.Add(list);
                await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                                          () =>
                {
                    CycleCount.Text = cycleCount.ToString();
                    int i           = MainLineCollectionH.Count > 0 ? MainLineCollectionH.Max(x => x.X) : 0;
                    MainLineCollection.ToList().ForEach(x =>
                    {
                        var p = new Models.Point(i++, x.Y);
                        MainLineCollectionH.Add(p);
                    });
                    var p0 = new Models.Point(i++, 0);
                    MainLineCollectionH.Add(p0);
                });
            });
        }
예제 #20
0
 public TestViewModel(IEventAggregator eventAggregator, IWindowManager windowManager)
 {
     //初始化
     _windowManager      = windowManager;
     _eventAggregator    = eventAggregator;
     _connectStatusEvent = new ConnectStatusEvent("离线!", "离线!");
     Workrec1            = new Workrec();
     Workrec2            = new Workrec();
     Holerec1            = new Holerec();
     Holerec2            = new Holerec();
     Point1       = new Models.Point();
     Point2       = new Models.Point();
     ActualPoint1 = new ActualPoint();
     ActualPoint2 = new ActualPoint();
     StartTime    = DateTime.Now.AddDays(-5);
     CanRedo2     = CanStop1 = CanRedo1 = CanStop2 = Working1 = Working2 = SubWorking1 = SubWorking2 = false;
     CanStart1    = CanStart2 = true;
     ReadValue.ConnnectPlc1();
     InitalChart();
     // 默认情况下开始画面曲线数据刷新
     IsReading = IsWorking1 = true;
     Read1();
     FreshCurve();
 }
예제 #21
0
        public async Task <IHttpActionResult> PopulateBuildingTableFromImport()
        {
            using (var db = DbHelper.GetDb())
            {
                var incoming = await db.OuMapDumpBuildings.ToListAsync();

                incoming.ForEach(b =>
                {
                    var customData = JsonConvert.DeserializeObject <OuMapsCustomGeoData>(b.geodata);
                    var marker     = new Models.Point()
                    {
                        Position = new Position()
                        {
                            Longitude = customData.Longitude,
                            Latitude  = customData.Latitude
                        }
                    };
                    var shape    = customData.Polygon;
                    var location = new Models.DB.Location()
                    {
                        Name        = b.loctitle,
                        Description = b.loctext,
                        ImgUrl      = string.IsNullOrEmpty(b.locimg) ? b.locimg : "http://www.ou.edu" + b.locimg,
                        MarkerData  = JsonConvert.SerializeObject(marker, Formatting.Indented),
                        GeoData     = JsonConvert.SerializeObject(shape, Formatting.Indented)
                    };
                    location.Building = new Models.DB.Building()
                    {
                        BuildingCode = b.loccode
                    };
                    db.Locations.Add(location);
                });

                return(Ok(await db.SaveChangesAsync()));
            }
        }
예제 #22
0
        private async void ImprimirButton_Click(object sender, RoutedEventArgs e)
        {
            if (CountingCollection.Count <= 0)
            {
                var dialog = new MessageDialog("No se ha completado al menos un ciclo");
                await dialog.ShowAsync();

                return;
            }
            List <Models.Point> avgs = new List <Models.Point>();

            for (int i = 0; i < CountingCollection.First().Count; i++)
            {
                var p = new Models.Point(CountingCollection.First()[i].X, 0);
                avgs.Add(p);
            }

            var csvString = new System.Text.StringBuilder();

            CountingCollection.ForEach(y =>
            {
                var line = "";
                y.ForEach(x =>
                {
                    line += x.Y + ",";
                    avgs.First(z => z.X == x.X).Y += x.Y;
                });
                csvString.AppendLine(line);
            });
            avgs.ForEach(y =>
            {
                y.Y = y.Y / CountingCollection.Count;
            });
            avgs.ForEach(y =>
            {
                MainLineCollection.ToList().First(x => x.X == y.X).Y = y.Y;
            });
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
                                      () =>
            {
                MainLineSeries.Refresh();
            });

            LineChart.Width  = LineChart.ActualWidth;
            LineChart.Height = LineChart.ActualHeight;
            var bitmap = new RenderTargetBitmap();
            await bitmap.RenderAsync(LineChart, (int)LineChart.Width, (int)LineChart.Height);

            var pixelBuffer = await bitmap.GetPixelsAsync();

            var displayInformation = DisplayInformation.GetForCurrentView();
            var guid = Guid.NewGuid();
            var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(guid + ".png", CreationCollisionOption.ReplaceExisting);

            var csvfile = await ApplicationData.Current.LocalFolder.CreateFileAsync(guid + ".csv", CreationCollisionOption.ReplaceExisting);

            using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
            {
                var encoder = await Windows.Graphics.Imaging.BitmapEncoder.CreateAsync(Windows.Graphics.Imaging.BitmapEncoder.PngEncoderId, stream);

                encoder.SetPixelData(BitmapPixelFormat.Bgra8,
                                     BitmapAlphaMode.Premultiplied,
                                     (uint)LineChart.ActualWidth,
                                     (uint)LineChart.ActualHeight,
                                     displayInformation.RawDpiX,
                                     displayInformation.RawDpiY,
                                     pixelBuffer.ToArray());
                await encoder.FlushAsync();
            }
            using (var stream = await csvfile.OpenAsync(FileAccessMode.ReadWrite))
            {
                await stream.AsStreamForWrite().WriteAsync(System.Text.Encoding.ASCII.GetBytes(csvString.ToString()), 0, csvString.Length);
            }
            var page = new PageToPrint();
            var bmp  = new BitmapImage(new Uri("ms-appdata:///local/" + guid + ".png"));

            page.ScenarioImage.Source   = bmp;
            page.OrdenTextBlock.Text    = labelOrderCustName.Text.ToUpper();
            page.SkuTextBlock.Text      = labelOrderSku.Text;
            page.OperadorTextBlock.Text = labelOrderOperador.Text.ToUpper();
            page.TurnoTextBlock.Text    = labelOrderTurno.Text;
            page.LongitudTextBlock.Text = labelOrderLongitud.Text;
            page.AdhesivoTextBlock.Text = labelOrderAdhesivo.Text;
            page.AreaTextBlock.Text     = labelOrderArea.Text;
            var observaciones = new System.Text.StringBuilder();
            var ix            = 0;

            if (!string.IsNullOrEmpty(labelOrderObservaciones.Text))
            {
                while (true)
                {
                    var line = "";
                    try
                    {
                        line = labelOrderObservaciones.Text.Substring(ix, 60);
                        ix  += 60;
                        observaciones.AppendLine(line);
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        line = labelOrderObservaciones.Text.Substring(ix);
                        observaciones.AppendLine(line);
                        break;
                    }
                }
            }

            page.ObservacionesTextBlock.Text = observaciones.ToString();
            page.DensPromTextBlock.Text      = avgs.Average(x => x.Y).ToString("#0.00");

            var printHelper = new Services.PrintHelper(this);

            printHelper.StatusChanged += async(string message, int type) =>
            {
                printHelper.UnregisterForPrinting();
                printHelper = null;
                page.ScenarioImage.Source = null;
                try
                {
                    await file.DeleteAsync();
                }
                catch (Exception)
                {
                }
                ResetButton_Click(sender, e);
            };
            printHelper.RegisterForPrinting();
            printHelper.PreparePrintContent(page);
            await printHelper.ShowPrintUIAsync();
        }
예제 #23
0
        public MainViewModel()
        {
            InitCommand = new Command(() =>
            {
                shapes.Clear();
                FileDataReader.ReadDataFile(dataFilePath)
                .Select(line => DataParser.ParseDataLine(line))
                .ToList()
                .ForEach(data =>
                {
                    if (data.Count == 6)
                    {
                        Models.Point a = new Models.Point(data[0], data[1]);
                        Models.Point b = new Models.Point(data[2], data[3]);
                        Models.Point c = new Models.Point(data[4], data[5]);

                        shapes.Add(new Triangle(a, b, c));
                    }
                    else if (data.Count == 8)
                    {
                        Models.Point a = new Models.Point(data[0], data[1]);
                        Models.Point b = new Models.Point(data[2], data[3]);
                        Models.Point c = new Models.Point(data[4], data[5]);
                        Models.Point d = new Models.Point(data[6], data[7]);

                        shapes.Add(new Quadrilateral(a, b, c, d));
                    }
                });
            });

            PlainDrawCommand = new Command(() =>
            {
                OnPropertyChanged(nameof(Lines));
            });

            ColorDrawCommand = new Command(() =>
            {
                double largestQuadPerimeter = shapes
                                              .FindAll(shape => shape is Quadrilateral)
                                              .OrderByDescending(quad => quad.Perimeter)
                                              .First().Perimeter;

                List <Triangle> halfPerimeterTriangles = shapes
                                                         .FindAll(shape => shape is Triangle && shape.Perimeter < largestQuadPerimeter / 2)
                                                         .Cast <Triangle>().ToList();

                halfPerimeterTriangles.ForEach(triangle => triangle.Color = Colors.Blue);

                List <Triangle> twoLargestTriangles = halfPerimeterTriangles
                                                      .OrderByDescending(triangle => triangle.Perimeter)
                                                      .Take(2).ToList();

                twoLargestTriangles.ForEach(triangle => triangle.Color = Colors.Green);
                if (twoLargestTriangles.Count == 2)
                {
                    twoLargestIntersect = twoLargestTriangles[0].Intersects(twoLargestTriangles[1]);
                }

                OnPropertyChanged(nameof(Lines));
            });

            IntersectCommand = new Command(() =>
            {
                MessageBox.Show(twoLargestIntersect.ToString());
            });

            ExitCommand = new Command(() =>
            {
                Environment.Exit(0);
            });
        }
예제 #24
0
        /// <summary>
        /// 创建 <see cref="FrontpagePage"/>
        /// </summary>
        /// <param name="point">已经查询好的据点对象</param>
        /// <param name="currentUserId">当前登录用户 ID</param>
        /// <param name="dbContext"><see cref="KeylolDbContext"/></param>
        /// <param name="cachedData"><see cref="CachedDataProvider"/></param>
        /// <returns><see cref="FrontpagePage"/></returns>
        public static async Task <FrontpagePage> CreateAsync(Models.Point point, string currentUserId,
                                                             KeylolDbContext dbContext, CachedDataProvider cachedData)
        {
            var frontPage = new FrontpagePage();

            if (point.Type == PointType.Game || point.Type == PointType.Hardware)
            {
                var briefReviews =
                    await BriefReviewList.CreateAsync(point, currentUserId, 1, true, dbContext, cachedData);

                frontPage.BriefReviewCount     = briefReviews.Item2;
                frontPage.BriefReviewPageCount = briefReviews.Item3;
                frontPage.BriefReviews         = briefReviews.Item1;
                frontPage.MediaHeaderImage     = point.MediaHeaderImage;
                frontPage.Media         = Helpers.SafeDeserialize <List <PointMedia> >(point.Media);
                frontPage.SimilarPoints =
                    await SimilarPointList.CreateAsync(point.Id, currentUserId, 1, dbContext, cachedData);

                frontPage.SelectedArticles =
                    await SelectedArticleList.CreateAsync(point.Id, 1, 4, currentUserId, dbContext, cachedData);
            }

            if (point.Type == PointType.Game)
            {
                frontPage.Platforms = await(from relationship in dbContext.PointRelationships
                                            where relationship.SourcePointId == point.Id &&
                                            relationship.Relationship == PointRelationshipType.Platform
                                            orderby relationship.Sid descending
                                            select relationship.TargetPoint.IdCode)
                                      .ToListAsync();

                #region 特性属性

                frontPage.MultiPlayer         = point.MultiPlayer ? true : (bool?)null;
                frontPage.SinglePlayer        = point.SinglePlayer ? true : (bool?)null;
                frontPage.Coop                = point.Coop ? true : (bool?)null;
                frontPage.CaptionsAvailable   = point.CaptionsAvailable ? true : (bool?)null;
                frontPage.CommentaryAvailable = point.CommentaryAvailable ? true : (bool?)null;
                frontPage.IncludeLevelEditor  = point.IncludeLevelEditor ? true : (bool?)null;
                frontPage.Achievements        = point.Achievements ? true : (bool?)null;
                frontPage.Cloud               = point.Cloud ? true : (bool?)null;
                frontPage.LocalCoop           = point.LocalCoop ? true : (bool?)null;
                frontPage.SteamTradingCards   = point.SteamTradingCards ? true : (bool?)null;
                frontPage.SteamWorkshop       = point.SteamWorkshop ? true : (bool?)null;
                frontPage.InAppPurchases      = point.InAppPurchases ? true : (bool?)null;

                #endregion

                frontPage.ChineseAvailability = Helpers.SafeDeserialize <ChineseAvailability>(point.ChineseAvailability);

                if (point.SteamAppId != null)
                {
                    frontPage.AddictedUsers =
                        await AddictedUserList.CreateAsync(currentUserId, point.SteamAppId, 1, dbContext, cachedData);
                }
            }
            else if (point.Type == PointType.Vendor)
            {
                var developerProducts = await ProductPointList.CreateAsync(currentUserId, point.Id,
                                                                           PointRelationshipType.Developer, 3, dbContext, cachedData);

                frontPage.DeveloperProducts     = developerProducts.Item1;
                frontPage.DeveloperProductCount = developerProducts.Item2;

                var publisherProducts = await ProductPointList.CreateAsync(currentUserId, point.Id,
                                                                           PointRelationshipType.Publisher, 3, dbContext, cachedData);

                frontPage.PublisherProducts     = publisherProducts.Item1;
                frontPage.PublisherProductCount = publisherProducts.Item2;

                var resellerProducts = await ProductPointList.CreateAsync(currentUserId, point.Id,
                                                                          PointRelationshipType.Reseller, 3, dbContext, cachedData);

                frontPage.ResellerProducts     = resellerProducts.Item1;
                frontPage.ResellerProductCount = resellerProducts.Item2;

                var manufacturerProducts = await ProductPointList.CreateAsync(currentUserId, point.Id,
                                                                              PointRelationshipType.Manufacturer, 3, dbContext, cachedData);

                frontPage.ManufacturerProducts     = manufacturerProducts.Item1;
                frontPage.ManufacturerProductCount = manufacturerProducts.Item2;
            }
            else if (point.Type == PointType.Category)
            {
                var tagProducts = await ProductPointList.CreateAsync(currentUserId, point.Id,
                                                                     PointRelationshipType.Tag, 3, dbContext, cachedData);

                frontPage.TagProducts     = tagProducts.Item1;
                frontPage.TagProductCount = tagProducts.Item2;

                var seriesProducts = await ProductPointList.CreateAsync(currentUserId, point.Id,
                                                                        PointRelationshipType.Series, 3, dbContext, cachedData);

                frontPage.SeriesProducts     = seriesProducts.Item1;
                frontPage.SeriesProductCount = seriesProducts.Item2;

                var genreProducts = await ProductPointList.CreateAsync(currentUserId, point.Id,
                                                                       PointRelationshipType.Genre, 3, dbContext, cachedData);

                frontPage.GenreProducts     = genreProducts.Item1;
                frontPage.GenreProductCount = genreProducts.Item2;
            }
            else if (point.Type == PointType.Platform)
            {
                var platformProducts = await ProductPointList.CreateAsync(currentUserId, point.Id,
                                                                          PointRelationshipType.Platform, 3, dbContext, cachedData);

                frontPage.PlatformProducts = platformProducts.Item1;
            }

            var latestArticles = await LatestArticleList.CreateAsync(point.Id, 1, true, true, dbContext, cachedData);

            frontPage.LatestArticleHeaderImage = latestArticles.Item3;
            frontPage.LatestArticlePageCount   = latestArticles.Item2;
            frontPage.LatestArticles           = latestArticles.Item1;

            return(frontPage);
        }
 /// <summary>
 /// Simplify a contour defined by a string of moves.
 /// </summary>
 /// <param name="x0"></param>
 /// <param name="d0"></param>
 /// <param name="turns">String of characters in {F,R,L} defining a sequence of one unit long moves.</param>
 /// <returns>Simplified, smoother polygon with fewer vertices.</returns>
 public static PointF[] Simplify(PointInt x0, PointInt d0, string turns)
 {
     var isClosed  = TraceContour(x0, d0, turns, out PointInt[] points, out PointInt[] directions);
예제 #26
0
        private static PointInt[] FindPolygon(
            Volume2D <byte> volume,
            ushort[] foundPolygons,
            ushort searchInsidePolygon,
            PointInt start,
            byte backgroundId,
            bool searchClockwise)
        {
            // Clockwise search starts at a point (x, y) where there is no foreground
            // on lines with smaller y. Next point can hence be in direction 0
            // (neighbor x+1,y) or at directions larger than 0.
            // For counterclockwise search, we start with a point that we know is background,
            // and go to the line above (y-1) from that, where we are guaranteed to find foreground.
            // From that point, going in direction hits the point we know is background, and can
            // continue to search in clockwise direction.
            var nextSearchDirection = searchClockwise ? 0 : 2;
            var done      = false;
            var current   = start;
            var nextPoint = start;
            var contour   = new List <PointInt>();
            var dimX      = volume.DimX;
            var dimY      = volume.DimY;
            var neighbors = Delta.Length;
            var array     = volume.Array;

            (int, PointInt) FindNextPoint(int currentX, int currentY, int deltaIndex)
            {
                for (var i = 0; i < 7; i++)
                {
                    var delta = Delta[deltaIndex];
                    var x     = currentX + delta.X;
                    var y     = currentY + delta.Y;
                    // Manually computing index, rather than relying on GetIndex, brings substantial speedup.
                    var index = x + y * dimX;
                    if (x < 0 || x >= dimX ||
                        y < 0 || y >= dimY ||
                        array[index] == backgroundId ||
                        foundPolygons[index] != searchInsidePolygon)
                    {
                        deltaIndex = (deltaIndex + 1) % neighbors;
                    }
                    else
                    {
                        // found non-background pixel
                        return(deltaIndex, new PointInt(x, y));
                    }
                }
                return(deltaIndex, new PointInt(currentX, currentY));
            }

            while (!done)
            {
                contour.Add(current);
                (nextSearchDirection, nextPoint) = FindNextPoint(
                    current.X,
                    current.Y,
                    nextSearchDirection);

                // Delta positions for search of the next neighbor are specified in clockwise order,
                // starting with the point (x+1,y). After finding a neighbor, reset those by going
                // "back" two increments.
                // Because of % 8, going back by 2 for clockwise search amounts to going forward by 6.
                nextSearchDirection = (nextSearchDirection + 6) % neighbors;

                // Terminate when we are back at the starting position.
                done    = nextPoint == start;
                current = nextPoint;
            }

            return(contour.ToArray());
        }
예제 #27
0
        /// <summary>
        /// Extracts polygons by walking the edge of the foreground values of the worker volume.
        /// This method will return closed polygons. Also, the polygons will be filled (any holes removed).
        /// The <paramref name="foundPolygons"/> argument will be updated in place, by marking all voxels
        /// that are found to be inside of a polygon with the index of that polygon.
        /// The first new polygon that is found will be given the number supplied in <paramref name="firstNewPolygon"/>
        /// (must be 1 or higher)
        /// </summary>
        /// <param name="binaryVolume">The volume we are extracting polygons from. Must only contain values 0 and 1.</param>
        /// <param name="foundPolygons">A volume that contains the IDs for all polygons that have been found already. 0 means no polygon found.</param>
        /// <param name="searchInsidePolygon">For walking along edges, limit to the voxels that presently are assigned to
        /// the polygon given here.</param>
        /// <param name="isInnerPolygon">If true, the polygon will walk along boundaries around regions with
        /// voxel value 0 (background), but keep the polyon points on voxel values 1, counterclockwises.</param>
        /// <param name="firstNewPolygon">The ID for the first polygon that is found.</param>
        /// <returns>A collection of polygons and there respective sizes (number of foreground points in each polygon)</returns>
        private static Dictionary <ushort, PolygonPoints> ExtractPolygons(
            Volume2D <byte> binaryVolume,
            ushort[] foundPolygons,
            ushort searchInsidePolygon,
            bool isInnerPolygon,
            ushort firstNewPolygon)
        {
            if (binaryVolume == null)
            {
                throw new ArgumentNullException(nameof(binaryVolume));
            }

            if (foundPolygons == null)
            {
                throw new ArgumentNullException(nameof(foundPolygons));
            }

            if (firstNewPolygon < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(firstNewPolygon), "Polygon index 0 is reserved for 'not assigned'");
            }

            var foregroundId = isInnerPolygon ? (byte)0 : (byte)1;
            var polygons     = new Dictionary <ushort, PolygonPoints>();
            var dimX         = binaryVolume.DimX;
            var dimY         = binaryVolume.DimY;
            var volumeArray  = binaryVolume.Array;

            for (var y = 0; y < dimY; y++)
            {
                // Manually computing index, rather than relying on GetIndex, brings substantial speedup.
                var offsetY = y * dimX;
                for (var x = 0; x < dimX; x++)
                {
                    var pixelIndex = x + offsetY;

                    // Starting point of a new polygon is where we see the desired foreground in the original
                    // volume, and have either not found any polygon yet (searchInsidePolygon == 0)
                    // or have found a polygon already and now search for the holes inside it.
                    if (volumeArray[pixelIndex] == foregroundId && foundPolygons[pixelIndex] == searchInsidePolygon)
                    {
                        PointInt startPoint;
                        if (isInnerPolygon)
                        {
                            Debug.Assert(y >= 1, "When searching for innner polygons (holes), expecting that there is foreground in the row above.");
                            startPoint = new PointInt(x, y - 1);
                        }
                        else
                        {
                            startPoint = new PointInt(x, y);
                        }

                        VoxelCounts voxelCounts;
                        PointInt[]  contourPoints;
                        if (isInnerPolygon)
                        {
                            var innerPoints = FindPolygon(
                                binaryVolume,
                                foundPolygons,
                                searchInsidePolygon,
                                new PointInt(x, y),
                                backgroundId: 1,
                                searchClockwise: true);
                            voxelCounts = FillPolygon.FillPolygonAndCount(
                                innerPoints,
                                foundPolygons,
                                firstNewPolygon,
                                binaryVolume,
                                foregroundId: 0);
                            contourPoints = FindPolygon(
                                binaryVolume,
                                foundPolygons,
                                searchInsidePolygon,
                                startPoint,
                                backgroundId: 0,
                                searchClockwise: false);
                        }
                        else
                        {
                            contourPoints = FindPolygon(
                                binaryVolume,
                                foundPolygons,
                                searchInsidePolygon,
                                startPoint,
                                backgroundId: 0,
                                searchClockwise: true);
                            voxelCounts = FillPolygon.FillPolygonAndCount(
                                contourPoints,
                                foundPolygons,
                                firstNewPolygon,
                                binaryVolume,
                                foregroundId);
                        }

                        var polygon = new PolygonPoints(
                            contourPoints,
                            voxelCounts,
                            searchInsidePolygon,
                            isInside: isInnerPolygon,
                            startPointMinimumY: startPoint);
                        polygons.Add(firstNewPolygon, polygon);
                        firstNewPolygon++;
                    }
                }
            }

            return(polygons);
        }
예제 #28
0
        private static PointF[] ClockwisePointsToExternalPathWindowsPoints(
            IReadOnlyList <PointInt> points,
            bool isCounterClockwise,
            float shift = -0.5f)
        {
            if (points == null || points.Count == 0)
            {
                return(null);
            }

            var PointF = points[0];

            // Round the X/Y PointF to the containing voxel
            var currentPointX = PointF.X;
            var currentPointY = PointF.Y;

            var shiftX = false;
            var shiftY = false;

            var lastEqualsFirst      = points[0] == points[points.Count - 1] && points.Count > 1;
            var result               = new List <PointF>();
            var discardFirstSegments = 0;
            var discardLastSegments  = 0;

            if (points.Count == (lastEqualsFirst ? 2 : 1))
            {
                result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                return(result.ToArray());
            }

            if (isCounterClockwise)
            {
                // To do CCW search, pretend that there is a PointF above (N) of the
                // actual starting PointF. The CW contouring will go from that fake starting
                // PointF down (direction S) to the actual starting PointF, and then turn direction E.
                // This makes assumptions about how the search for inner contours works:
                // We start from the top-left (lowest Y, lowest X) PointF that is background.
                // By construction, there is a PointF of foreground above (at Y-1), which becomes the
                // starting PointF for traversing the inner rim CCW. Furthermore, the PointF above
                // the starting PointF will not be part of the inner rim.
                // The following configurations are possible (X = 0, Y = 0 at top-left,
                // F = fake start PointF, S = first PointF of contour, L = last PointF of contour
                // 1 F 1 1 1 1
                // ? S L ? ? ?
                // or:
                // 1 F 1 1 1 1
                // ? S ? ? ? ?
                // ? 0 L
                // In both cases, walking from F to S will generate two vertical line segments, that will
                // be discarded at the end.
                discardFirstSegments = 2;
                var fakeStart = new PointInt(points[0].X, points[0].Y - 1);
                currentPointX = fakeStart.X;
                currentPointY = fakeStart.Y;
            }

            var startPosition = isCounterClockwise ? 0 : 1;
            var endPosition   =
                isCounterClockwise
                ? points.Count
                : points.Count + (lastEqualsFirst ? 0 : 1);

            // The following code has been copied over unmodified from its original location in the
            // Microsoft.InnerEye.Models project, Contours folder.
            for (var i = startPosition; i < endPosition; i++)
            {
                PointF = points[i >= points.Count ? i - points.Count : i];

                // Round the X/Y PointF to the containing voxel
                var pointX = PointF.X;
                var pointY = PointF.Y;

                var changeX = pointX - currentPointX;
                var changeY = pointY - currentPointY;

                // South East Diagonal
                if (changeX == 1 && changeY == 1)
                {
                    if (shiftX && !shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                    }
                    else if (!shiftX & !shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                    }
                    else if (shiftY && !shiftX)
                    {
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                    }

                    shiftX = true;
                    shiftY = false;
                }

                // South West Diagonal
                else if (changeX == -1 && changeY == 1)
                {
                    if (shiftX && shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                    }
                    else if (shiftX && !shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                    }
                    else if (!shiftX && !shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                    }

                    shiftY = true;
                    shiftX = true;
                }

                // Nort West Diagonal
                else if (changeX == -1 && changeY == -1)
                {
                    if (!shiftX & shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                    }
                    else if (shiftX && shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                    }
                    else if (shiftX && !shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                    }

                    shiftX = false;
                    shiftY = true;
                }

                // North East Diagonal
                else if (changeX == 1 && changeY == -1)
                {
                    if (!shiftX && !shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                    }
                    else if (!shiftX & shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                    }
                    else if (shiftX && shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                    }

                    shiftX = false;
                    shiftY = false;
                }

                // West
                else if (changeX == 1 && changeY == 0)
                {
                    if (!shiftX && !shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                    }

                    if (!shiftX && shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                    }
                    else if (shiftX && shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                    }

                    shiftX = true;
                    shiftY = false;
                }

                // East
                else if (changeX == -1 && changeY == 0)
                {
                    if (shiftX && shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                    }

                    if (shiftX && !shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                    }
                    else if (!shiftX && !shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                    }

                    shiftX = false;
                    shiftY = true;
                }

                // South
                else if (changeX == 0 && changeY == 1)
                {
                    if (shiftX && !shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                    }

                    if (!shiftX && !shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                    }
                    else if (!shiftX && shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift));
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                    }

                    shiftX = true;
                    shiftY = true;
                }

                // North
                else if (changeX == 0 && changeY == -1)
                {
                    if (!shiftX && shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                    }

                    if (shiftX && shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                    }
                    else if (shiftX && !shiftY)
                    {
                        result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                        result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                    }

                    shiftX = false;
                    shiftY = false;
                }

                result.Add(new PointF(pointX + shift + (shiftX ? 1 : 0), pointY + shift + (shiftY ? 1 : 0)));

                currentPointX = pointX;
                currentPointY = pointY;
            }

            var distanceTolerance = 1e-2;

            if (isCounterClockwise)
            {
                // Hacks to complete counterclockwise contour plotting: In one case, we need
                // to insert an additional segment, and in some cases (not detectable by means of the
                // variables shiftX and shiftY) remove surplus segments.
                if (shiftX && shiftY)
                {
                    result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                }

                // If first and last PointF coincide, remove the last one.
                var d0 = result[discardFirstSegments].Subtract(result[result.Count - 1]).LengthSquared();
                if (Math.Abs(d0) < distanceTolerance)
                {
                    discardLastSegments = 1;
                }
            }
            else
            {
                // Make the last PointF join up to the first
                if (!shiftX && shiftY)
                {
                    result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                }

                if (shiftX && shiftY)
                {
                    result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                    result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                }
                else if (shiftX && !shiftY)
                {
                    result.Add(new PointF(currentPointX + shift + 1, currentPointY + shift + 1));
                    result.Add(new PointF(currentPointX + shift, currentPointY + shift + 1));
                    result.Add(new PointF(currentPointX + shift, currentPointY + shift));
                }
            }

            var take        = result.Count - discardLastSegments;
            var resultArray = result.Take(take).Skip(discardFirstSegments).ToArray();

            // Measure the distance from the start of the first line segment to the end.
            // This must be 1.
            var firstPoint = resultArray[0];
            var lastPoint  = resultArray[resultArray.Length - 1];
            var distance   = firstPoint.Subtract(lastPoint).LengthSquared();

            if (Math.Abs(1 - distance) > distanceTolerance)
            {
                throw new InvalidOperationException($"Unable to find a closed contour. The contour started at {firstPoint}, and ended at {lastPoint}, leaving a gap of {distance:0.000}.");
            }

            return(resultArray);
        }
예제 #29
0
        /// <summary>
        /// Connects a parent contour (outer rim of a structure) with a child contour that represents the inner rim
        /// of a structure with holes. The connection is done via a vertical line from the starting PointF of the child contour
        /// to a PointF above (smaller Y coordinate) in the parent contour.
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="childStartingPoint"></param>
        /// <returns></returns>
        public static PointF[] ConnectViaVerticalLine(PointF[] parent, PointF[] child, PointInt childStartingPoint)
        {
            if (parent == null || parent.Length == 0)
            {
                throw new ArgumentNullException(nameof(parent));
            }

            if (child == null || child.Length == 0)
            {
                throw new ArgumentNullException(nameof(child));
            }

            var parentIndex1 = FindIntersectingPoints(parent, childStartingPoint, searchForHighestY: true);
            var childIndex1  = FindIntersectingPoints(child, childStartingPoint, searchForHighestY: false);

            (int, PointF) GetIntersection(PointF[] points, int index)
            {
                var index2 = index == points.Length - 1 ? 0 : index + 1;

                return(index2, IntersectLineAtX(points[index], points[index2], childStartingPoint.X));
            }

            var(_, connectionPointParent) = GetIntersection(parent, parentIndex1);
            var(_, connectionPointChild)  = GetIntersection(child, childIndex1);
            var connectionPoints = new PointF[] { connectionPointParent, connectionPointChild };

            return(InsertChildIntoParent(parent, parentIndex1, child, childIndex1 + 1, connectionPoints));
        }
예제 #30
0
 public Line(Point start, Point end)
 {
     _start = start;
     _end = end;
 }
예제 #31
0
        /// <summary>
        /// Implementation of flood fill using scans lines as per https://simpledevcode.wordpress.com/2015/12/29/flood-fill-algorithm-using-c-net/
        /// modified with bug fixes (from comments) and region of interest.
        /// </summary>
        /// <param name="mask">The input mask.</param>
        /// <param name="dimX">The X dimension of the mask.</param>
        /// <param name="dimY">The Y dimension of the mask.</param>
        /// <param name="sliceZ">The Z dimension slice we are flood filling holes on.</param>
        /// <param name="startPoint">The start point to flood file from.</param>
        /// <param name="fillId">The fill ID.</param>
        /// <param name="targetId">The ID we are looking to fill.</param>
        private static void FloodFill(
            byte[] mask,
            int dimX,
            int dimY,
            int sliceZ,
            PointInt startPoint,
            byte fillId,
            byte targetId,
            Rectangle bounds)
        {
            var dimXY = dimX * dimY;

            if (mask[startPoint.X + startPoint.Y * dimX + sliceZ * dimXY] == fillId)
            {
                return;
            }

            var left   = bounds.X;
            var right  = bounds.X + bounds.Width;
            var top    = bounds.Y;
            var bottom = bounds.Y + bounds.Height;

            var pixels = new Stack <PointInt>();

            pixels.Push(startPoint);

            while (pixels.Count != 0)
            {
                var temp = pixels.Pop();
                var y1   = temp.Y;

                while (y1 >= top && mask[temp.X + dimX * y1 + sliceZ * dimXY] == targetId)
                {
                    y1--;
                }

                y1++;

                var spanLeft  = false;
                var spanRight = false;

                while (y1 < bottom + 1 && mask[temp.X + dimX * y1 + sliceZ * dimXY] == targetId)
                {
                    mask[temp.X + dimX * y1 + sliceZ * dimXY] = fillId;

                    if (!spanLeft && temp.X > left && mask[temp.X - 1 + dimX * y1 + sliceZ * dimXY] == targetId)
                    {
                        pixels.Push(new PointInt(temp.X - 1, y1));
                        spanLeft = true;
                    }
                    else if (spanLeft && (temp.X - 1 == left || mask[temp.X - 1 + dimX * y1 + sliceZ * dimXY] != targetId))
                    {
                        spanLeft = false;
                    }

                    if (!spanRight && temp.X < right && mask[temp.X + 1 + dimX * y1 + sliceZ * dimXY] == targetId)
                    {
                        pixels.Push(new PointInt(temp.X + 1, y1));
                        spanRight = true;
                    }
                    else if (spanRight && temp.X < right && mask[temp.X + 1 + dimX * y1 + sliceZ * dimXY] != targetId)
                    {
                        spanRight = false;
                    }

                    y1++;
                }
            }
        }