public static SphereDataView Create(SphereData originalSphereData, Rect3D displayedDataBounds, double maxTime, Size locationBounds, double maxSize) { // First calculate normalized values (from 0 to 1) double x = originalSphereData.Time / maxTime; double y = originalSphereData.Location.Y / locationBounds.Height; double z = originalSphereData.Location.X / locationBounds.Width; // Set color of the sphere based on its y position // We choose the color from the gradient defined in EnsureGradientColorsArray EnsureGradientColorsArray(); int colorArrayIndex = (int)(y * _gradientColorsArray.Length); Color color = _gradientColorsArray[colorArrayIndex]; // Now put normalized values into a 3D space that is defined by displayedDataBounds x = (x * displayedDataBounds.SizeX) + displayedDataBounds.X; y = (y * displayedDataBounds.SizeY) + displayedDataBounds.Y; z = (z * displayedDataBounds.SizeZ) + displayedDataBounds.Z; Point3D position3D = new Point3D(x, y, z); // Use Size value to define the sphere radius in a range from 1 to 3 double sphereRadius = (originalSphereData.Size / maxSize) * 2 + 1; // Now we have all the data to create the SphereDataView var sphereDataView = new SphereDataView(originalSphereData, position3D, color, sphereRadius); return(sphereDataView); }
public void SelectData(SphereDataView selectedPositionData, Point mousePosition) { // Show tooltip with details DataToolTipBorder.DataContext = selectedPositionData; Canvas.SetLeft(DataToolTipBorder, mousePosition.X + 10); Canvas.SetTop(DataToolTipBorder, mousePosition.Y + 10); DataToolTipBorder.Visibility = Visibility.Visible; // Add additional 3D lines that will show where the sphere is in the 3D space double wireBoxBottom = AxisWireBox.CenterPosition.Y - AxisWireBox.Size.Y * 0.5; var verticalLineVisual3D = new Ab3d.Visuals.LineVisual3D() { StartPosition = selectedPositionData.Position, EndPosition = new Point3D(selectedPositionData.Position.X, wireBoxBottom, selectedPositionData.Position.Z), LineThickness = 2, LineColor = Colors.Gray }; SelectedSphereLinesVisual.Children.Add(verticalLineVisual3D); double x1 = AxisWireBox.CenterPosition.X - AxisWireBox.Size.X * 0.5; double x2 = AxisWireBox.CenterPosition.X + AxisWireBox.Size.X * 0.5; var xLineVisual3D = new Ab3d.Visuals.LineVisual3D() { StartPosition = new Point3D(x1, wireBoxBottom, selectedPositionData.Position.Z), EndPosition = new Point3D(x2, wireBoxBottom, selectedPositionData.Position.Z), LineThickness = 2, LineColor = Colors.Gray }; SelectedSphereLinesVisual.Children.Add(xLineVisual3D); double z1 = AxisWireBox.CenterPosition.Z - AxisWireBox.Size.Z * 0.5; double z2 = AxisWireBox.CenterPosition.Z + AxisWireBox.Size.Z * 0.5; var zLineVisual3D = new Ab3d.Visuals.LineVisual3D() { StartPosition = new Point3D(selectedPositionData.Position.X, wireBoxBottom, z1), EndPosition = new Point3D(selectedPositionData.Position.X, wireBoxBottom, z2), LineThickness = 2, LineColor = Colors.Gray }; SelectedSphereLinesVisual.Children.Add(zLineVisual3D); }
public void ShowData(List <SphereData> originalData) { // Now use original data to create our data view objects // All data will be displayed in a 3D box defined below: var displayedDataBounds = new Rect3D(-40, -20, -40, 80, 40, 80); _allPositionsData = new List <SphereDataView>(originalData.Count); foreach (var originalSphereData in originalData) { var sphereDataView = SphereDataView.Create(originalSphereData, displayedDataBounds, originalData.Count, _locationSize, _maxSize); sphereDataView.IsSelectedChanged += delegate(object sender, EventArgs args) { var changedPositionDataView = (SphereDataView)sender; if (changedPositionDataView.IsSelected) { DataListBox.SelectedItems.Add(changedPositionDataView); } else { DataListBox.SelectedItems.Remove(changedPositionDataView); } UpdateSelectedSpheresData(); }; _allPositionsData.Add(sphereDataView); } // Setup axis limits and shown values AxisWireBox.MinYValue = 0; AxisWireBox.MaxYValue = 10; AxisWireBox.YAxisValues = new double[] { 0, 2, 4, 6, 8, 10 }; // Bind positions data to ListBox DataListBox.ItemsSource = _allPositionsData; // Create curve through all positions // This is done by first creating all points that define the curve (10 points between each position that define the curve) List <Point3D> allPositions = new List <Point3D>(); foreach (var positionData in _allPositionsData) { allPositions.Add(positionData.Position); } BezierCurve bezierCurve = Ab3d.Utilities.BezierCurve.CreateFromCurvePositions(allPositions); Point3DCollection curvePoints = bezierCurve.CreateBezierCurve(positionsPerSegment: 10); // How many points between each defined position in the curve // Create 3D Polyline from curvePoints Model3D curveModel = Ab3d.Models.Line3DFactory.CreatePolyLine3D(curvePoints, thickness: 2, color: Colors.Blue, isClosed: false, startLineCap: LineCap.Flat, endLineCap: LineCap.Flat, parentViewport3D: MainViewport); CurveModelVisual.Content = curveModel; // Now create 3D sphere objects for each position SpheresModelVisual.Children.Clear(); // Each sphere will also need MouseEnter, MouseLeave and MouseClick event handlers // We use EventManager3D for that var eventManager3D = new Ab3d.Utilities.EventManager3D(MainViewport); // Add 3D sphere for each position foreach (var positionData in _allPositionsData) { SpheresModelVisual.Children.Add(positionData.ModelVisual3D); // Sphere Visual3D is created in SphereDataView object // Add event handlers (sphere Visual3D will be the source of the events) var visualEventSource3D = new VisualEventSource3D(positionData.ModelVisual3D); visualEventSource3D.MouseEnter += delegate(object sender, Mouse3DEventArgs e) { if (_isSelecting) { return; } // Use hand cursor Mouse.OverrideCursor = Cursors.Hand; // Find selected position data var selectedPositionData = _allPositionsData.FirstOrDefault(p => p.ModelVisual3D == e.HitObject); SelectData(selectedPositionData, e.CurrentMousePosition); }; visualEventSource3D.MouseLeave += delegate(object sender, Mouse3DEventArgs e) { if (_isSelecting) { return; } Mouse.OverrideCursor = null; DataToolTipBorder.Visibility = Visibility.Collapsed; DataToolTipBorder.DataContext = null; SelectedSphereLinesVisual.Children.Clear(); }; visualEventSource3D.MouseClick += delegate(object sender, MouseButton3DEventArgs e) { // Select / deselect on mouse click var clickedPositionData = _allPositionsData.FirstOrDefault(p => p.ModelVisual3D == e.HitObject); if (clickedPositionData != null) { positionData.IsSelected = !clickedPositionData.IsSelected; } }; // Register the event source eventManager3D.RegisterEventSource3D(visualEventSource3D); } }