AddArrow() public method

Adds an arrow to the mesh.
public AddArrow ( System.Windows.Media.Media3D.Point3D point1, System.Windows.Media.Media3D.Point3D point2, double diameter, double headLength = 3, double headDiameter = 2, int thetaDiv = 18 ) : void
point1 System.Windows.Media.Media3D.Point3D /// The start point. ///
point2 System.Windows.Media.Media3D.Point3D /// The end point. ///
diameter double /// The diameter of the arrow cylinder. ///
headLength double /// Length of the head (relative to diameter). ///
headDiameter double
thetaDiv int /// The number of divisions around the arrow. ///
return void
示例#1
0
        //// Using a DependencyProperty as the backing store for Direction.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty DirectionProperty =
        //    DependencyProperty.Register("Direction", typeof(Vector3D), typeof(SensorVisual3D), new PropertyMetadata(new Vector3D(1, 0, 0), GeometryChanged));

        //public string Name
        //{
        //    get { return (string)GetValue(NameProperty); }
        //    set { SetValue(NameProperty, value); }
        //}

        //// Using a DependencyProperty as the backing store for Name.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty NameProperty =
        //    DependencyProperty.Register("Name", typeof(Size3D), typeof(SensorVisual3D), new PropertyMetadata(new Size3D(), GeometryChanged));

        //public Size3D Size
        //{
        //    get { return (Size3D)GetValue(SizeProperty); }
        //    set { SetValue(SizeProperty, value); }
        //}

        //// Using a DependencyProperty as the backing store for Size.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty SizeProperty =
        //    DependencyProperty.Register("Size", typeof(Size3D), typeof(SensorVisual3D), new PropertyMetadata(new Size3D(0, 0, 0), GeometryChanged));

        /// <summary>
        /// The tessellate.
        /// </summary>
        /// <returns>The mesh.</returns>
        protected override MeshGeometry3D Tessellate()
        {
            var builder = new ht.MeshBuilder(true, true);

            builder.AddArrow(this.Position, this.Position + this.Orientation.Axis, 1);

            return(builder.ToMesh());
        }
