private Color GetDotColor(ISOMInput item) { if (_getDotColor == null) { return(UtilityWPF.GetRandomColor(96, 192)); } else { return(_getDotColor(item)); } }
public DrawTileArgs(ISOMInput tile, int tileWidth, int tileHeight, byte[] bitmapPixelBytes, int imageX, int imageY, int stride, int pixelWidth) { this.Tile = tile; this.TileWidth = tileWidth; this.TileHeight = tileHeight; this.BitmapPixelBytes = bitmapPixelBytes; this.ImageX = imageX; this.ImageY = imageY; this.Stride = stride; this.PixelWidth = pixelWidth; }
private static bool IsSame(ISOMInput input1, ISOMInput input2) { if (input1 == null && input2 == null) { return(true); } else if (input1 == null || input2 == null) { return(false); } return(IsSame(input1.Weights, input2.Weights)); }
private static bool IsTooClose(ISOMInput item, IEnumerable <ISOMInput> others, double dupeDistSquared) { foreach (ISOMInput other in others) { double distSqr = (item.Weights - other.Weights).LengthSquared; if (distSqr < dupeDistSquared) { return(true); } } return(false); }
public static Tuple <SOMNode, int> GetClosest(SOMNode[] nodes, ISOMInput input) { int closestIndex = -1; double closest = double.MaxValue; SOMNode retVal = null; for (int cntr = 0; cntr < nodes.Length; cntr++) { double distSquared = (nodes[cntr].Weights - input.Weights).LengthSquared; if (distSquared < closest) { closestIndex = cntr; closest = distSquared; retVal = nodes[cntr]; } } return(Tuple.Create(retVal, closestIndex)); }
private static Canvas DrawVoronoi_Tiled(VoronoiResult2D voronoi, SOMNode[] nodes, ISOMInput[][] images, int imageWidth, int imageHeight, int tileWidth, int tileHeight, Action<DrawTileArgs> drawTile, BlobEvents events) { #region transform var aabb = Math2D.GetAABB(voronoi.EdgePoints); TransformGroup transform = new TransformGroup(); transform.Children.Add(new TranslateTransform(-aabb.Item1.X, -aabb.Item1.Y)); transform.Children.Add(new ScaleTransform(imageWidth / (aabb.Item2.X - aabb.Item1.X), imageHeight / (aabb.Item2.Y - aabb.Item1.Y))); #endregion Canvas retVal = new Canvas(); for (int cntr = 0; cntr < voronoi.ControlPoints.Length; cntr++) { #region polygon Polygon polygon = new Polygon(); if (voronoi.EdgesByControlPoint[cntr].Length < 3) { throw new ApplicationException("Expected at least three edge points"); } Edge2D[] edges = voronoi.EdgesByControlPoint[cntr].Select(o => voronoi.Edges[o]).ToArray(); Point[] edgePoints = Edge2D.GetPolygon(edges, 1d); edgePoints = edgePoints. Select(o => transform.Transform(o)). ToArray(); foreach (Point point in edgePoints) { polygon.Points.Add(point); } polygon.Fill = GetTiledSamples(edgePoints, images[cntr], nodes[cntr], tileWidth, tileHeight, drawTile); polygon.Stroke = new SolidColorBrush(UtilityWPF.GetRandomColor(64, 192)); polygon.StrokeThickness = 2; polygon.Tag = Tuple.Create(nodes[cntr], images[cntr]); if (events != null) { if (events.MouseMove != null && events.MouseLeave != null) { polygon.MouseMove += Polygon2D_MouseMove; polygon.MouseLeave += Polygon2D_MouseLeave; } if (events.Click != null) { polygon.MouseUp += Polygon_MouseUp; } } retVal.Children.Add(polygon); #endregion } return retVal; }
private static Canvas DrawVoronoi_Blobs(VoronoiResult2D voronoi, Color[] colors, SOMNode[] nodes, ISOMInput[][] inputsByNode, int imageWidth, int imageHeight, BlobEvents events) { const double MARGINPERCENT = 1.05; // Analyze size ratios double[] areas = AnalyzeVoronoiCellSizes(voronoi, inputsByNode); #region transform var aabb = Math2D.GetAABB(voronoi.EdgePoints); aabb = Tuple.Create((aabb.Item1.ToVector() * MARGINPERCENT).ToPoint(), (aabb.Item2.ToVector() * MARGINPERCENT).ToPoint()); TransformGroup transform = new TransformGroup(); transform.Children.Add(new TranslateTransform(-aabb.Item1.X, -aabb.Item1.Y)); transform.Children.Add(new ScaleTransform(imageWidth / (aabb.Item2.X - aabb.Item1.X), imageHeight / (aabb.Item2.Y - aabb.Item1.Y))); #endregion Canvas retVal = new Canvas(); retVal.Effect = new DropShadowEffect() { Color = Colors.Gray, Opacity = .2, BlurRadius = 5, Direction = 0, ShadowDepth = 0, }; for (int cntr = 0; cntr < voronoi.ControlPoints.Length; cntr++) { #region polygon Polygon polygon = new Polygon(); if (voronoi.EdgesByControlPoint[cntr].Length < 3) { throw new ApplicationException("Expected at least three edge points"); } Edge2D[] edges = voronoi.EdgesByControlPoint[cntr].Select(o => voronoi.Edges[o]).ToArray(); Point[] edgePoints = Edge2D.GetPolygon(edges, 1d); // Resize to match the desired area edgePoints = ResizeConvexPolygon(edgePoints, areas[cntr]); // Convert into a smooth blob BezierSegment3D[] bezier = BezierUtil.GetBezierSegments(edgePoints.Select(o => o.ToPoint3D()).ToArray(), .25, true); edgePoints = BezierUtil.GetPath(75, bezier). Select(o => o.ToPoint2D()). ToArray(); // Transform to canvas coords edgePoints = edgePoints. Select(o => transform.Transform(o)). ToArray(); foreach (Point point in edgePoints) { polygon.Points.Add(point); } polygon.Fill = new SolidColorBrush(colors[cntr]); polygon.Stroke = null; // new SolidColorBrush(UtilityWPF.OppositeColor(colors[cntr], false)); polygon.StrokeThickness = 1; polygon.Tag = Tuple.Create(events, nodes[cntr], inputsByNode[cntr]); if (events != null) { if (events.MouseMove != null && events.MouseLeave != null) { polygon.MouseMove += Polygon2D_MouseMove; polygon.MouseLeave += Polygon2D_MouseLeave; } if (events.Click != null) { polygon.MouseUp += Polygon_MouseUp; } } retVal.Children.Add(polygon); #endregion } return retVal; }
/// <summary> /// This divides the node's weights into thirds, and maps to RGB /// </summary> public static Color GetNodeColor(ISOMInput node) { var raw = GetNodeColor_RGB(node.Weights); return GetNodeColor_Finish(raw); }
/// <summary> /// This divides the node's weights into thirds, and maps to RGB /// </summary> public static Color GetNodeColor(ISOMInput node) { var raw = GetNodeColor_RGB(node.Weights); return(GetNodeColor_Finish(raw)); }
private static Brush GetTiledSamples_ONE(Point[] edgePoints, ISOMInput[] samples) { var aabb = Math2D.GetAABB(edgePoints); var colors = Enumerable.Range(0, 256). Select(o => UtilityWPF.GetRandomColor(64, 192)). ToArray(); //BitmapSource bitmap = UtilityWPF.GetBitmap_Aliased(colors, 16, 16, 300, 300); BitmapSource bitmap = UtilityWPF.GetBitmap_Aliased(colors, 16, 16, (aabb.Item2.X - aabb.Item1.X).ToInt_Round(), (aabb.Item2.Y - aabb.Item1.Y).ToInt_Round()); return new ImageBrush(bitmap) { Stretch = Stretch.None, }; }
private void BuildOverlay2D(SOMNode node, ISOMInput[] inputs, bool showCount = false, bool showNodeHash = false) { const double SMALLFONT1 = 17; const double LARGEFONT1 = 21; const double SMALLFONT2 = 15; const double LARGEFONT2 = 18; const double SMALLFONT3 = 12; const double LARGEFONT3 = 14; const double SMALLLINE1 = .8; const double LARGELINE1 = 1; const double SMALLLINE2 = .5; const double LARGELINE2 = .85; const double SMALLLINE3 = .3; const double LARGELINE3 = .7; Canvas canvas = new Canvas(); List<Rect> rectangles = new List<Rect>(); #region cursor rectangle var cursorRect = SelfOrganizingMapsWPF.GetMouseCursorRect(); rectangles.Add(cursorRect.Item1); // This is just for debugging //Rectangle cursorVisual = new Rectangle() //{ // Width = cursorRect.Item1.Width, // Height = cursorRect.Item1.Height, // Fill = new SolidColorBrush(UtilityWPF.GetRandomColor(64, 192, 255)), //}; //Canvas.SetLeft(cursorVisual, cursorRect.Item1.Left); //Canvas.SetTop(cursorVisual, cursorRect.Item1.Top); //canvas.Children.Add(cursorVisual); #endregion #region count text if (showCount && _result != null && _result.InputsByNode != null) // it's possible that they are changing things while old graphics are still showing { StackPanel textPanel = new StackPanel() { Orientation = Orientation.Horizontal, }; // "rows " OutlinedTextBlock text = SelfOrganizingMapsWPF.GetOutlineText("rows ", SMALLFONT1, SMALLLINE1); text.Margin = new Thickness(0, 0, 4, 0); textPanel.Children.Add(text); // percent double percent = -1; if (_result.InputsByNode.Length == 0) { if (inputs.Length == 0) { percent = 0; } else { percent = -1; } } else { percent = inputs.Length.ToDouble() / _result.InputsByNode.SelectMany(o => o).Count().ToDouble(); percent *= 100d; } text = SelfOrganizingMapsWPF.GetOutlineText(percent.ToStringSignificantDigits(2) + "%", LARGEFONT1, LARGELINE1); textPanel.Children.Add(text); // Place on canvas textPanel.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); // aparently, the infinity is important to get an accurate desired size Size textSize = textPanel.DesiredSize; Rect textRect = SelfOrganizingMapsWPF.GetFreeSpot(textSize, new Point(0, 0), new Vector(0, -1), rectangles); rectangles.Add(textRect); Canvas.SetLeft(textPanel, textRect.Left); Canvas.SetTop(textPanel, textRect.Top); canvas.Children.Add(textPanel); } #endregion double[] nodeCenter = inputs.Length == 0 ? node.Weights : MathND.GetCenter(inputs.Select(o => o.Weights)); #region node hash if (showNodeHash) { var nodeCtrl = GetVectorVisual(node.Weights); // Place on canvas Rect nodeRect = SelfOrganizingMapsWPF.GetFreeSpot(new Size(nodeCtrl.Item2.X, nodeCtrl.Item2.Y), new Point(0, 0), new Vector(0, -1), rectangles); rectangles.Add(nodeRect); Canvas.SetLeft(nodeCtrl.Item1, nodeRect.Left); Canvas.SetTop(nodeCtrl.Item1, nodeRect.Top); canvas.Children.Add(nodeCtrl.Item1); } #endregion //TODO: For the first attempt, put all row descriptions under #region rows if (_queryResults != null && _queryResults.Results != null) { var rowsCtrl = GetRowsVisual(_queryResults.ColumnNames, inputs, _detailsHeaderStyle, _detailsBodyStyle); // Place on canvas Rect rowsRect = SelfOrganizingMapsWPF.GetFreeSpot(new Size(rowsCtrl.Item2.X, rowsCtrl.Item2.Y), new Point(0, 0), new Vector(0, 1), rectangles); rectangles.Add(rowsRect); Canvas.SetLeft(rowsCtrl.Item1, rowsRect.Left); Canvas.SetTop(rowsCtrl.Item1, rowsRect.Top); canvas.Children.Add(rowsCtrl.Item1); } #endregion Rect canvasAABB = Math2D.GetAABB(rectangles); //NOTE: All the items are placed around zero zero, but that may not be half width and height (items may not be centered) canvas.RenderTransform = new TranslateTransform(-canvasAABB.Left, -canvasAABB.Top); panelOverlay.Children.Clear(); panelOverlay.Children.Add(canvas); _overlayPolyStats = new OverlayPolygonStats(node, inputs, canvasAABB, cursorRect.Item2, canvas); }
private void Polygon_Click(Polygon sender, SOMNode node, ISOMInput[] images, MouseEventArgs e) { try { Color nodeColor = UtilityWPF.ExtractColor(sender.Fill); RadialGradientBrush brush = new RadialGradientBrush(); brush.GradientStops.Add(new GradientStop(UtilityWPF.AlphaBlend(Colors.White, nodeColor, .8), 0)); brush.GradientStops.Add(new GradientStop(UtilityWPF.AlphaBlend(Colors.White, nodeColor, .58), 1.9)); HighDimensionVisualizer visualizer = new HighDimensionVisualizer(GetPreviewImage, SelfOrganizingMapsWPF.GetNodeColor, chkVisualizerStaticDots.IsChecked.Value, chkVisualizer3D.IsChecked.Value); visualizer.AddStaticItems(HighDimensionVisualizer.GetSOMNodeStaticPositions(node, _nodes, HighDimensionVisualizer.RADIUS)); visualizer.AddItems(images); Window window = new Window() { Width = 400, Height = 400, Title = this.Title + " " + images.Length.ToString(), Background = brush, ResizeMode = ResizeMode.CanResizeWithGrip, Content = visualizer, Owner = this, // keep it on top of this window }; window.Show(); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary> /// This is used by child HighDimensionVisualizer windows /// </summary> private Tuple<UIElement, VectorInt> GetPreviewImage(ISOMInput input) { bool showHash = chkVisualizerShowHash.IsChecked.Value; ImageInput nodeImage = input as ImageInput; if (nodeImage == null) { // This is probably a node, instead of an input image (the nodes are sent as static control points) nodeImage = new ImageInput(null, input.Weights, input.Weights); showHash = true; } return GetPreviewImage(nodeImage, showHash, 80, false, -1); }
private void BuildOverlay2D(SOMNode node, ISOMInput[] images, bool showCount, bool showNodeHash, bool showImageHash, bool showSpread, bool showPerImageDistance) { const int IMAGESIZE = 80; const int NODEHASHSIZE = 100; const double SMALLFONT1 = 17; const double LARGEFONT1 = 21; const double SMALLFONT2 = 15; const double LARGEFONT2 = 18; const double SMALLFONT3 = 12; const double LARGEFONT3 = 14; const double SMALLLINE1 = .8; const double LARGELINE1 = 1; const double SMALLLINE2 = .5; const double LARGELINE2 = .85; const double SMALLLINE3 = .3; const double LARGELINE3 = .7; Canvas canvas = new Canvas(); List<Rect> rectangles = new List<Rect>(); #region cursor rectangle var cursorRect = SelfOrganizingMapsWPF.GetMouseCursorRect(0); rectangles.Add(cursorRect.Item1); // This is just for debugging //Rectangle cursorVisual = new Rectangle() //{ // Width = cursorRect.Item1.Width, // Height = cursorRect.Item1.Height, // Fill = new SolidColorBrush(UtilityWPF.GetRandomColor(64, 192, 255)), //}; //Canvas.SetLeft(cursorVisual, cursorRect.Item1.Left); //Canvas.SetTop(cursorVisual, cursorRect.Item1.Top); //canvas.Children.Add(cursorVisual); #endregion #region count text if (showCount) { StackPanel textPanel = new StackPanel() { Orientation = Orientation.Horizontal, }; // "images " OutlinedTextBlock text = SelfOrganizingMapsWPF.GetOutlineText("images ", SMALLFONT1, SMALLLINE1); text.Margin = new Thickness(0, 0, 4, 0); textPanel.Children.Add(text); // count text = SelfOrganizingMapsWPF.GetOutlineText(images.Length.ToString("N0"), LARGEFONT1, LARGELINE1); textPanel.Children.Add(text); // Place on canvas textPanel.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); // aparently, the infinity is important to get an accurate desired size Size textSize = textPanel.DesiredSize; Rect textRect = SelfOrganizingMapsWPF.GetFreeSpot(textSize, new Point(0, 0), new Vector(0, 1), rectangles); rectangles.Add(textRect); Canvas.SetLeft(textPanel, textRect.Left); Canvas.SetTop(textPanel, textRect.Top); canvas.Children.Add(textPanel); } #endregion #region spread var nodeImages = images.Select(o => o.Weights); var allImages = _imagesByNode.SelectMany(o => o).Select(o => o.Weights); double nodeSpread = images.Length == 0 ? 0d : SelfOrganizingMaps.GetTotalSpread(nodeImages); double totalSpread = SelfOrganizingMaps.GetTotalSpread(allImages); if (showSpread && images.Length > 0) { double nodeStandDev = MathND.GetStandardDeviation(nodeImages); double totalStandDev = MathND.GetStandardDeviation(allImages); double percentSpread = nodeSpread / totalSpread; double pecentStandDev = nodeStandDev / totalSpread; Grid spreadPanel = new Grid() { Margin = new Thickness(2), }; spreadPanel.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) }); spreadPanel.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(4) }); spreadPanel.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) }); spreadPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); spreadPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(2) }); spreadPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); spreadPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(2) }); spreadPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); spreadPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(2) }); spreadPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); spreadPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(2) }); spreadPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); spreadPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(2) }); spreadPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); AddTextRow(spreadPanel, 0, "node stand dev", (pecentStandDev * 100).ToStringSignificantDigits(2) + "%", SMALLFONT2, LARGEFONT2, SMALLLINE2, LARGELINE2, true); AddTextRow(spreadPanel, 2, "node spread", (percentSpread * 100).ToStringSignificantDigits(2) + "%", SMALLFONT2, LARGEFONT2, SMALLLINE2, LARGELINE2, false); AddTextRow(spreadPanel, 4, "node stand dev", nodeStandDev.ToStringSignificantDigits(2), SMALLFONT3, LARGEFONT3, SMALLLINE3, LARGELINE3, true); AddTextRow(spreadPanel, 6, "node spread", nodeSpread.ToStringSignificantDigits(2), SMALLFONT3, LARGEFONT3, SMALLLINE3, LARGELINE3, false); AddTextRow(spreadPanel, 8, "total stand dev", totalStandDev.ToStringSignificantDigits(2), SMALLFONT3, LARGEFONT3, SMALLLINE3, LARGELINE3, true); AddTextRow(spreadPanel, 10, "total spread", totalSpread.ToStringSignificantDigits(2), SMALLFONT3, LARGEFONT3, SMALLLINE3, LARGELINE3, false); // Place on canvas spreadPanel.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); // aparently, the infinity is important to get an accurate desired size Size spreadSize = spreadPanel.DesiredSize; Rect spreadRect = SelfOrganizingMapsWPF.GetFreeSpot(spreadSize, new Point(0, 0), new Vector(0, 1), rectangles); rectangles.Add(spreadRect); Canvas.SetLeft(spreadPanel, spreadRect.Left); Canvas.SetTop(spreadPanel, spreadRect.Top); canvas.Children.Add(spreadPanel); } #endregion double[] nodeCenter = images.Length == 0 ? node.Weights : MathND.GetCenter(nodeImages); #region node hash if (showNodeHash) { ImageInput nodeImage = new ImageInput(null, node.Weights, node.Weights); double nodeDist = MathND.GetDistance(nodeImage.Weights, nodeCenter); double nodeDistPercent = nodeSpread.IsNearZero() ? 1d : (nodeDist / nodeSpread); // if zero or one node, then spread will be zero Tuple<UIElement, VectorInt> nodeCtrl = GetPreviewImage(nodeImage, true, NODEHASHSIZE, showPerImageDistance, nodeDistPercent); // Place on canvas Rect nodeRect = SelfOrganizingMapsWPF.GetFreeSpot(new Size(nodeCtrl.Item2.X, nodeCtrl.Item2.Y), new Point(0, 0), new Vector(0, -1), rectangles); rectangles.Add(nodeRect); Canvas.SetLeft(nodeCtrl.Item1, nodeRect.Left); Canvas.SetTop(nodeCtrl.Item1, nodeRect.Top); canvas.Children.Add(nodeCtrl.Item1); } #endregion #region images foreach (ImageInput image in images) { double imageDistPercent; if (images.Length == 1) { imageDistPercent = 1; } else { imageDistPercent = MathND.GetDistance(image.Weights, nodeCenter) / nodeSpread; } // Create the image (and any other graphics for that image) Tuple<UIElement, VectorInt> imageCtrl = GetPreviewImage(image, showImageHash, IMAGESIZE, showPerImageDistance, imageDistPercent); // Find a spot for it var imageRect = Enumerable.Range(0, 10). Select(o => { Vector direction = Math3D.GetRandomVector_Circular_Shell(1).ToVector2D(); Rect imageRect2 = SelfOrganizingMapsWPF.GetFreeSpot(new Size(imageCtrl.Item2.X, imageCtrl.Item2.Y), new Point(0, 0), direction, rectangles); return new { Rect = imageRect2, Distance = new Vector(imageRect2.CenterX(), imageRect2.CenterY()).LengthSquared }; }). OrderBy(o => o.Distance). First(). Rect; Canvas.SetLeft(imageCtrl.Item1, imageRect.Left); Canvas.SetTop(imageCtrl.Item1, imageRect.Top); // Add it rectangles.Add(imageRect); canvas.Children.Add(imageCtrl.Item1); } #endregion Rect canvasAABB = Math2D.GetAABB(rectangles); //NOTE: All the items are placed around zero zero, but that may not be half width and height (items may not be centered) canvas.RenderTransform = new TranslateTransform(-canvasAABB.Left, -canvasAABB.Top); panelOverlay.Children.Clear(); panelOverlay.Children.Add(canvas); _overlayPolyStats = new OverlayPolygonStats(node, images, canvasAABB, cursorRect.Item2, canvas); }
private static double[] AnalyzeVoronoiCellSizes(VoronoiResult2D voronoi, ISOMInput[][] imagesByNode) { // Calculate area, density of each node var sizes = Enumerable.Range(0, voronoi.ControlPoints.Length). Select(o => { double area = Math2D.GetAreaPolygon(voronoi.GetPolygon(o, 1)); // there are no rays double imageCount = imagesByNode[o].Length.ToDouble(); return new { ImagesCount = imageCount, Area = area, Density = imageCount / area, }; }). ToArray(); // Don't let any node have an area smaller than this double minArea = sizes.Min(o => o.Area) * .2; // Find the node with the largest density. This is the density to use when drawing all cells var largestDensity = sizes. OrderByDescending(o => o.Density). First(); return sizes.Select(o => { // Figure out how much area it would take using the highest density double area = o.ImagesCount / largestDensity.Density; if (area < minArea) { area = minArea; } return area; }). ToArray(); }
private static Tuple<UIElement, VectorInt> GetRowsVisual(string[] columnNames, ISOMInput[] inputs, Style headerStyle, Style bodyStyle) { Grid grid = new Grid(); #region Header grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); // Header for (int cntr = 0; cntr < columnNames.Length; cntr++) { grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) }); TextBlock text = new TextBlock() { Text = columnNames[cntr], Style = headerStyle, }; Grid.SetColumn(text, cntr); Grid.SetRow(text, grid.RowDefinitions.Count - 1); grid.Children.Add(text); } #endregion //TODO: Sort by distance. Call this with 1D coords //SelfOrganizingMaps.ArrangeNodes_LikesAttract() foreach (RowInput input in UtilityCore.RandomOrder(inputs, 300)) // Mix it up. Also getting exceptions if too much is added, and it won't all be shown anyway { #region Body Row grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) }); // Header for (int cntr = 0; cntr < columnNames.Length; cntr++) { grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) }); TextBlock text = new TextBlock() { Text = input.Row[cntr], Style = bodyStyle, HorizontalAlignment = HorizontalAlignment.Right, }; Grid.SetColumn(text, cntr); Grid.SetRow(text, grid.RowDefinitions.Count - 1); grid.Children.Add(text); } #endregion } Border retVal = new Border() { Child = grid, Background = new SolidColorBrush(UtilityWPF.ColorFromHex("D0F7F1DA")), BorderBrush = new SolidColorBrush(UtilityWPF.ColorFromHex("B8B4A0")), BorderThickness = new Thickness(1), CornerRadius = new CornerRadius(3), Padding = new Thickness(8), }; retVal.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); // aparently, the infinity is important to get an accurate desired size Size returnSize = retVal.DesiredSize; return Tuple.Create((UIElement)retVal, new VectorInt(returnSize.Width.ToInt_Ceiling(), returnSize.Height.ToInt_Ceiling())); }
private static Brush GetTiledSamples(Point[] edgePoints, ISOMInput[] samples, SOMNode node, int tileWidth, int tileHeight, Action<DrawTileArgs> drawTile) { var dimensions = GetTileImagePositions(samples.Length); // The image tiles will be drawn spiraling out from the center. Order the list so that tiles closest to the node are first (so that // they are drawn closer to the center of the spiral) ISOMInput[] orderedSamples = samples. OrderBy(o => MathND.GetDistanceSquared(o.Weights, node.Weights)). ToArray(); //int tilehalf_left = tileWidth / 2; //int tilehalf_top = tileHeight / 2; //int tilehalf_right = tileWidth - tilehalf_left; //int tilehalf_bot = tileHeight - tilehalf_top; int imageWidth = (dimensions.Item2.X - dimensions.Item1.X + 1) * tileWidth; int imageHeight = (dimensions.Item2.Y - dimensions.Item1.Y + 1) * tileHeight; //int offsetX = (Math.Abs(dimensions.Item1.X) * tileWidth) + tilehalf_left; //int offsetY = (Math.Abs(dimensions.Item1.Y) * tileHeight) + tilehalf_top; //TODO: Get the AABB of edgePoints. If the bitmap will be bigger than the aabb, then draw just enough to totally fill the polygon //NOTE: Copied from UtilityWPF.GetBitmap WriteableBitmap bitmap = new WriteableBitmap(imageWidth, imageHeight, UtilityWPF.DPI, UtilityWPF.DPI, PixelFormats.Pbgra32, null); // may want Bgra32 if performance is an issue int pixelWidth = bitmap.Format.BitsPerPixel / 8; int stride = bitmap.PixelWidth * pixelWidth; // this is the length of one row of pixels byte[] pixels = new byte[bitmap.PixelHeight * stride]; DrawingVisual dv = new DrawingVisual(); using (DrawingContext ctx = dv.RenderOpen()) { for (int cntr = 0; cntr < orderedSamples.Length; cntr++) { int x = (dimensions.Item3[cntr].X - dimensions.Item1.X) * tileWidth; int y = (dimensions.Item3[cntr].Y - dimensions.Item1.Y) * tileWidth; DrawTileArgs args = new DrawTileArgs(orderedSamples[cntr], tileWidth, tileHeight, pixels, x, y, stride, pixelWidth); drawTile(args); } #region DISCARD //int index = 0; //for (int y = 0; y < colorsHeight; y++) //{ // for (int x = 0; x < colorsWidth; x++) // { // int gray = (grayColors[index] * grayValueScale).ToInt_Round(); // if (gray < 0) gray = 0; // if (gray > 255) gray = 255; // byte grayByte = Convert.ToByte(gray); // Color color = Color.FromRgb(grayByte, grayByte, grayByte); // ctx.DrawRectangle(new SolidColorBrush(color), null, new Rect(x * scaleX, y * scaleY, scaleX, scaleY)); // index++; // } //} #endregion } bitmap.WritePixels(new Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight), pixels, stride, 0); return new ImageBrush(bitmap) { Stretch = Stretch.None, }; }
public OverlayPolygonStats(SOMNode node, ISOMInput[] images, Rect canvasAABB, Vector cursorOffset, Canvas overlay) { this.Node = node; this.Images = images; this.CanvasAABB = canvasAABB; this.CursorOffset = cursorOffset; this.Overlay = overlay; }
private Color GetDotColor(ISOMInput item) { if (_getDotColor == null) { return UtilityWPF.GetRandomColor(96, 192); } else { return _getDotColor(item); } }
private void Polygon_MouseMove(Polygon poly, SOMNode node, ISOMInput[] inputs, MouseEventArgs e) { try { if (_overlayPolyStats == null || _overlayPolyStats.Node.Token != node.Token) { BuildOverlay2D(node, inputs, true, true); } Point mousePos = e.GetPosition(panelDisplay); double left = mousePos.X + _overlayPolyStats.CanvasAABB.Left + _overlayPolyStats.CursorOffset.X - 1; //double top = mousePos.Y + _overlayPolyStats.CanvasAABB.Top + _overlayPolyStats.CursorOffset.Y - 1; //double top = mousePos.Y + _overlayPolyStats.CanvasAABB.Top - _overlayPolyStats.CursorOffset.Y - 1; double top = mousePos.Y + _overlayPolyStats.CanvasAABB.Top - 1; // Y is already centered Canvas.SetLeft(_overlayPolyStats.Overlay, left); Canvas.SetTop(_overlayPolyStats.Overlay, top); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void Polygon_Click(Polygon poly, SOMNode node, ISOMInput[] inputs, MouseEventArgs e) { try { int index = _result.Nodes.IndexOf(node, (o, p) => o.Token == p.Token); DBRowsDetail viewer = new DBRowsDetail(_queryResults, _columns, _result, index) { Background = poly.Fill, }; viewer.Closed += DBRowsDetail_Closed; _childWindows.Add(viewer); viewer.Show(); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private static bool IsTooClose(ISOMInput item, IEnumerable<ISOMInput> others, double dupeDistSquared) { foreach (ISOMInput other in others) { double distSqr = MathND.GetDistanceSquared(item.Weights, other.Weights); if (distSqr < dupeDistSquared) { return true; } } return false; }