public void TestBaseCaseTriangle()
            {
                List <Point> triangleInPositiveOrientation = new List <Point>()
                {
                    new Point(0, 0), new Point(1, 0), new Point(0, 1)
                };

                Int32Collection indices = SweepLinePolygonTriangulator.Triangulate(triangleInPositiveOrientation);

                Assert.That(indices.Count == 3);
                Assert.That(indices[0] == 0);
                Assert.That(indices[1] == 1);
                Assert.That(indices[2] == 2);


                List <Point> triangleInNegativeOrientation = new List <Point>()
                {
                    new Point(0, 0), new Point(0, 1), new Point(1, 0)
                };

                indices = SweepLinePolygonTriangulator.Triangulate(triangleInNegativeOrientation);
                Assert.That(indices.Count == 3);
                Assert.That(indices[0] == 0);
                Assert.That(indices[1] == 2);
                Assert.That(indices[2] == 1);
            }
Пример #2
0
        private static void CreateSimpleTriangulatedMesh(MeshBuilder meshBuilder)
        {
            List <Point> triangleInPositiveOrientation = new List <Point>()
            {
                new Point(0, 0),
                new Point(1, 0),
                new Point(0, 1)
            };
            //it's up to the user how to map 2D points to 3D, in this case we simply add a z-coordinate to the points:
            IEnumerable <Point3D> triangleInXYPlane = triangleInPositiveOrientation.Select(p => new Point3D(p.X, p.Y, 0));

            foreach (Point3D point in triangleInXYPlane)
            {
                meshBuilder.Positions.Add(point);
            }

            Int32Collection indices = SweepLinePolygonTriangulator.Triangulate(triangleInPositiveOrientation);

            foreach (int index in indices)
            {
                meshBuilder.TriangleIndices.Add(index);
            }

            //Create a triangle with the reversed orientation, this should thus also be visible from the other side:
            List <Point> triangleInNegativeOrientation = new List <Point>()
            {
                new Point(0, 0),
                new Point(0, 1),
                new Point(1, 0)
            };

            triangleInXYPlane = triangleInPositiveOrientation.Select(p => new Point3D(p.X, p.Y, 1));
            foreach (Point3D point in triangleInXYPlane)
            {
                meshBuilder.Positions.Add(point);
            }


            indices = SweepLinePolygonTriangulator.Triangulate(triangleInNegativeOrientation);
            foreach (int index in indices)
            {
                //add 3 as we have already added a triangle before, making the starting index of this triangle 3 higher:
                meshBuilder.TriangleIndices.Add(index + 3);
            }
        }
Пример #3
0
        /// <summary>
        /// Generate a simple Polygon and then triangulate it.
        /// The Result is then Displayed.
        /// </summary>
        /// <param name="sender">The Sender (i.e. the Button)</param>
        /// <param name="e">The routet Event Args</param>
        private void generatePolygonButton_Click(object sender, RoutedEventArgs e)
        {
            // Generate random Polygon
            var random = new Random();
            var cnt    = mViewModel.PointCount;

            mPolygonPoints = new List <Vector2>();
            var angle     = 0f;
            var angleDiff = 2f * (Single)Math.PI / cnt;
            var radius    = 4f;
            // Random Radii for the Polygon
            var radii      = new List <float>();
            var innerRadii = new List <float>();

            for (int i = 0; i < cnt; i++)
            {
                radii.Add(random.NextFloat(radius * 0.9f, radius * 1.1f));
                innerRadii.Add(random.NextFloat(radius * 0.2f, radius * 0.3f));
            }
            var hole1        = new List <Vector2>();
            var hole2        = new List <Vector2>();
            var holeDistance = 2f;
            var holeAngle    = random.NextFloat(0, (float)Math.PI * 2);
            var cos          = (float)Math.Cos(holeAngle);
            var sin          = (float)Math.Sin(holeAngle);
            var offset1      = new Vector2(holeDistance * cos, holeDistance * sin);
            var offset2      = new Vector2(-holeDistance * cos, -holeDistance * sin);

            for (int i = 0; i < cnt; i++)
            {
                // Flatten a bit
                var radiusUse = radii[i];
                mPolygonPoints.Add(new Vector2(radii[i] * (Single)Math.Cos(angle), radii[i] * (Single)Math.Sin(angle)));
                hole1.Add(offset1 + new Vector2(innerRadii[i] * (Single)Math.Cos(-angle), innerRadii[i] * (Single)Math.Sin(-angle)));
                hole2.Add(offset2 + new Vector2(innerRadii[i] * (Single)Math.Cos(-angle), innerRadii[i] * (Single)Math.Sin(-angle)));
                angle += angleDiff;
            }

            var holes = new List <List <Vector2> >()
            {
                hole1, hole2
            };

            // Triangulate and measure the Time needed for the Triangulation
            var before = DateTime.Now;
            var sLTI   = SweepLinePolygonTriangulator.Triangulate(mPolygonPoints, holes);
            var after  = DateTime.Now;

            // Generate the Output
            var geometry = new HelixToolkit.Wpf.SharpDX.MeshGeometry3D();

            geometry.Positions = new HelixToolkit.Wpf.SharpDX.Core.Vector3Collection();
            geometry.Normals   = new HelixToolkit.Wpf.SharpDX.Core.Vector3Collection();
            foreach (var point in mPolygonPoints.Union(holes.SelectMany(h => h)))
            {
                geometry.Positions.Add(new Vector3(point.X, 0, point.Y + 5));
                geometry.Normals.Add(new Vector3(0, 1, 0));
            }
            geometry.Indices             = new HelixToolkit.Wpf.SharpDX.Core.IntCollection(sLTI);
            triangulatedPolygon.Geometry = geometry;

            var lb = new LineBuilder();

            for (int i = 0; i < sLTI.Count; i += 3)
            {
                lb.AddLine(geometry.Positions[sLTI[i]], geometry.Positions[sLTI[i + 1]]);
                lb.AddLine(geometry.Positions[sLTI[i + 1]], geometry.Positions[sLTI[i + 2]]);
                lb.AddLine(geometry.Positions[sLTI[i + 2]], geometry.Positions[sLTI[i]]);
            }
            mViewModel.LineGeometry = lb.ToLineGeometry3D();

            // Set the Lines if activated
            if (mViewModel.ShowTriangleLines)
            {
                lineTriangulatedPolygon.Geometry = mViewModel.LineGeometry;
            }
            else
            {
                lineTriangulatedPolygon.Geometry = null;
            }

            // Set the InfoLabel Text
            var timeNeeded = (after - before).TotalMilliseconds;

            infoLabel.Content = String.Format("Last triangulation of {0} Points took {1:0.##} Milliseconds!", triangulatedPolygon.Geometry.Positions.Count, timeNeeded);
        }
