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())); }
/// <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); } }
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)); } }
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; }
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); }
/// <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))); }
/// <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); }
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; } }
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; } } }
/// <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 }); }
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); } }
/// <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); }
// 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); } }
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); }
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); }); }); }
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(); }
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())); } }
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(); }
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); }); }
/// <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);
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()); }
/// <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); }
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); }
/// <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)); }
public Line(Point start, Point end) { _start = start; _end = end; }
/// <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++; } } }