using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
namespace uBIM_EarthTools
{
class Common
{
///
/// 三角剖分
///
/// 钻孔列表
/// 排除过长三角形边边长
/// 钻孔编号索引
public static List Delaunay(List boreholeList, double tolerance)
{
List list = new List();
List xyzList = boreholeList.Select(x => new XYZ(x.ValueList[0].Point.X, x.ValueList[0].Point.Y, 0)).ToList();
TriangleNet.Mesh mesh = new TriangleNet.Mesh();
TriangleNet.Geometry.InputGeometry inputGeometry = new TriangleNet.Geometry.InputGeometry(boreholeList.Count);
foreach (XYZ item in xyzList)
{
inputGeometry.AddPoint(item.X, item.Y);
}
mesh.Triangulate(inputGeometry);
foreach (TriangleNet.Data.Triangle item in mesh.Triangles)
{
if (IsCollinear(item) || MaxEdge(item) > tolerance)
continue;
int[] index = new int[3];
index[0] = item.P0;
index[1] = item.P1;
index[2] = item.P2;
list.Add(index);
}
return list;
}
///
/// 判断三角形三点是否接近共线
///
///
///
public static bool IsCollinear(TriangleNet.Data.Triangle triangle)
{
XYZ p0 = new XYZ(triangle.GetVertex(0).X, triangle.GetVertex(0).Y, 0);
XYZ p1 = new XYZ(triangle.GetVertex(1).X, triangle.GetVertex(1).Y, 0);
XYZ p2 = new XYZ(triangle.GetVertex(2).X, triangle.GetVertex(2).Y, 0);
Line line1 = Line.CreateUnbound(p0, p1 - p0);
Line line2 = Line.CreateUnbound(p1, p2 - p1);
Line line3 = Line.CreateUnbound(p2, p0 - p2);
double d1 = line1.Project(p2).Distance / p0.DistanceTo(p1);
double d2 = line2.Project(p0).Distance / p1.DistanceTo(p2);
double d3 = line3.Project(p1).Distance / p2.DistanceTo(p0);
if (Math.Min(Math.Min(d1, d2), d3) < 0.02)
return true;
else
return false;
}
///
/// 三角形最长边长度
///
///
///
public static double MaxEdge(TriangleNet.Data.Triangle triangle)
{
XYZ p0 = new XYZ(triangle.GetVertex(0).X, triangle.GetVertex(0).Y, 0);
XYZ p1 = new XYZ(triangle.GetVertex(1).X, triangle.GetVertex(1).Y, 0);
XYZ p2 = new XYZ(triangle.GetVertex(2).X, triangle.GetVertex(2).Y, 0);
return Math.Max(Math.Max(p0.DistanceTo(p1), p1.DistanceTo(p2)), p0.DistanceTo(p2));
}
public static int IsTypeEquals(List boreholeList)
{
List typeList = boreholeList.Select(x => x.CurrentType).ToList();
if (typeList[0].Equals(typeList[1]) && typeList[0].Equals(typeList[2]))
return 1;
else if (typeList[0].Equals(typeList[1]) && !typeList[0].Equals(typeList[2]))
return 2;
else if (typeList[0].Equals(typeList[2]) && !typeList[0].Equals(typeList[1]))
return 3;
else if (typeList[1].Equals(typeList[2]) && !typeList[0].Equals(typeList[2]))
return 4;
else
return 0;
}
///
/// 点1在XY平面(忽略Z值)绕中心点逆时针旋转到点2的弧度[0,2Π]
///
///
///
///
///
public static double AngleOfThreePoint(XYZ firstPoint, XYZ centerPoint, XYZ lastPoint)
{
XYZ vector1 = firstPoint - centerPoint;
XYZ vector2 = lastPoint - centerPoint;
double angle = Math.Atan2(vector2.Y, vector2.X) - Math.Atan2(vector1.Y, vector1.X);
if (angle < 0)
{
return angle += Math.PI * 2;
}
else if (angle == 0)
{
return angle = Math.PI * 2;
}
else
return angle;
}
public static double PointToLinePedal(XYZ lineFirstPoint, XYZ lineSecondPoint, XYZ point)
{
double A = lineSecondPoint.Y - lineFirstPoint.Y;
double B= lineSecondPoint.X - lineFirstPoint.X;
double C = lineSecondPoint.X * lineFirstPoint.Y - lineFirstPoint.X*lineSecondPoint.Y;
return (A * point.X + B * point.Y + C) / Math.Sqrt(A * A + B * B);
}
public static double PointToLineDistance(XYZ lineFirstPoint, XYZ lineSecondPoint, XYZ point)
{
double A = lineSecondPoint.Y - lineFirstPoint.Y;
double B = lineSecondPoint.X - lineFirstPoint.X;
double C = lineSecondPoint.X * lineFirstPoint.Y - lineFirstPoint.X * lineSecondPoint.Y;
return (A * point.X + B * point.Y + C) / Math.Sqrt(A * A + B * B);
}
///
/// 创建材质
///
/// Autodesk.Revit.DB.Document
/// 材质名称
///
public static Material CreateMaterial(Document doc, string name)
{
Material material = null;
ElementId materialId = Material.Create(doc, name);
material = doc.GetElement(materialId) as Material;
StructuralAsset strucAsset = new StructuralAsset("uBIM", StructuralAssetClass.Undefined);
strucAsset.Behavior = StructuralBehavior.Isotropic;
PropertySetElement propertySet = PropertySetElement.Create(doc, strucAsset);
propertySet.get_Parameter(BuiltInParameter.PROPERTY_SET_NAME).Set(name);
propertySet.get_Parameter(BuiltInParameter.PHY_MATERIAL_PARAM_CLASS).Set((int)StructuralMaterialType.Undefined);
propertySet.get_Parameter(BuiltInParameter.PHY_MATERIAL_PARAM_UNIT_WEIGHT).Set(232);
material.SetMaterialAspectByPropertySet(Autodesk.Revit.DB.MaterialAspect.Structural, propertySet.Id);
return material;
}
///
/// 创建材质
///
/// Autodesk.Revit.DB.Document
/// 材质名称列表
///
public static IList CreateMaterialElements(Document doc, List materialNameList)
{
Transaction transaction = new Transaction(doc);
IList mtset = new FilteredElementCollector(doc)
.WherePasses(new ElementClassFilter(typeof(Material))).ToElements();
transaction.Start("Create Material");
foreach (string type in materialNameList)
{
if (mtset.Select(x => x.Name).ToList().Contains(type))
continue;
else
{
Material material = CreateMaterial(doc, type);
Random randomNumFirst = new Random((int)DateTime.Now.Ticks);
System.Threading.Thread.Sleep(randomNumFirst.Next(50));
Random randomNumSencond = new Random((int)DateTime.Now.Ticks);
int intRed = randomNumFirst.Next(256);
int intGreen = randomNumSencond.Next(256);
int intBlue = (intRed + intGreen > 400) ? 0 : 400 - intRed - intGreen;
intBlue = (intBlue > 255) ? 255 : intBlue;
material.Color = new Color((byte)intRed, (byte)intGreen, (byte)intBlue);
material.MaterialClass = "地质材质";
mtset.Add(material);
}
}
transaction.Commit();
return mtset;
}
///
/// Transaction设置
///
/// Transaction
public static void SetTransaction(Transaction trans)
{
FailureHandlingOptions failureHandlingOptions = trans.GetFailureHandlingOptions();
FailureHandler failureHandler = new FailureHandler();
failureHandlingOptions.SetFailuresPreprocessor(failureHandler);
failureHandlingOptions.SetClearAfterRollback(true);
trans.SetFailureHandlingOptions(failureHandlingOptions);
}
///
/// 求某点处的textnote,在textnote_list范围内
///
/// 寻找点
/// TextNote列表
/// 误差范围,单位mm
/// textnote
public static TextNote Textnote_At_Point(XYZ p, List textnoteList, double tolerance)
{
TextNote tn = null;
XYZ newXyz = new XYZ(p.X, p.Y, textnoteList[0].Coord.Z);
foreach (TextNote tntmp in textnoteList)
{
if (Math.Round(tntmp.Coord.DistanceTo(newXyz), 5) < (tolerance / 304.8))
{
tn = tntmp;
}
}
return tn;
}
public static void Swap(ref T x, ref T y)
{
T temp = x;
x = y;
y = temp;
}
}
}