/*------------------------------------------------------------------------- * 功能描述:CurveExtension * 作者:xulisong * 创建时间: 2019/6/26 14:14:27 * 版本号:v1.0 * -------------------------------------------------------------------------*/ using Autodesk.Revit.DB; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using SAGA.RevitUtils.Extends; namespace RevitToJBim.Extension { public static class CurveExtension { /// <summary> /// 获取curve偏移后的Polygon信息 /// </summary> /// <param name="curve"></param> /// <param name="normal"></param> /// <param name="offset"></param> /// <returns></returns> public static List<XYZ> GetCurvePolygon(this Curve curve, XYZ normal, double offset) { List<XYZ> xyzs = new List<XYZ>(); XYZ referenceDirection = normal; if (curve.IsLine()) { referenceDirection = normal.CrossProduct((curve as Line).Direction); } #region 构建围护线 //从curve1.StartPoint()开始的可以顺序连接的线结构 var curve1 = curve.CreateOffset(offset, referenceDirection); var curve2 = curve.CreateOffset(-offset, referenceDirection); var line1 = Line.CreateBound(curve1.EndPoint(), curve2.EndPoint()); var line2 = Line.CreateBound(curve2.StartPoint(), curve1.StartPoint()); //curve2调转方向 curve2 = curve2.CreateReversed(); List<Curve> curves = new List<Curve>(); curves.Add(curve1); curves.Add(line1); curves.Add(curve2); curves.Add(line2); foreach (Curve useCurve in curves) { var points = useCurve.Tessellate(); points.RemoveAt(points.Count - 1); xyzs.AddRange(points); } #endregion #region 逆时针顺序转化 /* * //将线结构整理成逆时针形式; * 如果curve是弧线则使用开始,中间,结束三个点判断 * 如果curve是直线,则使用开始,结束,curve2的开始三个点判断; * * 也可以直接使用上面的的点集合取出三个点进行判断 */ List<XYZ> decisionXyzs = new List<XYZ>(); if (curve1.IsLine()) { decisionXyzs.Add(curve1.StartPoint()); decisionXyzs.Add(curve1.EndPoint()); decisionXyzs.Add(curve2.StartPoint()); } else if(curve1.IsArc()) { //找半径大的弧 var useCurve = (curve1 as Arc).Radius > (curve2 as Arc).Radius ? curve1 : curve2; decisionXyzs.Add(useCurve.StartPoint()); decisionXyzs.Add(useCurve.MiddlePoint()); decisionXyzs.Add(useCurve.EndPoint()); } if (decisionXyzs.Any()) { var useDirection = (decisionXyzs[1] - decisionXyzs[0]).CrossProduct(decisionXyzs[2] - decisionXyzs[0]); var isAnticlockwise = useDirection.IsSameDirection(normal); if (!isAnticlockwise) { xyzs.Reverse(); } } #endregion return xyzs; } } }