示例#2
0
        private void UpdateModel()
        {
            // http://en.wikipedia.org/wiki/Lorenz_attractor
            Func<double[], double[]> lorenzAttractor = x =>
                                                           {
                                                               var dx = new double[3];
                                                               dx[0] = sigma * (x[1] - x[0]);
                                                               dx[1] = x[0] * (rho - x[2]) - x[1];
                                                               dx[2] = x[0] * x[1] - beta * x[2];
                                                               return dx;
                                                           };
            // solve the ODE
            var x0 = new[] { 0, 1, 1.05 };
            IEnumerable<double[]> solution = EulerSolver(lorenzAttractor, x0, 25);
            // todo: should have a better ODE solver (R-K(4,5)? http://www.mathworks.com/help/techdoc/ref/ode45.html)
            List<Point3D> path = solution.Select(x => new Point3D(x[0], x[1], x[2])).ToList();

            // create the WPF3D model
            var m = new Model3DGroup();
            var gm = new MeshBuilder();
            gm.AddTube(path, 0.8, 10, false);
            if (directionArrows)
            {
                // sphere at the initial point
                gm.AddSphere(path[0], 1);
                // arrow heads every 100 point
                for (int i = 100; i + 1 < path.Count; i += 100)
                {
                    gm.AddArrow(path[i], path[i + 1], 0.8);
                }
                // arrow head at the end
                Point3D p0 = path[path.Count - 2];
                Point3D p1 = path[path.Count - 1];
                var d = new Vector3D(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
                d.Normalize();
                Point3D p2 = p1 + d * 2;
                gm.AddArrow(p1, p2, 0.8);
            }

            m.Children.Add(new GeometryModel3D(gm.ToMesh(), Materials.Gold));

            Model = m;
        }
        /// <summary>
        /// Create the text for the north arrow.
        /// 
        /// It is suggested to use an image instead
        /// of text for performance purposes.  I will
        /// look into this later.
        /// </summary>
        /// <returns>3D Text.</returns>
        private Model3D NorthArrow(int numBins)
        {
            Model3DGroup group = new Model3DGroup();

            // Get the length of the cylinder, if it is 0, then display something.
            double arrowLength = CylinderRadius * SCALE_ARROW;
            if (arrowLength <= 0)
            {
                arrowLength = SCALE_ARROW;
            }

            #region Arrow
            //Create the shape of the object
            //This will be an arrow
            //Length will be the scale value
            //The position will be above the plot
            double xAxisLoc = 0;
            double yAxisLoc = 0;
            double zAxisLoc = 0;

            if (YAxis)
            {
                yAxisLoc = -numBins * TRANSLATION_SCALE;
            }
            else
            {
                xAxisLoc = numBins * TRANSLATION_SCALE;
            }

            var mb = new MeshBuilder(false, false);
            if (YAxis)
            {
                mb.AddArrow(new Point3D(xAxisLoc, yAxisLoc, zAxisLoc), new Point3D(arrowLength, yAxisLoc, zAxisLoc), LABEL_ARROW_HEAD_SIZE, 3, 100);
            }
            else
            {
                mb.AddArrow(new Point3D(xAxisLoc, yAxisLoc, zAxisLoc), new Point3D(xAxisLoc, arrowLength, zAxisLoc), LABEL_ARROW_HEAD_SIZE, 3, 100);
            }
            Geometry3D geometry = mb.ToMesh();

            //Set the color
            Material material = MaterialHelper.CreateMaterial(SELECTED_BIN_COLOR);
            material.Freeze();

            var model = new GeometryModel3D(geometry, material);
            model.BackMaterial = material;
            #endregion

            #region Text
            double xAxisLocLabel = 0;
            double yAxisLocLabel = 0;
            double zAxisLocLabel = LABEL_ARROW_HEAD_SIZE;                                       // Make the text just in front of the North arrow
            if (YAxis)
            {
                xAxisLocLabel = arrowLength / 2;                                             // Make the text in the middle of the North arrow
                yAxisLocLabel = -numBins * TRANSLATION_SCALE;                                // Go to the bottom of the column
            }
            else
            {
                xAxisLocLabel = numBins * TRANSLATION_SCALE;
                yAxisLocLabel = arrowLength / 2;
            }

            TextVisual3D txt = new TextVisual3D();
            txt.Position = new Point3D(xAxisLocLabel, yAxisLocLabel, zAxisLocLabel);
            txt.Height = 0.5;
            txt.Text = string.Format("North {0}", (arrowLength / SCALE_ARROW).ToString("0.0"));   // Need to get the arrowLenght back to m/s
            txt.TextDirection = new Vector3D(1, 0, 0);                                              // Set text to run in line with X axis
            txt.UpDirection = new Vector3D(0, 1, 0);                                                     // Set text to Point Up on Y axis
            txt.Foreground = new SolidColorBrush(Colors.Black);
            txt.Background = new SolidColorBrush(Colors.WhiteSmoke);
            txt.Padding = new Thickness(2);

            #endregion

            group.Children.Add(model);
            group.Children.Add(txt.Content);

            return group;
        }
        /// <summary>
        /// Create the East and Radius label.
        /// This will display the text for "East" and the size
        /// of the cylinder radius.
        /// </summary>
        /// <param name="numBins">Number of bins in the ensemble.</param>
        /// <returns>Model of the label.</returns>
        private Model3D EastArrow(int numBins)
        {
            Model3DGroup group = new Model3DGroup();

            // Get the length of the cylinder, if it is 0, then display something.
            double arrowLength = CylinderRadius * SCALE_ARROW;
            if (arrowLength <= 0)
            {
                arrowLength = SCALE_ARROW;
            }

            #region Arrow
            //Create the shape of the object
            //This will be an arrow
            //Length will be the scale value
            //The position will be above the plot
            double xAxisLoc = 0;
            double yAxisLoc = 0;
            double zAxisLoc = 0;
            if (YAxis)
            {
                yAxisLoc = -numBins * TRANSLATION_SCALE;                // Go to the bottom of the column
            }
            else
            {
                xAxisLoc = numBins * TRANSLATION_SCALE;
            }

            var mb = new MeshBuilder(false, false);
            mb.AddArrow(new Point3D(xAxisLoc, yAxisLoc, zAxisLoc), new Point3D(xAxisLoc, yAxisLoc, arrowLength), LABEL_ARROW_HEAD_SIZE, 3, 100);
            Geometry3D geometry = mb.ToMesh();

            //Set the color
            Material material = MaterialHelper.CreateMaterial(Colors.Lime);
            material.Freeze();

            ////Rotate the object
            //var rotation = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(xAxisLoc, yAxisLoc, zAxisLoc), 90));
            //rotation.Freeze();

            //var tg = new Transform3DGroup();
            //tg.Children.Add(rotation);

            var model = new GeometryModel3D(geometry, material) {};
            model.BackMaterial = material;
            #endregion

            #region Text
            double xAxisLocLabel = 0;
            double yAxisLocLabel = 0;
            double zAxisLocLabel = 0;
            if (YAxis)
            {
                xAxisLocLabel = -LABEL_ARROW_HEAD_SIZE;                                              // Make the text in the middle of the East arrow
                yAxisLocLabel = (-numBins * TRANSLATION_SCALE) - (ARROW_HEAD_SIZE * 2);              // Go to the bottom of the column
                zAxisLocLabel = (arrowLength / 2);                                                   // Make the text just in front of the East arrow
            }
            else
            {
                xAxisLocLabel = (numBins * TRANSLATION_SCALE) + (ARROW_HEAD_SIZE * 2);              // Go to the bottom of the column
                yAxisLocLabel = -(ARROW_HEAD_SIZE * 2);                                                   // Make the text just in front of the East arrow
                zAxisLocLabel = (arrowLength / 2);                                         // Make the text in the middle of the East arrow
            }

            TextVisual3D txt = new TextVisual3D();
            txt.Position = new Point3D(xAxisLocLabel, yAxisLocLabel, zAxisLocLabel);
            txt.Height = 0.5;
            txt.Text = string.Format("East {0}", (arrowLength / SCALE_ARROW).ToString("0.0"));
            txt.TextDirection = new Vector3D(0, 0, 1);                      // Set text to run in line with X axis
            txt.UpDirection = new Vector3D(0, 1, 0);                             // Set text to Point Up on Y axis
            txt.Foreground = new SolidColorBrush(Colors.Black);
            txt.Background = new SolidColorBrush(Colors.WhiteSmoke);
            txt.Padding = new Thickness(2);

            #endregion

            group.Children.Add(model);
            group.Children.Add(txt.Content);

            return group;
        }
        /// <summary>
        /// Create an arrow representing the magnitude and direction
        /// for a given bin.  This will create an arrow within a column.
        /// The Column will start at 0 and go down, using the bin times a scale
        /// factor to move down the column for each bin.  The magnitude will
        /// give the length and color of the arrow.  The angle will be used to rotate around
        /// the origin of 0,0, to give the direction.  The angle is based off North = 0 degrees.
        /// </summary>
        /// <param name="bin">Bin to create.</param>
        /// <param name="mag">Magnitude of the bin.</param>
        /// <param name="angleYNorth">Direction of the bin with reference to Y as North.</param>
        /// <returns>3D model of the arrow.</returns>
        private GeometryModel3D CreateBin(int bin, double mag, double angleYNorth)
        {
            // Location on the axis for each bin
            // Set the Camera UpDirection in XMAL to UpDirection="0, 1, 0" to make it use Y axis as Up.  Default is Z up.
            double xAxisLoc = 0;
            double yAxisLoc = 0;
            double zAxisLoc = 0;

            if (YAxis)
            {
                yAxisLoc = -bin * TRANSLATION_SCALE;
            }
            else
            {
                xAxisLoc = bin * TRANSLATION_SCALE;
            }

            // Create the shape of the object
            // This will be an arrow
            // Use the magnitude to get the length of the arrow
            // Create a column of bins with arrows
            var mb = new MeshBuilder(false, false);
            if (YAxis)
            {
                mb.AddArrow(new Point3D(xAxisLoc, yAxisLoc, zAxisLoc), new Point3D(mag * SCALE_ARROW, yAxisLoc, zAxisLoc), ARROW_HEAD_SIZE);
            }
            else
            {
                mb.AddArrow(new Point3D(xAxisLoc, yAxisLoc, zAxisLoc), new Point3D(xAxisLoc, mag * SCALE_ARROW, zAxisLoc), ARROW_HEAD_SIZE);
            }
            Geometry3D geometry = mb.ToMesh();

            // Set the color based off the magnitude
            // If the bin is selected, use the selected color
            Material material;
            if (bin != SelectedBin)
            {
                material = MaterialHelper.CreateMaterial(GenerateColor(mag));
            }
            else
            {
                material = MaterialHelper.CreateMaterial(SELECTED_BIN_COLOR);
            }
            material.Freeze();

            // Rotate the object
            var rotation = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(xAxisLoc, yAxisLoc, zAxisLoc), angleYNorth));
            rotation.Freeze();

            // Create the model with the rotation
            var tg = new Transform3DGroup();
            tg.Children.Add(rotation);
            var model = new GeometryModel3D(geometry, material) { Transform = tg };

            return model;
        }
