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;
}
}
}