示例#1
0
        /// <summary>
        /// Returns the Vector3 Vertex Positions of the triangle.
        /// </summary>
        /// <param name="triangle"></param>
        /// <returns>
        /// A Vector3 List.
        /// </returns>
        public static List <Vector3> Points(this Elements.Geometry.Triangle triangle)
        {
            var points = new List <Vector3>();

            triangle.Vertices.ToList().ForEach(v => points.Add(v.Position));
            return(points);
        }
示例#2
0
        /// <summary>
        /// Returns a Mesh by applying the Delauney triangulation algorithm to this Polygon.
        /// </summary>
        /// <param name="polygon"></param>
        /// <returns>
        /// A Mesh.
        /// </returns>
        public static Mesh ToMesh(this Polygon polygon, bool top = true)
        {
            var points = new List <IPoint>();

            polygon.Vertices.ToList().ForEach(v => points.Add(new Point(v.X, v.Y)));
            var elev         = polygon.Vertices.First().Z;
            var delTriangles = new Delaunator(points.ToArray()).GetTriangles().ToList();
            var mesh         = new Mesh();

            foreach (var triangle in delTriangles)
            {
                var vertices = new List <Vector3>();
                triangle.Points.ToList().ForEach(p => vertices.Add(new Vector3(p.X, p.Y, elev)));
                var winder = new Polygon(vertices);
                if (!polygon.Covers(winder))
                {
                    continue;
                }
                if (winder.IsClockWise() && top || !winder.IsClockWise() && !top)
                {
                    winder = winder.Reversed();
                }
                var mTriangle = new Elements.Geometry.Triangle(new Elements.Geometry.Solids.Vertex(winder.Vertices[0]),
                                                               new Elements.Geometry.Solids.Vertex(winder.Vertices[1]),
                                                               new Elements.Geometry.Solids.Vertex(winder.Vertices[2]));
                mesh.AddTriangle(mTriangle);
                mesh.AddVertex(mTriangle.Vertices[0].Position);
                mesh.AddVertex(mTriangle.Vertices[1].Position);
                mesh.AddVertex(mTriangle.Vertices[2].Position);
            }
            mesh.ComputeNormals();
            return(mesh);
        }
示例#3
0
        /// <summary>
        /// Returns the centroid of the triangle.
        /// </summary>
        /// <returns>A double.</returns>
        public static Vector3 Centroid(this Elements.Geometry.Triangle triangle)
        {
            var a = triangle.Vertices[0].Position;
            var b = triangle.Vertices[1].Position;
            var c = triangle.Vertices[2].Position;

            return(new Line(a, new Line(b, c).Midpoint()).PointAt(0.666666666));
        }
示例#4
0
        /// <summary>
        /// Returns the area of the triangle.
        /// </summary>
        /// <returns>A double.</returns>
        public static double Area(this Elements.Geometry.Triangle triangle)
        {
            var a = triangle.Vertices[0].Position;
            var b = triangle.Vertices[1].Position;
            var c = triangle.Vertices[2].Position;

            return(Math.Abs((a.X * (b.Y - c.Y) + b.X * (c.Y - a.Y) + c.X * (a.Y - b.Y)) * 0.5));
        }
示例#5
0
        /// <summary>
        /// Returns the edges of a Triangle as a List of Lines.
        /// </summary>
        /// <returns>A List of Lines.</returns>
        public static List <Line> Edges(this Elements.Geometry.Triangle triangle)
        {
            var edges  = new List <Line>();
            var points = new List <Vector3>();

            triangle.Vertices.ToList().ForEach(v => points.Add(v.Position));
            edges.Add(new Line(points[0], points[1]));
            edges.Add(new Line(points[1], points[2]));
            edges.Add(new Line(points[2], points[0]));
            return(edges);
        }
示例#6
0
 /// <summary>
 /// Return true if an Equal Elements.Geometry.Triangle appears at least once in the supplied list.
 /// </summary>
 /// <returns>
 /// True if the Triangle vertex positions are AlmostEqual to those of any Triangle in the supplied List.
 /// </returns>
 public static bool IsListed(this Elements.Geometry.Triangle triangle,
                             List <Elements.Geometry.Triangle> triangles)
 {
     foreach (var entry in triangles)
     {
         if (triangle.IsEqualTo(entry))
         {
             return(true);
         }
     }
     return(false);
 }
示例#7
0
        /// <summary>
        /// Return true if the supplied Elements.Geometry.Triangle has the same vertices as this Triangle.
        /// </summary>
        /// <param name="thatTriangle">Triangle to compare to this Triangle.</param>
        /// <returns>
        /// True if the Triangle vertex positions are AlmostEqual to those of the supplied Triangle.
        /// </returns>
        public static bool IsEqualTo(this Elements.Geometry.Triangle triangle,
                                     Elements.Geometry.Triangle thatTriangle)
        {
            var points    = triangle.Points();
            var thosePnts = thatTriangle.Points();
            var common    = 0;

            points.ForEach(p => common += p.Occurs(thosePnts));
            if (common == 3)
            {
                return(true);
            }
            return(false);
        }
示例#8
0
        /// <summary>
        /// Return the number of times an equal Elements.Geometry.Triangle in the supplied list.
        /// </summary>
        /// <returns>
        /// An integer.
        /// </returns>
        public static int Occurs(this Elements.Geometry.Triangle triangle,
                                 List <Elements.Geometry.Triangle> triangles)
        {
            int count = 0;

            foreach (var entry in triangles)
            {
                if (triangle.IsEqualTo(entry))
                {
                    count++;
                }
            }
            return(count);
        }