示例#6
0
 /// <summary>
 /// Updates the geometry.
 /// </summary>
 protected override void UpdateGeometry()
 {
     var mb = new MeshBuilder(false, false);
     var p0 = new Point3D(0, 0, 0);
     var d = this.Direction;
     d.Normalize();
     var p1 = p0 + (d * this.Length);
     mb.AddArrow(p0, p1, this.Diameter);
     this.Model.Geometry = mb.ToMesh();
 }
示例#7
0
        /// <summary>
        /// Updates the visuals.
        /// </summary>
        protected virtual void OnMeshChanged()
        {
            this.Children.Clear();

            var builder = new MeshBuilder();
            for (int i = 0; i < this.Mesh.Positions.Count; i++)
            {
                builder.AddArrow(
                    this.Mesh.Positions[i], this.Mesh.Positions[i] + this.Mesh.Normals[i], this.Diameter, 3, 10);
            }

            this.Content = new GeometryModel3D
                {
                   Geometry = builder.ToMesh(true), Material = MaterialHelper.CreateMaterial(this.Color)
                };
        }
示例#8
0
        /// <summary>
        /// Do the tessellation and return the <see cref="MeshGeometry3D"/>.
        /// </summary>
        /// <returns>A triangular mesh geometry.</returns>
        protected override MeshGeometry3D Tessellate()
        {
            if (this.Diameter <= 0)
            {
                return null;
            }

            var builder = new MeshBuilder(true, true);
            builder.AddArrow(this.Point1, this.Point2, this.Diameter, this.HeadLength, this.ThetaDiv);
            return builder.ToMesh();
        }
        /// <summary>
        /// Updates the visuals.
        /// </summary>
        protected void UpdateVisuals()
        {
            this.vertexVisuals = new Dictionary<HalfEdgeMesh.Vertex, ModelUIElement3D>();
            this.halfEdgeVisuals = new Dictionary<HalfEdgeMesh.HalfEdge, ModelUIElement3D>();
            this.faceVisuals = new Dictionary<HalfEdgeMesh.Face, ModelUIElement3D>();
            this.Children.Clear();
            if (this.Mesh == null)
            {
                return;
            }

            if (this.VertexRadius > 0)
            {
                // Add the vertices
                foreach (var vertex in this.Mesh.Vertices)
                {
                    var gm = new MeshBuilder(false, false);
                    gm.AddSubdivisionSphere(vertex.Position, this.VertexRadius, 4);
                    var vertexElement = new ModelUIElement3D
                        {
                           Model = new GeometryModel3D(gm.ToMesh(), this.VertexMaterial)
                        };
                    var currentVertex = vertex;
                    vertexElement.MouseLeftButtonDown += (s, e) => this.HighlightVertex(currentVertex);
                    this.vertexVisuals.Add(vertex, vertexElement);
                    this.Add(vertexElement);
                }
            }

            var faceCenter = new Dictionary<HalfEdgeMesh.Face, Point3D>();

            foreach (var face in this.Mesh.Faces)
            {
                var faceVertices = face.Vertices.Select(v => v.Position).ToList();

                // Find the face centroid
                var center = this.FindCentroid(faceVertices);
                faceCenter.Add(face, center);

                if (this.ShrinkFactor < 1)
                {
                    // Add the faces
                    for (int i = 0; i < faceVertices.Count; i++)
                    {
                        faceVertices[i] += (center - faceVertices[i]) * this.ShrinkFactor;
                    }

                    var gm = new MeshBuilder(false, false);
                    gm.AddTriangleFan(faceVertices);
                    var faceElement = new ModelUIElement3D
                        {
                            Model =
                                new GeometryModel3D(gm.ToMesh(), this.FaceMaterial)
                                    {
                                       BackMaterial = this.FaceBackMaterial
                                    }
                        };
                    var currentFace = face;
                    faceElement.MouseLeftButtonDown += (s, e) => this.HighlightFace(currentFace);
                    this.faceVisuals.Add(face, faceElement);
                    this.Add(faceElement);
                }
            }

            if (this.EdgeDiameter > 0)
            {
                // Add the edges
                foreach (var edge in this.Mesh.Edges)
                {
                    var start = edge.StartVertex.Position;
                    var end = edge.EndVertex.Position;
                    var center = faceCenter[edge.Face];
                    start = start + (center - start) * this.ShrinkFactor;
                    end = end + (center - end) * this.ShrinkFactor;
                    var gm = new MeshBuilder(false, false);
                    gm.AddArrow(start, end, this.EdgeDiameter);
                    var edgeElement = new ModelUIElement3D
                        {
                           Model = new GeometryModel3D(gm.ToMesh(), this.EdgeMaterial)
                        };
                    var currentEdge = edge;
                    edgeElement.MouseLeftButtonDown += (s, e) => { this.HighlightEdge(currentEdge); };
                    this.halfEdgeVisuals.Add(edge, edgeElement);
                    this.Add(edgeElement);
                }
            }
        }
