private void UpdateAll()
        {
            int arraySize = GetSelectedArraySize();

            if (Function1RadioButton.IsChecked ?? false)
            {
                _data = CreateGraphData1(arraySize, arraySize, out _minYValue, out _maxYValue);
            }
            else if (Function2RadioButton.IsChecked ?? false)
            {
                _data = CreateGraphData2(arraySize, arraySize, out _minYValue, out _maxYValue);
            }
            else if (Function3RadioButton.IsChecked ?? false)
            {
                _data = CreateGraphData3(arraySize, arraySize, out _minYValue, out _maxYValue);
            }
            else if (Function4RadioButton.IsChecked ?? false)
            {
                _data = CreateGraphData4(arraySize, arraySize, out _minYValue, out _maxYValue);
            }

            HeightMap1.HeightData = _data;


            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.XAxis, 0, arraySize, 1, 0, false);
            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.YAxis, 0, arraySize, 1, 0, false);

            UpdateGradientTexture();

            UpdateWireBox();
        }
        private void CustomizeButton_OnClick(object sender, RoutedEventArgs e)
        {
            AxesBox.AxisTitleBrush    = GetRandomBrush();
            AxesBox.AxisTitleFontSize = _rnd.Next(5) + 5;

            if (!AxesBox.Is3DTextShown)
            {
                AxesBox.AxisTitleFontSize *= 2; // Increase size of title when the size is specified in 2D coordinates
            }
            AxesBox.AxisLineColor     = GetRandomColor();
            AxesBox.AxisLineThickness = _rnd.Next(3) + 0.5;

            AxesBox.TicksLineColor     = GetRandomColor();
            AxesBox.TicksLineThickness = _rnd.Next(3) + 0.5;

            AxesBox.ConnectionLinesColor     = GetRandomColor();
            AxesBox.ConnectionLinesThickness = _rnd.Next(3) + 0.5;

            AxesBox.MinorTicksLength = _rnd.Next(3) + 2;
            AxesBox.MajorTicksLength = AxesBox.MinorTicksLength * 2;

            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.XAxis, _rnd.Next(50), _rnd.Next(50) + 60, 10, 5, true);
            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.YAxis, _rnd.Next(50), _rnd.Next(50) + 60, 10, 5, true);
            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.ZAxis, _rnd.Next(50), _rnd.Next(50) + 60, 10, 5, true);
        }
        private void UpdateWireBox()
        {
            // Get local values
            Size3D heightMapSize = HeightMap1.Size;

            // First we have to get the position and size of the WireBoxVisual3
            // It is not the same as the HeightMapVisual3D because we start and stop the axis on the whole part of the _minYValue and _maxYValue
            // For example if the function's min is 0.8 and its max is 0.9 we would show axis from -1 to +1.

            double axisMinY = Math.Floor(_minYValue);
            double axisMaxY = Math.Ceiling(_maxYValue);

            double dataValuesRange = _maxYValue - _minYValue;

            double heightMapYSize = heightMapSize.Y; // This is defined by the height slider

            // First get the center
            double centerY = ((_maxYValue + _minYValue) / 2) * heightMapYSize;

            // Now calculate for how much we extend the y size to go from _minYValue to axisMinY and from _maxYValue to axisMaxY

            double axisSizeY;

            if (dataValuesRange > 0)
            {
                axisSizeY = heightMapYSize * dataValuesRange +
                            (heightMapYSize * Math.Abs(_minYValue - axisMinY)) + // extent for the axisMinY - _minYValue
                            (heightMapYSize * Math.Abs(axisMaxY - _maxYValue));  // extent for the axisMaxY - _maxYValue
            }
            else
            {
                axisSizeY = 0;
            }


            // Update the position, size and ZAxis value range
            AxesBox.CenterPosition = new Point3D(0, centerY, 0);
            AxesBox.Size           = new Size3D(100, axisSizeY, 100);

            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.ZAxis, minimumValue: axisMinY, maximumValue: axisMaxY, majorTicksStep: 1, minorTicksStep: 0, snapMaximumValueToMajorTicks: true);


            // Create contour lines
            UpdateContourLines();
        }
        public Graph3D()
        {
            InitializeComponent();

            CameraControllerInfo.AddCustomInfoLine(0, Ab3d.Controls.MouseCameraController.MouseAndKeyboardConditions.LeftMouseButtonPressed, "Click to select sphere\r\nDrag for rectangular section");


            var linearGradientBrush = CreateGradientBrush();

            _gradientColorsArray = HeightMapMesh3D.GetGradientColorsArray(linearGradientBrush, 30);

            LegendRectangle.Fill = linearGradientBrush;


            _xyDataRange = new Rect(-10, -10, 20, 20);
            _sampleData  = GenerateRandomData(_xyDataRange, relativeMargin: 0.2, dataCount: 20);


            // Setup axis limits and shown values
            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.XAxis, minimumValue: 0, maximumValue: _sampleData.Count, majorTicksStep: 2, minorTicksStep: 0, snapMaximumValueToMajorTicks: true);
            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.YAxis, minimumValue: _xyDataRange.Y, maximumValue: _xyDataRange.Y + _xyDataRange.Height, majorTicksStep: 5, minorTicksStep: 2.5, snapMaximumValueToMajorTicks: true);
            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.ZAxis, minimumValue: _xyDataRange.X, maximumValue: _xyDataRange.X + _xyDataRange.Width, majorTicksStep: 5, minorTicksStep: 2.5, snapMaximumValueToMajorTicks: true);


            // All data will be displayed in a 3D box defined below:
            var displayedDataBounds = new Rect3D(AxesBox.CenterPosition.X - AxesBox.Size.X * 0.5,
                                                 AxesBox.CenterPosition.Y - AxesBox.Size.Y * 0.5,
                                                 AxesBox.CenterPosition.Z - AxesBox.Size.Z * 0.5,
                                                 AxesBox.Size.X,
                                                 AxesBox.Size.Y,
                                                 AxesBox.Size.Z);

            ShowData(_sampleData, displayedDataBounds, _xyDataRange);

            UpdateSelectedSpheresData();

            MinValueTextBlock.Text = string.Format("{0:0}", _xyDataRange.Y);
            MaxValueTextBlock.Text = string.Format("{0:0}", _xyDataRange.Y + _xyDataRange.Height);

            // Subscribe mouse events that will be used to create selection rectangle
            ViewportBorder.MouseLeftButtonDown += SelectionOverlayCanvasOnMouseLeftButtonDown;
            ViewportBorder.MouseMove           += SelectionOverlayCanvasOnMouseMove;
            ViewportBorder.MouseLeftButtonUp   += SelectionOverlayCanvasOnMouseLeftButtonUp;
        }
        public ContourLinesSample()
        {
            InitializeComponent();

            _contourLineValues = SetupContourLineValues(minValue: 0, maxValue: 1, step: 0.05);

            _heightMapFileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources\\HeightMaps\\simpleHeightMap.png");

            _ambientLight = new AmbientLight(Colors.Black);
            MainViewport.Children.Add(_ambientLight.CreateModelVisual3D());

            OpenHeightMapDataFile(_heightMapFileName);

            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.ZAxis, minimumValue: 0, maximumValue: 1, majorTicksStep: 0.25, minorTicksStep: 0, snapMaximumValueToMajorTicks: true);

            CreateContourLines();

            ResetCamera(isTopDownOrthographicCamera: false);
        }
        public AxesBoxVisual3DSample()
        {
            InitializeComponent();


            // Customize the shown axis to show the XY axes horizontally and Z axis up (by default WPF as Y axis up).
            AxisPanel.CustomizeAxes(new Vector3D(1, 0, 0), "X", Colors.Red,
                                    new Vector3D(0, 1, 0), "Z", Colors.Blue,
                                    new Vector3D(0, 0, -1), "Y", Colors.Green);

            AxisShowingStrategyComboBox.ItemsSource   = Enum.GetValues(typeof(AxesBoxVisual3D.AxisShowingStrategies));
            AxisShowingStrategyComboBox.SelectedIndex = 1;


            // Axes colors and line thicknesses are set in XAML

            // Set axes data ranges:
            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.XAxis, minimumValue: 0, maximumValue: 100, majorTicksStep: 10, minorTicksStep: 5, snapMaximumValueToMajorTicks: true);
            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.YAxis, minimumValue: 0, maximumValue: 100, majorTicksStep: 10, minorTicksStep: 5, snapMaximumValueToMajorTicks: true);
            AxesBox.SetAxisDataRange(AxesBoxVisual3D.AxisTypes.ZAxis, minimumValue: -20, maximumValue: 200, majorTicksStep: 20, minorTicksStep: 5, snapMaximumValueToMajorTicks: true);


            // Set axes names:
            AxesBox.XAxis1.AxisTitle = "XAxis1";
            AxesBox.XAxis2.AxisTitle = null;

            AxesBox.YAxis1.AxisTitle = "YAxis1";
            AxesBox.YAxis2.AxisTitle = null;

            AxesBox.ZAxis1.AxisTitle = "ZAxis1";
            AxesBox.ZAxis2.AxisTitle = null;

            AxesBox.OverlayCanvas = AxisOverlayCanvas;

            this.Unloaded += delegate(object sender, RoutedEventArgs args)
            {
                // It is recommended to call Dispose method when the AxesBox is no longer used.
                // This releases the native memory that is used by the RenderTargetBitmap objects that can be created by the TextBlockVisual3D object.
                AxesBox.Dispose();
            };
        }