Esempio n. 1
0
        /// <summary>
        /// Cleans up a simple polygon by removing duplicate adjacent positions and making
        /// the first position not equal the last position
        /// </summary>
        public static IList <T> Cleanup <T>(IEnumerable <T> positions)
        {
            IList <T> positionsList = CollectionAlgorithms.EnumerableToList(positions);

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

            List <T> cleanedPositions = new List <T>(positionsList.Count);

            for (int i0 = positionsList.Count - 1, i1 = 0; i1 < positionsList.Count; i0 = i1++)
            {
                T v0 = positionsList[i0];
                T v1 = positionsList[i1];

                if (!v0.Equals(v1))
                {
                    cleanedPositions.Add(v1);
                }
            }

            cleanedPositions.TrimExcess();
            return(cleanedPositions);
        }
        public ICollection <Vector2D> ComputePositionsOnPlane(IEnumerable <Vector3D> positions)
        {
            if (positions == null)
            {
                throw new ArgumentNullException("positions");
            }

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

            foreach (Vector3D position in positions)
            {
                Vector3D intersectionPoint;

                if (IntersectionTests.TryRayPlane(Vector3D.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);
        }
        public EllipsoidTangentPlane(Ellipsoid ellipsoid, IEnumerable <Vector3D> 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();
        }
Esempio n. 4
0
        public void EnumerableToList2()
        {
            Dictionary <int, int> dictionary = new Dictionary <int, int>();

            dictionary.Add(0, 0);
            dictionary.Add(1, 1);

            IList <KeyValuePair <int, int> > returnedList = CollectionAlgorithms.EnumerableToList(dictionary);

            Assert.AreEqual(2, returnedList.Count);
            Assert.AreEqual(new KeyValuePair <int, int>(0, 0), returnedList[0]);
            Assert.AreEqual(new KeyValuePair <int, int>(1, 1), returnedList[1]);
        }
Esempio n. 5
0
        public void EnumerableToList()
        {
            IList <int> list = new List <int>();

            list.Add(0);
            list.Add(1);

            IList <int> returnedList = CollectionAlgorithms.EnumerableToList(list);

            Assert.AreEqual(2, returnedList.Count);
            Assert.AreEqual(0, returnedList[0]);
            Assert.AreEqual(1, returnedList[1]);
        }
Esempio n. 6
0
        public void EnumerableCount()
        {
            int[] list = new int[] { 0, 1 };
            Assert.AreEqual(2, CollectionAlgorithms.EnumerableCount(list));

            Dictionary <int, int> dictionary = new Dictionary <int, int>();

            dictionary.Add(0, 0);
            dictionary.Add(1, 1);

            IEnumerable <KeyValuePair <int, int> > enumerable = dictionary;

            Assert.AreEqual(2, CollectionAlgorithms.EnumerableCount(enumerable));
        }
Esempio n. 7
0
        public ICollection <Geodetic2D> ToGeodetic2D(IEnumerable <Vector3D> positions)
        {
            if (positions == null)
            {
                throw new ArgumentNullException("positions");
            }

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

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

            return(geodetics);
        }
Esempio n. 8
0
        public static double ComputeArea(IEnumerable <Vector2D> positions)
        {
            IList <Vector2D> positionsList = CollectionAlgorithms.EnumerableToList(positions);

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

            double area = 0.0;

            //
            // Compute the area of the polygon.  The sign of the area determines the winding order.
            //
            for (int i0 = positionsList.Count - 1, i1 = 0; i1 < positionsList.Count; i0 = i1++)
            {
                Vector2D v0 = positionsList[i0];
                Vector2D v1 = positionsList[i1];

                area += (v0.X * v1.Y) - (v1.X * v0.Y);
            }

            return(area * 0.5);
        }
Esempio n. 9
0
 public void EnumerableToListNull()
 {
     CollectionAlgorithms.EnumerableToList <int>(null);
 }
Esempio n. 10
0
 public void EnumerableCountNull()
 {
     CollectionAlgorithms.EnumerableCount <int>(null);
 }
        public static TriangleMeshSubdivisionResult Compute(IEnumerable <Vector3D> positions, IndicesUnsignedInt indices, double granularity)
        {
            if (positions == null)
            {
                throw new ArgumentNullException("positions");
            }

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

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

            if (indices.Values.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 <TriangleIndicesUnsignedInt> triangles = new Queue <TriangleIndicesUnsignedInt>(indices.Values.Count / 3);
            Queue <TriangleIndicesUnsignedInt> done      = new Queue <TriangleIndicesUnsignedInt>(indices.Values.Count / 3);

            IList <uint> indicesValues = indices.Values;

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

            //
            // New positions due to edge splits are appended to the positions list.
            //
            IList <Vector3D> 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)
            {
                TriangleIndicesUnsignedInt triangle = triangles.Dequeue();

                Vector3D v0 = subdividedPositions[triangle.I0];
                Vector3D v1 = subdividedPositions[triangle.I1];
                Vector3D v2 = subdividedPositions[triangle.I2];

                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.I0, triangle.I1), Math.Max(triangle.I0, triangle.I1));
                        int  i;
                        if (!edges.TryGetValue(edge, out i))
                        {
                            subdividedPositions.Add((v0 + v1) * 0.5);
                            i = subdividedPositions.Count - 1;
                            edges.Add(edge, i);
                        }

                        triangles.Enqueue(new TriangleIndicesUnsignedInt(triangle.I0, i, triangle.I2));
                        triangles.Enqueue(new TriangleIndicesUnsignedInt(i, triangle.I1, triangle.I2));
                    }
                    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.5);
                            i = subdividedPositions.Count - 1;
                            edges.Add(edge, i);
                        }

                        triangles.Enqueue(new TriangleIndicesUnsignedInt(triangle.I1, i, triangle.I0));
                        triangles.Enqueue(new TriangleIndicesUnsignedInt(i, triangle.I2, triangle.I0));
                    }
                    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.5);
                            i = subdividedPositions.Count - 1;
                            edges.Add(edge, i);
                        }

                        triangles.Enqueue(new TriangleIndicesUnsignedInt(triangle.I2, i, triangle.I1));
                        triangles.Enqueue(new TriangleIndicesUnsignedInt(i, triangle.I0, triangle.I1));
                    }
                }
                else
                {
                    done.Enqueue(triangle);
                }
            }

            //
            // New indices
            //
            IndicesUnsignedInt subdividedIndices = new IndicesUnsignedInt(done.Count * 3);

            foreach (TriangleIndicesUnsignedInt t in done)
            {
                subdividedIndices.AddTriangle(t);
            }

            return(new TriangleMeshSubdivisionResult(subdividedPositions, subdividedIndices));
        }