/// <summary>
        /// This creates solid colored blobs with areas proportional to the number of items contained.  When the user
        /// mouses over a blob, the caller can show examples of the items as tooltips
        /// </summary>
        public static void ShowResults2D_Blobs(Border border, SOMResult result, Func<SOMNode, Color> getNodeColor, BlobEvents events = null)
        {
            #region validate
#if DEBUG
            if (!result.Nodes.All(o => o.Position.Length == 2))
            {
                throw new ArgumentException("Node positions need to be 2D");
            }
#endif
            #endregion

            Point[] points = result.Nodes.
                Select(o => new Point(o.Position[0], o.Position[1])).
                ToArray();

            VoronoiResult2D voronoi = Math2D.GetVoronoi(points, true);
            voronoi = Math2D.CapVoronoiCircle(voronoi);

            Color[] colors = result.Nodes.
                Select(o => getNodeColor(o)).
                ToArray();

            //ISOMInput[][] inputsByNode = UtilityCore.ConvertJaggedArray<ISOMInput>(result.InputsByNode);

            Vector size = new Vector(border.ActualWidth - border.Padding.Left - border.Padding.Right, border.ActualHeight - border.Padding.Top - border.Padding.Bottom);
            Canvas canvas = DrawVoronoi_Blobs(voronoi, colors, result.Nodes, result.InputsByNode, size.X.ToInt_Floor(), size.Y.ToInt_Floor(), events);

            border.Child = canvas;
        }
Exemplo n.º 2
0
        /// <summary>
        /// This creates solid colored blobs with areas proportional to the number of items contained.  When the user
        /// mouses over a blob, the caller can show examples of the items as tooltips
        /// </summary>
        public static void ShowResults2D_Blobs(Border border, SOMResult result, Func <SOMNode, Color> getNodeColor, BlobEvents events = null)
        {
            #region validate
#if DEBUG
            if (!result.Nodes.All(o => o.Position.Size == 2))
            {
                throw new ArgumentException("Node positions need to be 2D");
            }
#endif
            #endregion

            Point[] points = result.Nodes.
                             Select(o => new Point(o.Position[0], o.Position[1])).
                             ToArray();

            VoronoiResult2D voronoi = Math2D.GetVoronoi(points, true);
            voronoi = Math2D.CapVoronoiCircle(voronoi);

            Color[] colors = result.Nodes.
                             Select(o => getNodeColor(o)).
                             ToArray();

            //ISOMInput[][] inputsByNode = UtilityCore.ConvertJaggedArray<ISOMInput>(result.InputsByNode);

            Vector size   = new Vector(border.ActualWidth - border.Padding.Left - border.Padding.Right, border.ActualHeight - border.Padding.Top - border.Padding.Bottom);
            Canvas canvas = DrawVoronoi_Blobs(voronoi, colors, result.Nodes, result.InputsByNode, size.X.ToInt_Floor(), size.Y.ToInt_Floor(), events);

            border.Child = canvas;
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        /// <summary>
        /// This divides the border up into a voronoi, then each node is tiled with examples
        /// </summary>
        public static void ShowResults2D_Tiled(Border border, SOMResult result, int tileWidth, int tileHeight, Action <DrawTileArgs> drawTile, BlobEvents events = null)
        {
            //TODO: Take a func that will render the input onto a writable bitmap, or something dynamic but efficient?
            // or take these in?
            //int tileWidth, int tileHeight



            Point[] points = result.Nodes.
                             Select(o => new Point(o.Position[0], o.Position[1])).
                             ToArray();

            Vector size = new Vector(border.ActualWidth - border.Padding.Left - border.Padding.Right, border.ActualHeight - border.Padding.Top - border.Padding.Bottom);

            VoronoiResult2D voronoi = Math2D.GetVoronoi(points, true);

            voronoi = Math2D.CapVoronoiCircle(voronoi);
            //voronoi = Math2D.CapVoronoiRectangle(voronoi, aspectRatio: 1d);       //TODO: Implement this

            Canvas canvas = DrawVoronoi_Tiled(voronoi, result.Nodes, result.InputsByNode, size.X.ToInt_Floor(), size.Y.ToInt_Floor(), tileWidth, tileHeight, drawTile, events);

            border.Child = canvas;
        }
        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 border up into a voronoi, then each node is tiled with examples
        /// </summary>
        public static void ShowResults2D_Tiled(Border border, SOMResult result, int tileWidth, int tileHeight, Action<DrawTileArgs> drawTile, BlobEvents events = null)
        {

            //TODO: Take a func that will render the input onto a writable bitmap, or something dynamic but efficient?
            // or take these in?
            //int tileWidth, int tileHeight



            Point[] points = result.Nodes.
                Select(o => new Point(o.Position[0], o.Position[1])).
                ToArray();

            Vector size = new Vector(border.ActualWidth - border.Padding.Left - border.Padding.Right, border.ActualHeight - border.Padding.Top - border.Padding.Bottom);

            VoronoiResult2D voronoi = Math2D.GetVoronoi(points, true);
            voronoi = Math2D.CapVoronoiCircle(voronoi);
            //voronoi = Math2D.CapVoronoiRectangle(voronoi, aspectRatio: 1d);       //TODO: Implement this

            Canvas canvas = DrawVoronoi_Tiled(voronoi, result.Nodes, result.InputsByNode, size.X.ToInt_Floor(), size.Y.ToInt_Floor(), tileWidth, tileHeight, drawTile, events);

            border.Child = canvas;
        }