示例#10
0
文件: 3DView.cs 项目: litdev1/LitDev
        /// <summary>
        /// Add an arrow geometry object pointing up starting at (0,0,0).
        /// </summary>
        /// <param name="shapeName">The 3DView object.</param>
        /// <param name="length">The length of the arrow.</param>
        /// <param name="diameter">The diameter of the arrow shaft.</param>
        /// <param name="arrowLength">The length of the arrow head.</param>
        /// <param name="arrowDiameter">The diameter of the arrow head.</param>
        /// <param name="divisions">The number of divisions for the arrow (default 18).</param>
        /// <param name="colour">A colour or gradient brush for the object.</param>
        /// <param name="materialType">A material for the object.
        /// The available options are:
        /// "E" Emmissive - constant brightness.
        /// "D" Diffusive - affected by lights.
        /// "S" Specular  - specular highlights.
        /// </param>
        /// <returns>The 3DView Geometry name.</returns>
        public static Primitive AddArrow(Primitive shapeName, Primitive length, Primitive diameter, Primitive arrowLength, Primitive arrowDiameter, Primitive divisions, Primitive colour, Primitive materialType)
        {
            UIElement obj;

            try
            {
                if (_objectsMap.TryGetValue((string)shapeName, out obj))
                {
                    InvokeHelperWithReturn ret = new InvokeHelperWithReturn(delegate
                    {
                        try
                        {
                            if (obj.GetType() == typeof(Viewport3D))
                            {
                                MeshBuilder builder = new MeshBuilder(true, true);
                                builder.AddArrow(new Point3D(0, 0, 0), new Point3D(0, length, 0), diameter, arrowLength / diameter, arrowDiameter / diameter, divisions);
                                MeshGeometry3D mesh = builder.ToMesh();

                                Viewport3D viewport3D = (Viewport3D)obj;
                                return AddGeometry(viewport3D, mesh.Positions, mesh.TriangleIndices, mesh.Normals, mesh.TextureCoordinates, colour, materialType);
                            }
                        }
                        catch (Exception ex)
                        {
                            Utilities.OnError(Utilities.GetCurrentMethod(), ex);
                        }
                        return "";
                    });
                    return FastThread.InvokeWithReturn(ret).ToString();
                }
                else
                {
                    Utilities.OnShapeError(Utilities.GetCurrentMethod(), shapeName);
                }
            }
            catch (Exception ex)
            {
                Utilities.OnError(Utilities.GetCurrentMethod(), ex);
            }
            return "";
        }