示例#9
0
        /// <summary>
        /// Returns the Triangle as a CCW Polygon.
        /// </summary>
        /// <returns></returns>
        public static Polygon ToPolygon(this Elements.Geometry.Triangle triangle)
        {
            var polygon = new Polygon(triangle.Points());

            return(polygon.IsClockWise() ? polygon.Reversed() : polygon);
        }
示例#10
0
 /// <summary>
 /// Inserts this Triangle into a new List.
 /// </summary>
 /// <returns>A new List containing this Triangle.</returns>
 public static List <Elements.Geometry.Triangle> ToList(this Elements.Geometry.Triangle triangle)
 {
     return(new List <Elements.Geometry.Triangle> {
         triangle
     });
 }
示例#11
0
        /// <summary>
        /// Creates a Roof from a supplied Polygon sketch and a supplied elevation.
        /// </summary>
        /// <param name="model">The input model.</param>
        /// <param name="input">The arguments to the execution.</param>
        /// <returns>A RoofBySketchOutputs instance containing computed results and the model with any new elements.</returns>
        public static RoofBySketchOutputs Execute(Dictionary <string, Model> inputModels, RoofBySketchInputs input)
        {
            var topSide = new Elements.Geometry.Mesh();
            var area    = 0.0;

            foreach (var triangle in input.Mesh.Triangles)
            {
                var a      = topSide.AddVertex(triangle.Vertices[0].Position);
                var b      = topSide.AddVertex(triangle.Vertices[1].Position);
                var c      = topSide.AddVertex(triangle.Vertices[2].Position);
                var triAng =
                    new Elements.Geometry.Triangle(a, b, c);
                topSide.AddTriangle(triAng);
                area += triAng.Area();
            }
            topSide.ComputeNormals();

            // Find the Mesh's lowest point and use the
            // roof thickness to the set the Roof's underside elevation.
            var vertices = input.Mesh.Vertices.ToList();

            vertices = vertices.OrderBy(v => v.Position.Z).ToList();
            var elevation = vertices.First().Position.Z - input.Thickness;

            // Find the topSide Mesh's perimeter points and use them to
            // construct a Mesh representing the underside of the Roof.
            var perimeter = topSide.EdgesPerimeters().First();
            var ePoints   = new List <Vector3>();

            perimeter.ForEach(e => ePoints.AddRange(e.Points()));
            ePoints = ePoints.Distinct().ToList();
            var uPoints = new List <Vector3>();

            ePoints.ForEach(p => uPoints.Add(new Vector3(p.X, p.Y, elevation)));
            var underBoundary = new Polygon(uPoints);
            var underSide     = underBoundary.ToMesh(false);

            // Use the topSide Mesh's edgePoints and the lower Mesh's underPoints
            // to construct a series of triangles forming the sides of the Roof.
            var sideTriangles = new List <Elements.Geometry.Triangle>();

            for (var i = 0; i < ePoints.Count; i++)
            {
                sideTriangles.Add(
                    new Elements.Geometry.Triangle(new Vertex(ePoints[i]),
                                                   new Vertex(uPoints[i]),
                                                   new Vertex(uPoints[(i + 1) % uPoints.Count])));
                sideTriangles.Add(
                    new Elements.Geometry.Triangle(new Vertex(ePoints[i]),
                                                   new Vertex(uPoints[(i + 1) % uPoints.Count]),
                                                   new Vertex(ePoints[(i + 1) % ePoints.Count])));
            }

            // Construct the roof envelope in Elements.Geometry.mesh form.
            // We add vertices individually by position so that we don't affect
            // the original vertices of hte individual faces
            var Envelope = new Elements.Geometry.Mesh();

            foreach (var t in topSide.Triangles)
            {
                var a = Envelope.AddVertex(t.Vertices[0].Position);
                var b = Envelope.AddVertex(t.Vertices[1].Position);
                var c = Envelope.AddVertex(t.Vertices[2].Position);

                Envelope.AddTriangle(new Triangle(a, b, c));
            }
            foreach (var t in underSide.Triangles)
            {
                var a = Envelope.AddVertex(t.Vertices[0].Position);
                var b = Envelope.AddVertex(t.Vertices[1].Position);
                var c = Envelope.AddVertex(t.Vertices[2].Position);

                Envelope.AddTriangle(new Triangle(a, b, c));
            }
            foreach (var t in sideTriangles)
            {
                var a = Envelope.AddVertex(t.Vertices[0].Position);
                var b = Envelope.AddVertex(t.Vertices[1].Position);
                var c = Envelope.AddVertex(t.Vertices[2].Position);

                Envelope.AddTriangle(new Triangle(a, b, c));
            }
            // enVertices.ToList().ForEach(v => Envelope.AddVertex(v));
            // envTriangles.ToList().ForEach(t => Envelope.AddTriangle(t));
            Envelope.ComputeNormals();

            //Record roof high point from topSide mesh.
            var highPoint = topSide.Points().OrderByDescending(p => p.Z).First().Z;

            // // code for when debugging the function.
            // var envelope = MakeEnvelope();
            // var topside = MakeTopside();
            // var underside = MakeUnderside();
            // var underBoundary = Polygon.Rectangle(20.0, 20.0);
            // var elevation = 10.0;
            // var highPoint = 15.0;
            // var area = 100.0;

            var roof =
                new Roof(
                    Envelope,
                    topSide,
                    underSide,
                    underBoundary,
                    elevation,
                    highPoint,
                    input.Thickness,
                    area,
                    new Transform(),
                    BuiltInMaterials.Concrete,
                    null, false, Guid.NewGuid(), "Roof");
            var output = new RoofBySketchOutputs(area);


            output.Model.AddElement(new MeshElement(Envelope, BuiltInMaterials.Concrete));
            output.Model.AddElement(roof);
            return(output);
        }