Example #1
0
        void Render()
        {
            CanvasFill.Children.Clear();
            CanvasLines.Children.Clear();

            if (GridSize.Elements() < 1 || this.ActualWidth == 0)
            {
                return;
            }

            float  StepLength = (float)(this.ActualWidth / (GridSize.X + GridSize.Y)) / (float)Math.Sqrt(1f - 1f / AxisRatio / AxisRatio);
            float2 StepZ      = new float2(0, -StepLength);
            float2 StepY      = new float2(-(float)Math.Sqrt(1f - 1f / AxisRatio / AxisRatio) * StepLength, StepLength / AxisRatio);
            float2 StepX      = new float2((float)Math.Sqrt(1f - 1f / AxisRatio / AxisRatio) * StepLength, StepLength / AxisRatio);

            double DesiredHeight = GridSize.X * Math.Abs(StepX.Y) + GridSize.Y * Math.Abs(StepY.Y) + GridSize.Z * Math.Abs(StepZ.Y);

            if (DesiredHeight != this.Height)
            {
                this.Height = DesiredHeight;
                return;
            }

            float2 Origin = new float2(GridSize.X * StepX.X, -GridSize.Z * StepZ.Y);

            Func <int, int, int, bool> CubeExists     = (x, y, z) => (z * GridSize.Y + y) * GridSize.X + x < Value && x < GridSize.X && y < GridSize.Y && z < GridSize.Z && x >= 0 && y >= 0 && z >= 0;
            SolidColorBrush            LineBrush      = new SolidColorBrush(Colors.Black);
            SolidColorBrush            BoundsBrush    = new SolidColorBrush(Color.FromArgb(40, 0, 0, 0));
            SolidColorBrush            FaceLeftBrush  = new SolidColorBrush(Color.FromArgb(60, Colors.CornflowerBlue.R, Colors.CornflowerBlue.G, Colors.CornflowerBlue.B));
            SolidColorBrush            FaceRightBrush = new SolidColorBrush(Color.FromArgb(120, Colors.CornflowerBlue.R, Colors.CornflowerBlue.G, Colors.CornflowerBlue.B));
            SolidColorBrush            FaceTopBrush   = new SolidColorBrush(Color.FromArgb(30, Colors.CornflowerBlue.R, Colors.CornflowerBlue.G, Colors.CornflowerBlue.B));

            for (int z = 0; z < GridSize.Z; z++)
            {
                for (int y = 0; y < GridSize.Y; y++)
                {
                    for (int x = 0; x < GridSize.X; x++)
                    {
                        if (!CubeExists(x, y, z))
                        {
                            break;
                        }

                        #region Vertical Edges

                        // Left edge
                        if (!CubeExists(x - 1, y, z) && !CubeExists(x - 1, y + 1, z) && !CubeExists(x, y + 1, z))
                        {
                            Line EdgeLine = new Line()
                            {
                                X1 = Origin.X + (x + 0) * StepX.X + (y + 1) * StepY.X + (z + 0) * StepZ.X,
                                Y1 = Origin.Y + (x + 0) * StepX.Y + (y + 1) * StepY.Y + (z + 0) * StepZ.Y,

                                X2 = Origin.X + (x + 0) * StepX.X + (y + 1) * StepY.X + (z + 1) * StepZ.X,
                                Y2 = Origin.Y + (x + 0) * StepX.Y + (y + 1) * StepY.Y + (z + 1) * StepZ.Y,

                                StrokeThickness = 1,
                                Stroke          = LineBrush
                            };
                            CanvasLines.Children.Add(EdgeLine);
                        }

                        // Front edge
                        if ((!CubeExists(x + 1, y, z) && !CubeExists(x + 1, y + 1, z) && !CubeExists(x, y + 1, z)) || (CubeExists(x + 1, y, z) && !CubeExists(x + 1, y + 1, z) && CubeExists(x, y + 1, z)))
                        {
                            Line EdgeLine = new Line()
                            {
                                X1 = Origin.X + (x + 1) * StepX.X + (y + 1) * StepY.X + (z + 0) * StepZ.X,
                                Y1 = Origin.Y + (x + 1) * StepX.Y + (y + 1) * StepY.Y + (z + 0) * StepZ.Y,

                                X2 = Origin.X + (x + 1) * StepX.X + (y + 1) * StepY.X + (z + 1) * StepZ.X,
                                Y2 = Origin.Y + (x + 1) * StepX.Y + (y + 1) * StepY.Y + (z + 1) * StepZ.Y,

                                StrokeThickness = 1,
                                Stroke          = LineBrush
                            };
                            CanvasLines.Children.Add(EdgeLine);
                        }

                        // Right edge
                        if (!CubeExists(x + 1, y, z) && !CubeExists(x + 1, y - 1, z) && !CubeExists(x, y - 1, z))
                        {
                            Line EdgeLine = new Line()
                            {
                                X1 = Origin.X + (x + 1) * StepX.X + (y + 0) * StepY.X + (z + 0) * StepZ.X,
                                Y1 = Origin.Y + (x + 1) * StepX.Y + (y + 0) * StepY.Y + (z + 0) * StepZ.Y,

                                X2 = Origin.X + (x + 1) * StepX.X + (y + 0) * StepY.X + (z + 1) * StepZ.X,
                                Y2 = Origin.Y + (x + 1) * StepX.Y + (y + 0) * StepY.Y + (z + 1) * StepZ.Y,

                                StrokeThickness = 1,
                                Stroke          = LineBrush
                            };
                            CanvasLines.Children.Add(EdgeLine);
                        }

                        #endregion

                        #region Horizontal edges

                        #region Bottom edges

                        // Left edge
                        if ((!CubeExists(x, y + 1, z) && !CubeExists(x, y + 1, z - 1) && !CubeExists(x, y, z - 1)) || (!CubeExists(x, y + 1, z) && CubeExists(x, y + 1, z - 1)))
                        {
                            Line EdgeLine = new Line()
                            {
                                X1 = Origin.X + (x + 0) * StepX.X + (y + 1) * StepY.X + (z + 0) * StepZ.X,
                                Y1 = Origin.Y + (x + 0) * StepX.Y + (y + 1) * StepY.Y + (z + 0) * StepZ.Y,

                                X2 = Origin.X + (x + 1) * StepX.X + (y + 1) * StepY.X + (z + 0) * StepZ.X,
                                Y2 = Origin.Y + (x + 1) * StepX.Y + (y + 1) * StepY.Y + (z + 0) * StepZ.Y,

                                StrokeThickness = 1,
                                Stroke          = LineBrush
                            };
                            CanvasLines.Children.Add(EdgeLine);
                        }

                        // Right edge
                        if ((!CubeExists(x + 1, y, z) && !CubeExists(x + 1, y, z - 1) && !CubeExists(x, y, z - 1)) || (!CubeExists(x + 1, y, z) && CubeExists(x + 1, y, z - 1)))
                        {
                            Line EdgeLine = new Line()
                            {
                                X1 = Origin.X + (x + 1) * StepX.X + (y + 0) * StepY.X + (z + 0) * StepZ.X,
                                Y1 = Origin.Y + (x + 1) * StepX.Y + (y + 0) * StepY.Y + (z + 0) * StepZ.Y,

                                X2 = Origin.X + (x + 1) * StepX.X + (y + 1) * StepY.X + (z + 0) * StepZ.X,
                                Y2 = Origin.Y + (x + 1) * StepX.Y + (y + 1) * StepY.Y + (z + 0) * StepZ.Y,

                                StrokeThickness = 1,
                                Stroke          = LineBrush
                            };
                            CanvasLines.Children.Add(EdgeLine);
                        }

                        #endregion

                        #region Middle edges

                        // Left edge
                        if (!CubeExists(x, y + 1, z) && !CubeExists(x, y + 1, z + 1) && !CubeExists(x, y, z + 1))
                        {
                            Line EdgeLine = new Line()
                            {
                                X1 = Origin.X + (x + 0) * StepX.X + (y + 1) * StepY.X + (z + 1) * StepZ.X,
                                Y1 = Origin.Y + (x + 0) * StepX.Y + (y + 1) * StepY.Y + (z + 1) * StepZ.Y,

                                X2 = Origin.X + (x + 1) * StepX.X + (y + 1) * StepY.X + (z + 1) * StepZ.X,
                                Y2 = Origin.Y + (x + 1) * StepX.Y + (y + 1) * StepY.Y + (z + 1) * StepZ.Y,

                                StrokeThickness = 1,
                                Stroke          = LineBrush
                            };
                            CanvasLines.Children.Add(EdgeLine);
                        }

                        // Right edge
                        if (!CubeExists(x + 1, y, z) && !CubeExists(x + 1, y, z + 1) && !CubeExists(x, y, z + 1))
                        {
                            Line EdgeLine = new Line()
                            {
                                X1 = Origin.X + (x + 1) * StepX.X + (y + 0) * StepY.X + (z + 1) * StepZ.X,
                                Y1 = Origin.Y + (x + 1) * StepX.Y + (y + 0) * StepY.Y + (z + 1) * StepZ.Y,

                                X2 = Origin.X + (x + 1) * StepX.X + (y + 1) * StepY.X + (z + 1) * StepZ.X,
                                Y2 = Origin.Y + (x + 1) * StepX.Y + (y + 1) * StepY.Y + (z + 1) * StepZ.Y,

                                StrokeThickness = 1,
                                Stroke          = LineBrush
                            };
                            CanvasLines.Children.Add(EdgeLine);
                        }

                        #endregion

                        #region Top edges

                        // Left edge
                        if (!CubeExists(x - 1, y, z) && !CubeExists(x - 1, y, z + 1) && !CubeExists(x, y, z + 1))
                        {
                            Line EdgeLine = new Line()
                            {
                                X1 = Origin.X + (x + 0) * StepX.X + (y + 0) * StepY.X + (z + 1) * StepZ.X,
                                Y1 = Origin.Y + (x + 0) * StepX.Y + (y + 0) * StepY.Y + (z + 1) * StepZ.Y,

                                X2 = Origin.X + (x + 0) * StepX.X + (y + 1) * StepY.X + (z + 1) * StepZ.X,
                                Y2 = Origin.Y + (x + 0) * StepX.Y + (y + 1) * StepY.Y + (z + 1) * StepZ.Y,

                                StrokeThickness = 1,
                                Stroke          = LineBrush
                            };
                            CanvasLines.Children.Add(EdgeLine);
                        }

                        // Right edge
                        if (!CubeExists(x, y - 1, z) && !CubeExists(x, y - 1, z + 1) && !CubeExists(x, y, z + 1))
                        {
                            Line EdgeLine = new Line()
                            {
                                X1 = Origin.X + (x + 0) * StepX.X + (y + 0) * StepY.X + (z + 1) * StepZ.X,
                                Y1 = Origin.Y + (x + 0) * StepX.Y + (y + 0) * StepY.Y + (z + 1) * StepZ.Y,

                                X2 = Origin.X + (x + 1) * StepX.X + (y + 0) * StepY.X + (z + 1) * StepZ.X,
                                Y2 = Origin.Y + (x + 1) * StepX.Y + (y + 0) * StepY.Y + (z + 1) * StepZ.Y,

                                StrokeThickness = 1,
                                Stroke          = LineBrush
                            };
                            CanvasLines.Children.Add(EdgeLine);
                        }

                        #endregion

                        #endregion

                        #region Faces

                        // Left
                        if (!CubeExists(x, y + 1, z))
                        {
                            Polygon Poly = new Polygon()
                            {
                                Points = new PointCollection()
                                {
                                    new Point(Origin.X + (x + 0) * StepX.X + (y + 1) * StepY.X + (z + 0) * StepZ.X,
                                              Origin.Y + (x + 0) * StepX.Y + (y + 1) * StepY.Y + (z + 0) * StepZ.Y),
                                    new Point(Origin.X + (x + 1) * StepX.X + (y + 1) * StepY.X + (z + 0) * StepZ.X,
                                              Origin.Y + (x + 1) * StepX.Y + (y + 1) * StepY.Y + (z + 0) * StepZ.Y),
                                    new Point(Origin.X + (x + 1) * StepX.X + (y + 1) * StepY.X + (z + 1) * StepZ.X,
                                              Origin.Y + (x + 1) * StepX.Y + (y + 1) * StepY.Y + (z + 1) * StepZ.Y),
                                    new Point(Origin.X + (x + 0) * StepX.X + (y + 1) * StepY.X + (z + 1) * StepZ.X,
                                              Origin.Y + (x + 0) * StepX.Y + (y + 1) * StepY.Y + (z + 1) * StepZ.Y)
                                },
                                Fill = new SolidColorBrush(Color.FromArgb(60,
                                                                          (byte)((x + 1) / (float)GridSize.X * 255),
                                                                          (byte)((y + 1) / (float)GridSize.Y * 255),
                                                                          (byte)((z + 1) / (float)GridSize.Z * 255)))
                            };
                            CanvasFill.Children.Add(Poly);
                        }

                        // Right
                        if (!CubeExists(x + 1, y, z))
                        {
                            Polygon Poly = new Polygon()
                            {
                                Points = new PointCollection()
                                {
                                    new Point(Origin.X + (x + 1) * StepX.X + (y + 1) * StepY.X + (z + 0) * StepZ.X,
                                              Origin.Y + (x + 1) * StepX.Y + (y + 1) * StepY.Y + (z + 0) * StepZ.Y),
                                    new Point(Origin.X + (x + 1) * StepX.X + (y + 0) * StepY.X + (z + 0) * StepZ.X,
                                              Origin.Y + (x + 1) * StepX.Y + (y + 0) * StepY.Y + (z + 0) * StepZ.Y),
                                    new Point(Origin.X + (x + 1) * StepX.X + (y + 0) * StepY.X + (z + 1) * StepZ.X,
                                              Origin.Y + (x + 1) * StepX.Y + (y + 0) * StepY.Y + (z + 1) * StepZ.Y),
                                    new Point(Origin.X + (x + 1) * StepX.X + (y + 1) * StepY.X + (z + 1) * StepZ.X,
                                              Origin.Y + (x + 1) * StepX.Y + (y + 1) * StepY.Y + (z + 1) * StepZ.Y)
                                },
                                Fill = new SolidColorBrush(Color.FromArgb(120,
                                                                          (byte)((x + 1) / (float)GridSize.X * 255),
                                                                          (byte)((y + 1) / (float)GridSize.Y * 255),
                                                                          (byte)((z + 1) / (float)GridSize.Z * 255)))
                            };
                            CanvasFill.Children.Add(Poly);
                        }

                        // Top
                        if (!CubeExists(x, y, z + 1))
                        {
                            Polygon Poly = new Polygon()
                            {
                                Points = new PointCollection()
                                {
                                    new Point(Origin.X + (x + 0) * StepX.X + (y + 0) * StepY.X + (z + 1) * StepZ.X,
                                              Origin.Y + (x + 0) * StepX.Y + (y + 0) * StepY.Y + (z + 1) * StepZ.Y),
                                    new Point(Origin.X + (x + 1) * StepX.X + (y + 0) * StepY.X + (z + 1) * StepZ.X,
                                              Origin.Y + (x + 1) * StepX.Y + (y + 0) * StepY.Y + (z + 1) * StepZ.Y),
                                    new Point(Origin.X + (x + 1) * StepX.X + (y + 1) * StepY.X + (z + 1) * StepZ.X,
                                              Origin.Y + (x + 1) * StepX.Y + (y + 1) * StepY.Y + (z + 1) * StepZ.Y),
                                    new Point(Origin.X + (x + 0) * StepX.X + (y + 1) * StepY.X + (z + 1) * StepZ.X,
                                              Origin.Y + (x + 0) * StepX.Y + (y + 1) * StepY.Y + (z + 1) * StepZ.Y)
                                },
                                Fill = new SolidColorBrush(Color.FromArgb(30,
                                                                          (byte)((x + 1) / (float)GridSize.X * 255),
                                                                          (byte)((y + 1) / (float)GridSize.Y * 255),
                                                                          (byte)((z + 1) / (float)GridSize.Z * 255)))
                            };
                            CanvasFill.Children.Add(Poly);
                        }

                        #endregion
                    }
                }
            }

            #region Bounding box

            // Top left
            {
                Line EdgeLine = new Line
                {
                    X1 = Origin.X + 0 * GridSize.X * StepX.X + 0 * GridSize.Y * StepY.X + 1 * GridSize.Z * StepZ.X,
                    Y1 = Origin.Y + 0 * GridSize.X * StepX.Y + 0 * GridSize.Y * StepY.Y + 1 * GridSize.Z * StepZ.Y,

                    X2 = Origin.X + 0 * GridSize.X * StepX.X + 1 * GridSize.Y * StepY.X + 1 * GridSize.Z * StepZ.X,
                    Y2 = Origin.Y + 0 * GridSize.X * StepX.Y + 1 * GridSize.Y * StepY.Y + 1 * GridSize.Z * StepZ.Y,

                    StrokeThickness = 1,
                    Stroke          = BoundsBrush
                };
                CanvasLines.Children.Add(EdgeLine);
            }

            // Top right
            {
                Line EdgeLine = new Line
                {
                    X1 = Origin.X + 0 * GridSize.X * StepX.X + 0 * GridSize.Y * StepY.X + 1 * GridSize.Z * StepZ.X,
                    Y1 = Origin.Y + 0 * GridSize.X * StepX.Y + 0 * GridSize.Y * StepY.Y + 1 * GridSize.Z * StepZ.Y,

                    X2 = Origin.X + 1 * GridSize.X * StepX.X + 0 * GridSize.Y * StepY.X + 1 * GridSize.Z * StepZ.X,
                    Y2 = Origin.Y + 1 * GridSize.X * StepX.Y + 0 * GridSize.Y * StepY.Y + 1 * GridSize.Z * StepZ.Y,

                    StrokeThickness = 1,
                    Stroke          = BoundsBrush
                };
                CanvasLines.Children.Add(EdgeLine);
            }

            // Middle left
            {
                Line EdgeLine = new Line
                {
                    X1 = Origin.X + 0 * GridSize.X * StepX.X + 1 * GridSize.Y * StepY.X + 1 * GridSize.Z * StepZ.X,
                    Y1 = Origin.Y + 0 * GridSize.X * StepX.Y + 1 * GridSize.Y * StepY.Y + 1 * GridSize.Z * StepZ.Y,

                    X2 = Origin.X + 1 * GridSize.X * StepX.X + 1 * GridSize.Y * StepY.X + 1 * GridSize.Z * StepZ.X,
                    Y2 = Origin.Y + 1 * GridSize.X * StepX.Y + 1 * GridSize.Y * StepY.Y + 1 * GridSize.Z * StepZ.Y,

                    StrokeThickness = 1,
                    Stroke          = BoundsBrush
                };
                CanvasLines.Children.Add(EdgeLine);
            }

            // Middle right
            {
                Line EdgeLine = new Line
                {
                    X1 = Origin.X + 1 * GridSize.X * StepX.X + 0 * GridSize.Y * StepY.X + 1 * GridSize.Z * StepZ.X,
                    Y1 = Origin.Y + 1 * GridSize.X * StepX.Y + 0 * GridSize.Y * StepY.Y + 1 * GridSize.Z * StepZ.Y,

                    X2 = Origin.X + 1 * GridSize.X * StepX.X + 1 * GridSize.Y * StepY.X + 1 * GridSize.Z * StepZ.X,
                    Y2 = Origin.Y + 1 * GridSize.X * StepX.Y + 1 * GridSize.Y * StepY.Y + 1 * GridSize.Z * StepZ.Y,

                    StrokeThickness = 1,
                    Stroke          = BoundsBrush
                };
                CanvasLines.Children.Add(EdgeLine);
            }

            // Bottom left
            {
                Line EdgeLine = new Line
                {
                    X1 = Origin.X + 0 * GridSize.X * StepX.X + 1 * GridSize.Y * StepY.X + 0 * GridSize.Z * StepZ.X,
                    Y1 = Origin.Y + 0 * GridSize.X * StepX.Y + 1 * GridSize.Y * StepY.Y + 0 * GridSize.Z * StepZ.Y,

                    X2 = Origin.X + 1 * GridSize.X * StepX.X + 1 * GridSize.Y * StepY.X + 0 * GridSize.Z * StepZ.X,
                    Y2 = Origin.Y + 1 * GridSize.X * StepX.Y + 1 * GridSize.Y * StepY.Y + 0 * GridSize.Z * StepZ.Y,

                    StrokeThickness = 1,
                    Stroke          = BoundsBrush
                };
                CanvasLines.Children.Add(EdgeLine);
            }

            // Bottom right
            {
                Line EdgeLine = new Line
                {
                    X1 = Origin.X + 1 * GridSize.X * StepX.X + 0 * GridSize.Y * StepY.X + 0 * GridSize.Z * StepZ.X,
                    Y1 = Origin.Y + 1 * GridSize.X * StepX.Y + 0 * GridSize.Y * StepY.Y + 0 * GridSize.Z * StepZ.Y,

                    X2 = Origin.X + 1 * GridSize.X * StepX.X + 1 * GridSize.Y * StepY.X + 0 * GridSize.Z * StepZ.X,
                    Y2 = Origin.Y + 1 * GridSize.X * StepX.Y + 1 * GridSize.Y * StepY.Y + 0 * GridSize.Z * StepZ.Y,

                    StrokeThickness = 1,
                    Stroke          = BoundsBrush
                };
                CanvasLines.Children.Add(EdgeLine);
            }

            // Vertical left
            {
                Line EdgeLine = new Line
                {
                    X1 = Origin.X + 0 * GridSize.X * StepX.X + 1 * GridSize.Y * StepY.X + 0 * GridSize.Z * StepZ.X,
                    Y1 = Origin.Y + 0 * GridSize.X * StepX.Y + 1 * GridSize.Y * StepY.Y + 0 * GridSize.Z * StepZ.Y,

                    X2 = Origin.X + 0 * GridSize.X * StepX.X + 1 * GridSize.Y * StepY.X + 1 * GridSize.Z * StepZ.X,
                    Y2 = Origin.Y + 0 * GridSize.X * StepX.Y + 1 * GridSize.Y * StepY.Y + 1 * GridSize.Z * StepZ.Y,

                    StrokeThickness = 1,
                    Stroke          = BoundsBrush
                };
                CanvasLines.Children.Add(EdgeLine);
            }

            // Vertical middle
            {
                Line EdgeLine = new Line
                {
                    X1 = Origin.X + 1 * GridSize.X * StepX.X + 1 * GridSize.Y * StepY.X + 0 * GridSize.Z * StepZ.X,
                    Y1 = Origin.Y + 1 * GridSize.X * StepX.Y + 1 * GridSize.Y * StepY.Y + 0 * GridSize.Z * StepZ.Y,

                    X2 = Origin.X + 1 * GridSize.X * StepX.X + 1 * GridSize.Y * StepY.X + 1 * GridSize.Z * StepZ.X,
                    Y2 = Origin.Y + 1 * GridSize.X * StepX.Y + 1 * GridSize.Y * StepY.Y + 1 * GridSize.Z * StepZ.Y,

                    StrokeThickness = 1,
                    Stroke          = BoundsBrush
                };
                CanvasLines.Children.Add(EdgeLine);
            }

            // Vertical right
            {
                Line EdgeLine = new Line
                {
                    X1 = Origin.X + 1 * GridSize.X * StepX.X + 0 * GridSize.Y * StepY.X + 0 * GridSize.Z * StepZ.X,
                    Y1 = Origin.Y + 1 * GridSize.X * StepX.Y + 0 * GridSize.Y * StepY.Y + 0 * GridSize.Z * StepZ.Y,

                    X2 = Origin.X + 1 * GridSize.X * StepX.X + 0 * GridSize.Y * StepY.X + 1 * GridSize.Z * StepZ.X,
                    Y2 = Origin.Y + 1 * GridSize.X * StepX.Y + 0 * GridSize.Y * StepY.Y + 1 * GridSize.Z * StepZ.Y,

                    StrokeThickness = 1,
                    Stroke          = BoundsBrush
                };
                CanvasLines.Children.Add(EdgeLine);
            }

            #endregion
        }