コード例 #1
0
        public EllipsoidTangentPlane(Ellipsoid ellipsoid, IEnumerable <Vector3> positions)
        {
            if (ellipsoid == null)
            {
                throw new ArgumentNullException("ellipsoid");
            }

            if (positions == null)
            {
                throw new ArgumentNullException("positions");
            }

            if (!CollectionAlgorithms.EnumerableCountGreaterThanOrEqual(positions, 1))
            {
                throw new ArgumentOutOfRangeException("positions", "At least one position is required.");
            }

            AxisAlignedBoundingBox box = new AxisAlignedBoundingBox(positions);

            _origin = ellipsoid.ScaleToGeodeticSurface(box.Center);
            _normal = ellipsoid.GeodeticSurfaceNormal(_origin);
            _d      = -_origin.Dot(_origin);
            _yAxis  = _origin.Cross(_origin.MostOrthogonalAxis).Normalize();
            _xAxis  = _yAxis.Cross(_origin).Normalize();
        }
コード例 #2
0
        public ICollection <Vector2> ComputePositionsOnPlane(IEnumerable <Vector3D> positions)
        {
            if (positions == null)
            {
                throw new ArgumentNullException("positions");
            }

            IList <Vector2> positionsOnPlane = new List <Vector2>(CollectionAlgorithms.EnumerableCount(positions));

            foreach (Vector3 position in positions)
            {
                Vector3 intersectionPoint;

                if (IntersectionTests.TryRayPlane(Vector3.Zero, position.Normalize(), _normal, _d, out intersectionPoint))
                {
                    Vector3D v = intersectionPoint - _origin;
                    positionsOnPlane.Add(new Vector2D(_xAxis.Dot(v), _yAxis.Dot(v)));
                }
                else
                {
                    // Ray does not intersect plane
                }
            }

            return(positionsOnPlane);
        }
コード例 #3
0
        public ICollection <Geodetic2D> ToGeodetic2D(IEnumerable <Vector3> positions)
        {
            if (positions == null)
            {
                throw new ArgumentNullException("positions");
            }

            IList <Geodetic2D> geodetics = new List <Geodetic2D>(CollectionAlgorithms.EnumerableCount(positions));

            foreach (Vector3 position in positions)
            {
                geodetics.Add(ToGeodetic2D(position));
            }

            return(geodetics);
        }
コード例 #4
0
        /// <summary>
        /// 返回一个mesh对象
        /// </summary>
        /// <param name="positions"></param>
        /// <param name="indices"></param>
        /// <param name="granularity"></param>
        /// <returns></returns>
        public static Mesh <Vector3> Compute(IEnumerable <Vector3> positions, ushort[] indices, double granularity)
        {
            if (positions == null)
            {
                throw new ArgumentNullException("positions");
            }

            if (indices == null)
            {
                throw new ArgumentNullException("positions");
            }

            if (indices.Count() < 3)
            {
                throw new ArgumentOutOfRangeException("indices", "At least three indices are required.");
            }

            if (indices.Count() % 3 != 0)
            {
                throw new ArgumentException("indices", "The number of indices must be divisable by three.");
            }

            if (granularity <= 0.0)
            {
                throw new ArgumentOutOfRangeException("granularity", "Granularity must be greater than zero.");
            }

            //
            // Use two queues:  one for triangles that need (or might need) to be
            // subdivided and other for triangles that are fully subdivided.
            //
            Queue <TriangleIndicesUnsignedShort> triangles = new Queue <TriangleIndicesUnsignedShort>(indices.Count() / 3);
            Queue <TriangleIndicesUnsignedShort> done      = new Queue <TriangleIndicesUnsignedShort>(indices.Count() / 3);


            for (int i = 0; i < indices.Count(); i += 3)
            {
                triangles.Enqueue(new TriangleIndicesUnsignedShort(indices[i], indices[i + 1], indices[i + 2]));
            }

            //
            // New positions due to edge splits are appended to the positions list.
            //
            IList <Vector3> subdividedPositions = CollectionAlgorithms.CopyEnumerableToList(positions);

            //
            // Used to make sure shared edges are not split more than once.
            //
            Dictionary <Edge, int> edges = new Dictionary <Edge, int>();

            //
            // Subdivide triangles until we run out
            //
            while (triangles.Count != 0)
            {
                TriangleIndicesUnsignedShort triangle = triangles.Dequeue();

                Vector3 v0 = subdividedPositions[triangle.UI0];
                Vector3 v1 = subdividedPositions[triangle.UI1];
                Vector3 v2 = subdividedPositions[triangle.UI2];

                double g0 = v0.AngleBetween(v1);
                double g1 = v1.AngleBetween(v2);
                double g2 = v2.AngleBetween(v0);

                double max = Math.Max(g0, Math.Max(g1, g2));

                if (max > granularity)
                {
                    if (g0 == max)
                    {
                        Edge edge = new Edge(Math.Min(triangle.UI0, triangle.UI1), Math.Max(triangle.UI0, triangle.UI1));
                        int  i;
                        if (!edges.TryGetValue(edge, out i))
                        {
                            subdividedPositions.Add((v0 + v1) * 0.5f);
                            i = subdividedPositions.Count - 1;
                            edges.Add(edge, i);
                        }
                        triangles.Enqueue(new TriangleIndicesUnsignedShort(triangle.UI0, (ushort)i, triangle.UI2));
                        triangles.Enqueue(new TriangleIndicesUnsignedShort((ushort)i, triangle.UI1, triangle.UI2));
                    }
                    else if (g1 == max)
                    {
                        Edge edge = new Edge(Math.Min(triangle.I1, triangle.I2), Math.Max(triangle.I1, triangle.I2));
                        int  i;
                        if (!edges.TryGetValue(edge, out i))
                        {
                            subdividedPositions.Add((v1 + v2) * 0.5f);
                            i = subdividedPositions.Count - 1;
                            edges.Add(edge, i);
                        }

                        triangles.Enqueue(new TriangleIndicesUnsignedShort(triangle.UI1, (ushort)i, triangle.UI0));
                        triangles.Enqueue(new TriangleIndicesUnsignedShort((ushort)i, triangle.UI2, triangle.UI0));
                    }
                    else if (g2 == max)
                    {
                        Edge edge = new Edge(Math.Min(triangle.I2, triangle.I0), Math.Max(triangle.I2, triangle.I0));
                        int  i;
                        if (!edges.TryGetValue(edge, out i))
                        {
                            subdividedPositions.Add((v2 + v0) * 0.5f);
                            i = subdividedPositions.Count - 1;
                            edges.Add(edge, i);
                        }

                        triangles.Enqueue(new TriangleIndicesUnsignedShort(triangle.UI2, (ushort)i, triangle.UI1));
                        triangles.Enqueue(new TriangleIndicesUnsignedShort((ushort)i, triangle.UI0, triangle.UI1));
                    }
                }
                else
                {
                    done.Enqueue(triangle);
                }
            }

            //
            // New indices
            //
            List <ushort> subdividedIndices = new List <ushort>(done.Count * 3);

            foreach (TriangleIndicesUnsignedShort t in done)
            {
                subdividedIndices.Add(t.UI0);
                subdividedIndices.Add(t.UI1);
                subdividedIndices.Add(t.UI2);
            }
            var mesh = new Mesh <Vector3>();

            mesh.Positions = subdividedPositions.ToArray();
            mesh.Indices   = subdividedIndices.ToArray();
            return(mesh);
        }