前言
这个例子模拟光线反弹。
内容
通过修改参数,从(0,0,0)点向(1,0,0)方向射出光线,经过若干次反弹之后的结果。如图所示:
在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 hitsFaceNormal = m_rClosest.GetInstanceTransform().OfVector(FaceNormal); // transformation to get it in terms of document coordinates instead of the parent symbolAutodesk.Revit.DB.XYZ directionMirrored = m_direction - 2 * m_direction.DotProduct(FaceNormal) * FaceNormal; //http://www.fvastro.org/presentations/ray_tracing.htmm_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);}}
}