using Autodesk.Revit.DB;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FWindSoft.SystemExtensions;
namespace FWindSoft.Revit
{
///
/// 点的扩展相关
///
public static class XYZExtension
{
///
/// 向量是否平行
///
///
///
///
public static bool IsParallel(this XYZ baseDirection, XYZ direction)
{
return baseDirection.CrossProduct(direction).GetLength().IsZero();
}
///
/// 向量是否垂直
///
///
///
///
public static bool IsVertical(this XYZ baseDirection, XYZ direction)
{
return baseDirection.DotProduct(direction).IsZero();
}
///
/// 判断向量是否同向
///
///
///
///
public static bool IsSameDirection(this XYZ firstDirection, XYZ secondDirection)
{
if(firstDirection.IsParallel(secondDirection))
{
return firstDirection.DotProduct(secondDirection).MoreEqual(0);
}
return false;
}
///
/// 向量方向相反
///
///
///
///
public static bool IsOppositeDirection(this XYZ firstDirection, XYZ secondDirection)
{
if (firstDirection.IsParallel(secondDirection))
{
return secondDirection.DotProduct(secondDirection).LessEqual(0);
}
return false;
}
///
/// 偏移指定向量
///
///
///
///
public static XYZ Offset(this XYZ origin,XYZ vector)
{
return origin + vector;
}
///
/// 判断两个点是否重合
///
///
///
///
///
public static bool IsEqual(this XYZ first, XYZ second, double tolerance)
{
return first.X.IsEqual(second.X, tolerance)
&& first.Y.IsEqual(second.Y, tolerance)
&& first.Z.IsEqual(second.Z, tolerance);
}
///
/// 判断两个点是否重合
///
///
///
///
public static bool IsEqual(this XYZ first, XYZ second)
{
return first.X.IsEqual(second.X, DoubleExtensions.Precision)
&& first.Y.IsEqual(second.Y, DoubleExtensions.Precision)
&& first.Z.IsEqual(second.Z, DoubleExtensions.Precision);
}
///
/// 判断两个点是否重合
///
///
///
///
public static bool IsEqual2(this XYZ first, XYZ second)
{
return first.X.IsEqual(second.X, DoubleExtensions.Precision)
&& first.Y.IsEqual(second.Y, DoubleExtensions.Precision);
}
///
/// 按指定方向的轴,在原点位置旋转向量
///
///
///
///
///
public static XYZ RotateVector(this XYZ vec, XYZ axis, double angle)
{
var transform = Transform.CreateRotationAtPoint(axis, angle, XYZ.Zero);
return transform.OfVector(vec);
}
///
/// 计算点到指定平面的投影
///
///
///
///
///
public static XYZ GetPlaneProject(this XYZ input, XYZ normal, XYZ origin)
{
if (!normal.IsUnitLength())
{
normal = normal.Normalize();
}
return input + normal * origin.Subtract(input).DotProduct(normal);
}
///
/// 计算点到指定直线的投影
///
///
///
///
///
public static XYZ GetLineProject(this XYZ input, XYZ direction, XYZ origin)
{
if (!direction.IsUnitLength())
{
direction = direction.Normalize();
}
return origin + direction * input.Subtract(origin).DotProduct(direction);
}
///
/// 获取任意一个与input垂直的向量
///
///
///
public static XYZ GetAnyVerticalVector(this XYZ input)
{
if (!XYZ.BasisX.IsParallel(input))
{
return input.CrossProduct(XYZ.BasisX).Normalize();
}
else
{
return input.CrossProduct(XYZ.BasisY).Normalize();
}
}
///
/// 判断点的投影是否在直线段内
///
///
///
///
public static bool IsProjectInLine(this XYZ input, Line line)
{
if (!line.IsBound)
{
return true;
}
var project =line.GetProject(input);
return line.InCurve(project);
}
///
/// 使用Input在line上的投影点分割指定直线
///
///
///
/// 如果点在线外侧,则返回一个较大的向量,另一个去掉。如果在线上,则返回两个向量
public static List SplitVector(this XYZ input, Line line)
{
if (!line.IsBound)
{
return new List() { line.Direction * Double.MaxValue, line.Direction * Double.MaxValue, };
}
var project = line.GetProject(input);
var startVector = line.StartPoint() - project;
var endVector = line.EndPoint() - project;
if (startVector.DotProduct(endVector).MoreEqual(0))
{
//两个向量同向,去较大的返回
if (startVector.GetLength().More(endVector.GetLength()))
{
return new List() { startVector };
}
else
{
return new List() { endVector };
}
}
return new List() { startVector, endVector };
}
}
}