144 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C#
		
	
	
	
		
		
			
		
	
	
			144 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C#
		
	
	
	
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								namespace TriangleNet.Geometry
							 | 
						|||
| 
								 | 
							
								{
							 | 
						|||
| 
								 | 
							
								    using System;
							 | 
						|||
| 
								 | 
							
								    using TriangleNet.Meshing;
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								    public static class ExtensionMethods
							 | 
						|||
| 
								 | 
							
								    {
							 | 
						|||
| 
								 | 
							
								        #region IPolygon extensions
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Triangulates a polygon.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        public static IMesh Triangulate(this IPolygon polygon)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return (new GenericMesher()).Triangulate(polygon, null, null);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Triangulates a polygon, applying constraint options.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="options">Constraint options.</param>
							 | 
						|||
| 
								 | 
							
								        public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return (new GenericMesher()).Triangulate(polygon, options, null);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Triangulates a polygon, applying quality options.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="quality">Quality options.</param>
							 | 
						|||
| 
								 | 
							
								        public static IMesh Triangulate(this IPolygon polygon, QualityOptions quality)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return (new GenericMesher()).Triangulate(polygon, null, quality);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Triangulates a polygon, applying quality and constraint options.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="options">Constraint options.</param>
							 | 
						|||
| 
								 | 
							
								        /// <param name="quality">Quality options.</param>
							 | 
						|||
| 
								 | 
							
								        public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return (new GenericMesher()).Triangulate(polygon, options, quality);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Triangulates a polygon, applying quality and constraint options.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="options">Constraint options.</param>
							 | 
						|||
| 
								 | 
							
								        /// <param name="quality">Quality options.</param>
							 | 
						|||
| 
								 | 
							
								        /// <param name="triangulator">The triangulation algorithm.</param>
							 | 
						|||
| 
								 | 
							
								        public static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality,
							 | 
						|||
| 
								 | 
							
								            ITriangulator triangulator)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return (new GenericMesher(triangulator)).Triangulate(polygon, options, quality);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #endregion
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #region Rectangle extensions
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #endregion
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #region ITriangle extensions
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Test whether a given point lies inside a triangle or not.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="p">Point to locate.</param>
							 | 
						|||
| 
								 | 
							
								        /// <returns>True, if point is inside or on the edge of this triangle.</returns>
							 | 
						|||
| 
								 | 
							
								        public static bool Contains(this ITriangle triangle, Point p)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return Contains(triangle, p.X, p.Y);
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        /// <summary>
							 | 
						|||
| 
								 | 
							
								        /// Test whether a given point lies inside a triangle or not.
							 | 
						|||
| 
								 | 
							
								        /// </summary>
							 | 
						|||
| 
								 | 
							
								        /// <param name="x">Point to locate.</param>
							 | 
						|||
| 
								 | 
							
								        /// <param name="y">Point to locate.</param>
							 | 
						|||
| 
								 | 
							
								        /// <returns>True, if point is inside or on the edge of this triangle.</returns>
							 | 
						|||
| 
								 | 
							
								        public static bool Contains(this ITriangle triangle, double x, double y)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            var t0 = triangle.GetVertex(0);
							 | 
						|||
| 
								 | 
							
								            var t1 = triangle.GetVertex(1);
							 | 
						|||
| 
								 | 
							
								            var t2 = triangle.GetVertex(2);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            // TODO: no need to create new Point instances here
							 | 
						|||
| 
								 | 
							
								            Point d0 = new Point(t1.X - t0.X, t1.Y - t0.Y);
							 | 
						|||
| 
								 | 
							
								            Point d1 = new Point(t2.X - t0.X, t2.Y - t0.Y);
							 | 
						|||
| 
								 | 
							
								            Point d2 = new Point(x - t0.X, y - t0.Y);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            // crossproduct of (0, 0, 1) and d0
							 | 
						|||
| 
								 | 
							
								            Point c0 = new Point(-d0.Y, d0.X);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            // crossproduct of (0, 0, 1) and d1
							 | 
						|||
| 
								 | 
							
								            Point c1 = new Point(-d1.Y, d1.X);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            // Linear combination d2 = s * d0 + v * d1.
							 | 
						|||
| 
								 | 
							
								            //
							 | 
						|||
| 
								 | 
							
								            // Multiply both sides of the equation with c0 and c1
							 | 
						|||
| 
								 | 
							
								            // and solve for s and v respectively
							 | 
						|||
| 
								 | 
							
								            //
							 | 
						|||
| 
								 | 
							
								            // s = d2 * c1 / d0 * c1
							 | 
						|||
| 
								 | 
							
								            // v = d2 * c0 / d1 * c0
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            double s = DotProduct(d2, c1) / DotProduct(d0, c1);
							 | 
						|||
| 
								 | 
							
								            double v = DotProduct(d2, c0) / DotProduct(d1, c0);
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            if (s >= 0 && v >= 0 && ((s + v) <= 1))
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                // Point is inside or on the edge of this triangle.
							 | 
						|||
| 
								 | 
							
								                return true;
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            return false;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        public static Rectangle Bounds(this ITriangle triangle)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            var bounds = new Rectangle();
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            for (int i = 0; i < 3; i++)
							 | 
						|||
| 
								 | 
							
								            {
							 | 
						|||
| 
								 | 
							
								                bounds.Expand(triangle.GetVertex(i));
							 | 
						|||
| 
								 | 
							
								            }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								            return bounds;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #endregion
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #region Helper methods
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        internal static double DotProduct(Point p, Point q)
							 | 
						|||
| 
								 | 
							
								        {
							 | 
						|||
| 
								 | 
							
								            return p.X * q.X + p.Y * q.Y;
							 | 
						|||
| 
								 | 
							
								        }
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								        #endregion
							 | 
						|||
| 
								 | 
							
								    }
							 | 
						|||
| 
								 | 
							
								}
							 |