Revit SDK 介绍:RayTraceBounce 光线反弹

前言

这个例子模拟光线反弹。

内容

通过修改参数,从(0,0,0)点向(1,0,0)方向射出光线,经过若干次反弹之后的结果。如图所示:
Revit SDK 介绍:RayTraceBounce 光线反弹_第1张图片

在Revit API 中,用 ReferenceIntersector::Find 来计算射线上相交的几何。

核心逻辑,简化了代码,只保留重要部分:

// 从起点 startpt 出发,做 rayLimit 次射线
Autodesk.Revit.DB.XYZ startpt = m_origin;
for (int ctr = 1; ctr <= rayLimit; ctr++){
   // 通过 ReferenceIntersector::Find 查找相交几何
   ReferenceIntersector referenceIntersector = new ReferenceIntersector(m_view);
   IList<ReferenceWithContext> references = referenceIntersector.Find(startpt, m_direction);
   m_rClosest = null;
   // 遍历找到最近的几何,获取相交点
   FindClosestReference(references);
   Reference reference = m_rClosest.GetReference();
   Element referenceElement = m_doc.GetElement(reference);
   GeometryObject referenceObject = referenceElement.GetGeometryObjectFromReference(reference);
   Autodesk.Revit.DB.XYZ endpt = reference.GlobalPoint;
   // 绘制一条线段表示光线
   MakeLine(startpt, endpt, m_direction, "bounce");
   // 计算反射光线的防线
   m_face = referenceObject as Face;
   Autodesk.Revit.DB.UV endptUV = reference.UVPoint;
   Autodesk.Revit.DB.XYZ FaceNormal = m_face.ComputeDerivatives(endptUV).BasisZ;  // face normal where ray hits
   FaceNormal = m_rClosest.GetInstanceTransform().OfVector(FaceNormal); // transformation to get it in terms of document coordinates instead of the parent symbol
   Autodesk.Revit.DB.XYZ directionMirrored = m_direction - 2 * m_direction.DotProduct(FaceNormal) * FaceNormal; //http://www.fvastro.org/presentations/ray_tracing.htm
   m_direction = directionMirrored; // get ready to shoot the next ray
   // 重置光线起点
   startpt = endpt;
}

FindClosetReference 核心逻辑:

double face_prox = Double.PositiveInfinity;
double edge_prox = Double.PositiveInfinity;
foreach (ReferenceWithContext r in references){
   Reference reference = r.GetReference();
   Element referenceElement = m_doc.GetElement(reference);
   GeometryObject referenceGeometryObject = referenceElement.GetGeometryObjectFromReference(reference);
   m_face = null;
   m_face = referenceGeometryObject as Face;
   Edge edge = null;
   edge = referenceGeometryObject as Edge;
   if (m_face != null){
      if ((r.Proximity < face_prox) && (r.Proximity > epsilon)){
            m_rClosest = r;
            face_prox = Math.Abs(r.Proximity);
      }
   } 
}

你可能感兴趣的:(C#)