using Autodesk.Revit.DB; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using FWindSoft.SystemExtensions; namespace FWindSoft.Revit { /// /// 点的扩展相关 /// public static class XYZExtension { /// /// 向量是否平行 /// /// /// /// public static bool IsParallel(this XYZ baseDirection, XYZ direction) { return baseDirection.CrossProduct(direction).GetLength().IsZero(); } /// /// 向量是否垂直 /// /// /// /// public static bool IsVertical(this XYZ baseDirection, XYZ direction) { return baseDirection.DotProduct(direction).IsZero(); } /// /// 判断向量是否同向 /// /// /// /// public static bool IsSameDirection(this XYZ firstDirection, XYZ secondDirection) { if(firstDirection.IsParallel(secondDirection)) { return firstDirection.DotProduct(secondDirection).MoreEqual(0); } return false; } /// /// 向量方向相反 /// /// /// /// public static bool IsOppositeDirection(this XYZ firstDirection, XYZ secondDirection) { if (firstDirection.IsParallel(secondDirection)) { return secondDirection.DotProduct(secondDirection).LessEqual(0); } return false; } /// /// 偏移指定向量 /// /// /// /// public static XYZ Offset(this XYZ origin,XYZ vector) { return origin + vector; } /// /// 判断两个点是否重合 /// /// /// /// /// public static bool IsEqual(this XYZ first, XYZ second, double tolerance) { return first.X.IsEqual(second.X, tolerance) && first.Y.IsEqual(second.Y, tolerance) && first.Z.IsEqual(second.Z, tolerance); } /// /// 判断两个点是否重合 /// /// /// /// public static bool IsEqual(this XYZ first, XYZ second) { return first.X.IsEqual(second.X, DoubleExtensions.Precision) && first.Y.IsEqual(second.Y, DoubleExtensions.Precision) && first.Z.IsEqual(second.Z, DoubleExtensions.Precision); } /// /// 判断两个点是否重合 /// /// /// /// public static bool IsEqual2(this XYZ first, XYZ second) { return first.X.IsEqual(second.X, DoubleExtensions.Precision) && first.Y.IsEqual(second.Y, DoubleExtensions.Precision); } /// /// 按指定方向的轴,在原点位置旋转向量 /// /// /// /// /// public static XYZ RotateVector(this XYZ vec, XYZ axis, double angle) { var transform = Transform.CreateRotationAtPoint(axis, angle, XYZ.Zero); return transform.OfVector(vec); } /// /// 计算点到指定平面的投影 /// /// /// /// /// public static XYZ GetPlaneProject(this XYZ input, XYZ normal, XYZ origin) { if (!normal.IsUnitLength()) { normal = normal.Normalize(); } return input + normal * origin.Subtract(input).DotProduct(normal); } /// /// 计算点到指定直线的投影 /// /// /// /// /// public static XYZ GetLineProject(this XYZ input, XYZ direction, XYZ origin) { if (!direction.IsUnitLength()) { direction = direction.Normalize(); } return origin + direction * input.Subtract(origin).DotProduct(direction); } /// /// 获取任意一个与input垂直的向量 /// /// /// public static XYZ GetAnyVerticalVector(this XYZ input) { if (!XYZ.BasisX.IsParallel(input)) { return input.CrossProduct(XYZ.BasisX).Normalize(); } else { return input.CrossProduct(XYZ.BasisY).Normalize(); } } /// /// 判断点的投影是否在直线段内 /// /// /// /// public static bool IsProjectInLine(this XYZ input, Line line) { if (!line.IsBound) { return true; } var project =line.GetProject(input); return line.InCurve(project); } /// /// 使用Input在line上的投影点分割指定直线 /// /// /// /// 如果点在线外侧,则返回一个较大的向量,另一个去掉。如果在线上,则返回两个向量 public static List SplitVector(this XYZ input, Line line) { if (!line.IsBound) { return new List() { line.Direction * Double.MaxValue, line.Direction * Double.MaxValue, }; } var project = line.GetProject(input); var startVector = line.StartPoint() - project; var endVector = line.EndPoint() - project; if (startVector.DotProduct(endVector).MoreEqual(0)) { //两个向量同向,去较大的返回 if (startVector.GetLength().More(endVector.GetLength())) { return new List() { startVector }; } else { return new List() { endVector }; } } return new List() { startVector, endVector }; } } }