ComputerGraphics/20210129/zzx-20210129作业/Method/XYZMethod.cs
2021-02-25 15:53:31 +08:00

235 lines
8.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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