using Autodesk.Revit.DB; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace GraphicsStudy { public static class XYZMethod { /// /// 坐标点去重 /// /// /// public static List DeWeighting(this List xyzs) { for (int i = 0; i < xyzs.Count; i++) { for (int j = 0; j < xyzs.Count; j++) { if (i == j) continue; if (Comparison(xyzs[i], xyzs[j], 4, false)) { xyzs.RemoveAt(j); j--; } } } return xyzs; } public static bool Comparison(XYZ xyz1, XYZ xyz2, int v, bool is3d) { double x1 = xyz1.X; double y1 = xyz1.Y; double x2 = xyz2.X; double y2 = xyz2.Y; if (is3d) { double z1 = xyz1.Z; double z2 = xyz2.Z; return Math.Round(x1, v) == Math.Round(x2, v) && Math.Round(y1, v) == Math.Round(y2, v) && Math.Round(z1, v) == Math.Round(z2, v); } else { return Math.Round(x1, v) == Math.Round(x2, v) && Math.Round(y1, v) == Math.Round(y2, v); } } /// /// 排序 /// ps:顺时针或者逆时针,点集合中找到最大的轮廓 /// /// public static void ClockwiseSortPoints(List points) { //计算重心 XYZ center = new XYZ(); double X = 0, Y = 0; for (int i = 0; i < points.Count; i++) { X += points[i].X; Y += points[i].Y; } double centerX = (int)X / points.Count; double centerY = (int)Y / points.Count; center = new XYZ(centerX, centerY, 0); //冒泡排序 for (int i = 0; i < points.Count - 1; i++) { for (int j = 0; j < points.Count - i - 1; j++) { if (PointCmp(points[j], points[j + 1], center)) { XYZ tmp = points[j]; points[j] = points[j + 1]; points[j + 1] = tmp; } } } } /// /// 判断两点绕中心点的顺逆时针方向 /// 若点a大于点b,即点a在点b顺时针方向,返回true,否则返回false /// /// /// /// public static bool PointCmp(XYZ a, XYZ b, XYZ center) { if (a.X >= 0 && b.X < 0) return true; if (a.X == 0 && b.X == 0) return a.Y > b.Y; //向量OA和向量OB的叉积 int det = Convert.ToInt32((a.X - center.X) * (b.Y - center.Y) - (b.X - center.X) * (a.Y - center.Y)); if (det < 0) return true; if (det > 0) return false; //向量OA和向量OB共线,以距离判断大小 double d1 = (a.X - center.X) * (a.X - center.X) + (a.Y - center.Y) * (a.Y - center.Y); double d2 = (b.X - center.X) * (b.X - center.Y) + (b.Y - center.Y) * (b.Y - center.Y); return d1 > d2; } //判断点是否在线上 public static bool IsOnLine(this XYZ xYZ, Line l) { bool result = false; XYZ start = l.GetEndPoint(0); XYZ end = l.GetEndPoint(1); double startDistance = xYZ.SetZ().DistanceTo(start.SetZ()); double endDistance = xYZ.SetZ().DistanceTo(end.SetZ()); if (startDistance + endDistance < l.Length + 5.ToFeet()) { result = true; } return result; } /// /// 判断点是否在轮廓内 /// /// /// 目标延长点 /// /// public static bool IsInsideOutline(this XYZ TargetPoint, XYZ xYZ, List lines) { bool result = true; int insertCount = 0; Line rayLine = Line.CreateBound(TargetPoint, xYZ).SetZ(0); foreach (var areaLine in lines) { var interResult = areaLine.SetZ().Intersect(rayLine, out IntersectionResultArray resultArray); var insPoint = resultArray?.get_Item(0); if (insPoint != null) { insertCount++; } } //如果次数为偶数就在外面,次数为奇数就在里面 if (insertCount % 2 == 0)//偶数 { return result = false; } return result; } /// /// 判断点是否在封闭轮廓内 /// /// /// /// public static bool IsInsideOutline(this XYZ TargetPoint, List lines) { bool result = true; int insertCount = 0; Line rayLine = Line.CreateBound(TargetPoint, TargetPoint.Add(XYZ.BasisX * 1000)).SetZ(0); foreach (var areaLine in lines) { var interResult = areaLine.SetZ().Intersect(rayLine, out IntersectionResultArray resultArray); var insPoint = resultArray?.get_Item(0); if (insPoint != null) { insertCount++; } } //如果次数为偶数就在外面,次数为奇数就在里面 if (insertCount % 2 == 0)//偶数 { return result = false; } return result; } /// /// 英尺转毫米 /// /// /// public static double ToMM(this double b) { return UnitUtils.Convert(b, DisplayUnitType.DUT_DECIMAL_FEET, DisplayUnitType.DUT_MILLIMETERS); } /// /// 毫米转英尺 /// /// /// public static double ToFeet(this T b) where T : struct { double.TryParse(b.ToString(), out var d); return UnitUtils.Convert(d, DisplayUnitType.DUT_MILLIMETERS, DisplayUnitType.DUT_DECIMAL_FEET); } /// /// 平方英尺转平方米 /// /// /// public static double ToSquareMeters(this double b) { return UnitUtils.Convert(b, DisplayUnitType.DUT_SQUARE_FEET, DisplayUnitType.DUT_SQUARE_METERS); } /// /// 平方米转平方英尺 /// /// /// public static double ToSquareFeet(this double b) { return UnitUtils.Convert(b, DisplayUnitType.DUT_SQUARE_METERS, DisplayUnitType.DUT_SQUARE_FEET); } /// /// 设置Z轴 /// /// /// /// public static XYZ SetZ(this XYZ sPoint, double z = 0) { return new XYZ(sPoint.X, sPoint.Y, z); } /// /// 转弧度 /// /// /// /// public static double ToRad(this T t) where T : struct { return double.Parse(t.ToString()) * Math.PI / 180; } } }