// 已知曲线(直线、圆曲线)和其上一点距曲线起点的沿线距离,
 // 计算该点的坐标, 以及该点切向的垂直方向向量lateral
 public static (XbimPoint3D pt, XbimVector3D vec) GetPointOnCurve(IIfcCurveSegment2D c, double dist)
 {
     if (c is IIfcLineSegment2D line)
     {
         return(GetPointOnCurve(line, dist));
     }
     if (c is IIfcCircularArcSegment2D arc)
     {
         return(GetPointOnCurve(arc, dist));
     }
     throw new NotImplementedException("Transition curve not supported for now");
 }
        public static (XbimPoint3D pt, XbimVector3D vec) GetPointByDistAlong(IItemSet <IIfcAlignment2DHorizontalSegment> horSegs, double dist)
        {
            int i = 0;
            IIfcCurveSegment2D cur = null;

            for (; i < horSegs.Count; i++)
            {
                cur = horSegs[i].CurveGeometry;
                if (dist > cur.SegmentLength + Tolerance)
                {
                    dist -= cur.SegmentLength;
                }
                else
                {
                    break;
                }
            }
            if (cur == null)
            {
                throw new ArgumentNullException("horSegs");
            }
            return(GetPointOnCurve(cur, dist));
        }
        public static XbimPoint3D GetPlacementPoint(IIfcCurveSegment2D c, double dist,
                                                    double verticalOffset, double lateraloffset)
        {
            XbimPoint3D Point3D = new XbimPoint3D();

            if (c is IIfcLineSegment2D line)
            {
                (XbimPoint3D pointOnCurve, XbimVector3D vecOnCurve) = GetPointOnCurve(line, dist);
                var zAxis  = new XbimVector3D(0, 0, 1);
                var vecoff = vecOnCurve.CrossProduct(zAxis);
                Point3D = (pointOnCurve + vecoff * lateraloffset + zAxis * verticalOffset);
                //return Point3D;
            }
            if (c is IIfcCircularArcSegment2D arc)
            {
                (XbimPoint3D pointOnCurve, XbimVector3D vecOnCurve) = GetPointOnCurve(arc, dist);
                var isCCW        = (bool)arc.IsCCW.Value;
                var zAxis        = new XbimVector3D(0, 0, 1);
                var start2center = isCCW ? zAxis.CrossProduct(vecOnCurve) : vecOnCurve.CrossProduct(zAxis);
                Point3D = (pointOnCurve + start2center * lateraloffset + zAxis * verticalOffset);
                //return Point3D;
            }
            return(Point3D);
        }