ComputerGraphics/20210129/zzx-20210129作业/Method/XYZMethod.cs

235 lines
8.1 KiB
C#
Raw Normal View History

2021-02-25 15:53:31 +08:00
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;
}
}
}