由于现在API没有提供此类的判断。因此,只能我们自己去封装一个方法去使用。
先上代码后讲解,Just Do It!!!
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;
}
用的是几何的线相交的知识,通过以目标点往x轴一个方向做延长线,再判断与这一个闭合轮廓的线相交的情况,通过相交点的数量来最终得出是否在这个闭合轮廓内。下面附上两张图,大家可以理解了。
交点有两个,和2取余数等于0,因此判断为外面。
交点有三个,因此,在轮廓里面。
最终结论是,当交点数为奇数时,说明点在这个轮廓内。这里有需要注意的地方是,这一条线必须是完全穿过这个轮廓的,而且在revit中得到的线不是一定在同一个平面中,因此我在方法中用了SetZ()方法,是把线放到同一个平面上,是一个自己封装的方法,大家可以自己封装一个就好。如果确定在同一平面上那就可以不用封装这一个方法。这就是这次的分享,谢谢大家。有什么疑问和问题可以直接私信我,我看到会回复的。