我正在使用Revit宏来获取部件(地板部件)的中心点,以检查它是在室内还是空间内。
我无法得到很多BoundingBox
对象,这个对象在部件之外给我一个点,所以我尝试使用Geometry
元素内部面来获取网格顶点但是我卡住计算中间点。
我正在使用下面的代码段中显示的一个相当天真的算法,但是它给了我错误的结果,因为它似乎受到最小/最大变量的初始默认值的影响。
有什么建议吗?
PS:DebugTools是我自己的自定义助手类。
public void ZoneDetect()
{
Document doc = this.ActiveUIDocument.Document;
using (Transaction t = new Transaction(doc,"Set Rooms By Region"))
{
t.Start();
FilteredElementCollector fec =
new FilteredElementCollector(doc)
.OfClass(typeof(Part))
.OfCategory(BuiltInCategory.OST_Parts)
.Cast<Part>();
foreach (Part p in fec)
{
Options op = new Options();
op.View=doc.ActiveView;
op.ComputeReferences=true;
GeometryElement gm=p.get_Geometry(op);
Solid so = gm.First() as Solid;
PlanarFace fc=so.Faces.get_Item(0) as PlanarFace;
foreach (PlanarFace f in so.Faces)
{
if (f.Normal == new XYZ(0,0,-1)) fc=f;
}
XYZ max = new XYZ();
XYZ min = new XYZ();
int no = 0;
foreach (XYZ vx in fc.Triangulate().Vertices)
{
// Just for debugging
DebugTools.DrawModelTick(vx,doc,"Max");
doc.Regenerate();
TaskDialog.Show("Point:"+no.ToString(),vx.ToString());
no++;
//Comparing points
if (vx.X>max.X) max=new XYZ (vx.X,max.Y,0);
if (vx.Y>max.Y) max=new XYZ (max.X,vx.Y,0);
if (vx.X<min.X) min=new XYZ (vx.X,min.Y,0);
if (vx.Y<min.Y) min=new XYZ (min.X,vx.Y,0);
}
XYZ mid = new XYZ(max.X-min.X,max.Y-min.Y,0);
DebugTools.DrawModelTick(mid,doc,"Mid");
DebugTools.DrawModelTick(max,doc,"Max");
DebugTools.DrawModelTick(min,doc,"Min");
}
t.Commit();
}
}
答案 0 :(得分:0)
看起来你正在寻找多边形的重心。可以在此处找到一种算法:Center of gravity of a polygon
获得Face
对象后,可以枚举其边缘以接收顶点列表。使用脸部EdgeLoops
中最长的一个。收集所有点并确保它们的顺序正确(边缘的起点和终点可能需要交换)。
答案 1 :(得分:0)
XYZ midSum = Max + Min;
XYZ mid = new XYZ(midSum.X/2 , midSum.Y/2,0);
我将使用你提供的链接来研究它,但是现在我将完成我的任务。
非常感谢