235 lines
8.1 KiB
C#
235 lines
8.1 KiB
C#
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
|
||
{
|
||
/// <summary>
|
||
/// 坐标点去重
|
||
/// </summary>
|
||
/// <param name="xyzs"></param>
|
||
/// <returns></returns>
|
||
public static List<XYZ> DeWeighting(this List<XYZ> 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);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 排序
|
||
/// ps:顺时针或者逆时针,点集合中找到最大的轮廓
|
||
/// </summary>
|
||
/// <param name="points"></param>
|
||
public static void ClockwiseSortPoints(List<XYZ> 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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 判断两点绕中心点的顺逆时针方向
|
||
/// 若点a大于点b,即点a在点b顺时针方向,返回true,否则返回false
|
||
/// </summary>
|
||
/// <param name="a"></param>
|
||
/// <param name="b"></param>
|
||
/// <param name="center"></param>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 判断点是否在轮廓内
|
||
/// </summary>
|
||
/// <param name="TargetPoint"></param>
|
||
/// <param name="xYZ">目标延长点</param>
|
||
/// <param name="lines"></param>
|
||
/// <returns></returns>
|
||
public static bool IsInsideOutline(this XYZ TargetPoint, XYZ xYZ, List<Line> 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;
|
||
}
|
||
/// <summary>
|
||
/// 判断点是否在封闭轮廓内
|
||
/// </summary>
|
||
/// <param name="TargetPoint"></param>
|
||
/// <param name="lines"></param>
|
||
/// <returns></returns>
|
||
public static bool IsInsideOutline(this XYZ TargetPoint, List<Line> 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;
|
||
}
|
||
/// <summary>
|
||
/// 英尺转毫米
|
||
/// </summary>
|
||
/// <param name="b"></param>
|
||
/// <returns></returns>
|
||
public static double ToMM(this double b)
|
||
{
|
||
return UnitUtils.Convert(b, DisplayUnitType.DUT_DECIMAL_FEET, DisplayUnitType.DUT_MILLIMETERS);
|
||
}
|
||
/// <summary>
|
||
/// 毫米转英尺
|
||
/// </summary>
|
||
/// <param name="b"></param>
|
||
/// <returns></returns>
|
||
public static double ToFeet<T>(this T b) where T : struct
|
||
{
|
||
double.TryParse(b.ToString(), out var d);
|
||
return UnitUtils.Convert(d, DisplayUnitType.DUT_MILLIMETERS, DisplayUnitType.DUT_DECIMAL_FEET);
|
||
}
|
||
/// <summary>
|
||
/// 平方英尺转平方米
|
||
/// </summary>
|
||
/// <param name="b"></param>
|
||
/// <returns></returns>
|
||
public static double ToSquareMeters(this double b)
|
||
{
|
||
return UnitUtils.Convert(b, DisplayUnitType.DUT_SQUARE_FEET, DisplayUnitType.DUT_SQUARE_METERS);
|
||
}
|
||
/// <summary>
|
||
/// 平方米转平方英尺
|
||
/// </summary>
|
||
/// <param name="b"></param>
|
||
/// <returns></returns>
|
||
public static double ToSquareFeet(this double b)
|
||
{
|
||
return UnitUtils.Convert(b, DisplayUnitType.DUT_SQUARE_METERS, DisplayUnitType.DUT_SQUARE_FEET);
|
||
}
|
||
/// <summary>
|
||
/// 设置Z轴
|
||
/// </summary>
|
||
/// <param name="sPoint"></param>
|
||
/// <param name="z"></param>
|
||
/// <returns></returns>
|
||
public static XYZ SetZ(this XYZ sPoint, double z = 0)
|
||
{
|
||
return new XYZ(sPoint.X, sPoint.Y, z);
|
||
}
|
||
/// <summary>
|
||
/// 转弧度
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="t"></param>
|
||
/// <returns></returns>
|
||
public static double ToRad<T>(this T t) where T : struct
|
||
{
|
||
return double.Parse(t.ToString()) * Math.PI / 180;
|
||
}
|
||
}
|
||
}
|