Пример #4
0
 /// <summary>
 /// Triangulate the polygon by using the sweep line algorithm
 /// </summary>
 /// <returns>An index collection.</returns>
 public Int32Collection Triangulate()
 {
     return(SweepLinePolygonTriangulator.Triangulate(this.points));
 }
Пример #5
0
        /// <summary>
        /// Generate a simple Polygon and then triangulate it.
        /// The Result is then Displayed.
        /// </summary>
        /// <param name="sender">The Sender (i.e. the Button)</param>
        /// <param name="e">The routet Event Args</param>
        private void generatePolygonButton_Click(object sender, RoutedEventArgs e)
        {
            // Generate random Polygon
            var random = new Random();
            var cnt    = mViewModel.PointCount;

            mPolygonPoints = new List <Vector2>();
            var angle     = 0f;
            var angleDiff = 2f * (Single)Math.PI / cnt;
            var radius    = 4f;
            // Random Radii for the Polygon
            var radii = new List <float>();

            for (int i = 0; i < cnt; i++)
            {
                radii.Add(radius + random.NextFloat(-radius, radius));
            }
            for (int i = 0; i < cnt; i++)
            {
                var last = i > 0 ? i - 1 : cnt - 1;
                var next = i < cnt - 1 ? i + 1 : 0;
                // Flatten a bit
                var radiusUse = radii[last] * 0.25f + radii[i] * 0.5f + radii[next] * 0.25f;
                mPolygonPoints.Add(new Vector2(radiusUse * (Single)Math.Cos(angle), radiusUse * (Single)Math.Sin(angle)));
                angle += angleDiff;
            }
            // Triangulate and measure the Time needed for the Triangulation
            var before = DateTime.Now;
            var sLTI   = SweepLinePolygonTriangulator.Triangulate(mPolygonPoints);
            var after  = DateTime.Now;

            // Generate the Output
            var geometry = new HelixToolkit.Wpf.SharpDX.MeshGeometry3D();

            geometry.Positions = new HelixToolkit.Wpf.SharpDX.Core.Vector3Collection();
            geometry.Normals   = new HelixToolkit.Wpf.SharpDX.Core.Vector3Collection();
            foreach (var point in mPolygonPoints)
            {
                geometry.Positions.Add(new Vector3(point.X, 0, point.Y + 5));
                geometry.Normals.Add(new Vector3(0, 1, 0));
            }
            geometry.Indices             = new HelixToolkit.Wpf.SharpDX.Core.IntCollection(sLTI);
            triangulatedPolygon.Geometry = geometry;

            var lb = new LineBuilder();

            for (int i = 0; i < sLTI.Count; i += 3)
            {
                lb.AddLine(geometry.Positions[sLTI[i]], geometry.Positions[sLTI[i + 1]]);
                lb.AddLine(geometry.Positions[sLTI[i + 1]], geometry.Positions[sLTI[i + 2]]);
                lb.AddLine(geometry.Positions[sLTI[i + 2]], geometry.Positions[sLTI[i]]);
            }
            mViewModel.LineGeometry = lb.ToLineGeometry3D();

            // Set the Lines if activated
            if (mViewModel.ShowTriangleLines)
            {
                lineTriangulatedPolygon.Geometry = mViewModel.LineGeometry;
            }
            else
            {
                lineTriangulatedPolygon.Geometry = null;
            }

            // Set the InfoLabel Text
            var timeNeeded = (after - before).TotalMilliseconds;

            infoLabel.Content = String.Format("Last triangulation of {0} Points took {1:0.##} Milliseconds!", triangulatedPolygon.Geometry.Positions.Count, timeNeeded);
        }