コード例 #1
0
        /// <summary> 判断半边道路的挖填情况 </summary>
        /// <param name="center"></param>
        /// <param name="leftSide">左侧还是右侧</param>
        /// <param name="slopeFill">此侧边坡的填挖情况</param>
        /// <param name="treatmentDepth">浅挖路基的翻挖压实处理的最底部距离路面顶的深度,一般为1.5m左右</param>
        /// <param name="ground">自然地面</param>
        /// <returns>此侧路基中,需要进行翻挖压实处理的路基宽度。
        ///     当边坡为填方时(且道路中线处为挖方),此时自然地面线一般会与路面线相交,返回相交后靠近道路中线侧的挖方宽度;
        ///     如果自然地面线与路面线不相交(),则将此侧道路按全挖方考虑,且为全浅挖</returns>
        private static double HalfRoadShallowCut(SectionInfo center, bool leftSide, bool?slopeFill,
                                                 double treatmentDepth, Polyline ground)
        {
            var centerCutWidth = 0.0;

            var halfRoadWidth = leftSide
                ? center.CenterX - center.LeftRoadEdge.X
                : center.RightRoadEdge.X - center.CenterX; // 路面+路肩

            if (slopeFill == null || !slopeFill.Value)
            {
                // 说明不是填方
                centerCutWidth = halfRoadWidth;
            }
            else
            {
                // 说明中心为挖方,而边坡为填方
                var bottomPt = new Point2d(center.CenterX, center.CenterY - treatmentDepth);
                var inters   = new CurveCurveIntersector2d(ground.Get2dLinearCurve(),
                                                           new Ray2d(bottomPt, new Vector2d(leftSide ? -1 : 1, 0)));
                if (inters.NumberOfIntersectionPoints == 0)
                {
                    centerCutWidth = halfRoadWidth;
                }
                else
                {
                    centerCutWidth = Math.Abs(inters.GetIntersectionPoint(0).X - center.CenterX);
                    if (centerCutWidth > halfRoadWidth)
                    {
                        centerCutWidth = halfRoadWidth;
                    }
                }
            }
            return(centerCutWidth);
        }
コード例 #2
0
ファイル: LongitudinalSection.cs プロジェクト: sunjini/CADDev
 private void GetIntersects()
 {
     IntersPoints = new Dictionary <double, Point2d>();
     for (int i = 0; i < Intersects.NumberOfIntersectionPoints; i++)
     {
         var pt = Intersects.GetIntersectionPoint(i);
         IntersPoints.Add(pt.X, pt);
     }
 }
コード例 #3
0
        /// <summary>
        /// Расчет пересечений двух линий
        /// С учетом допусков автокада
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <param name="p4"></param>
        /// <returns></returns>
        public static Point2d?GetLinesIntersectionAcad(Point2d p1, Point2d p2, Point2d p3, Point2d p4)
        {
            Point2d?                pt          = null;
            LineSegment2d           line1       = new LineSegment2d(p1, p2);
            LineSegment2d           line2       = new LineSegment2d(p3, p4);
            CurveCurveIntersector2d intersector = new CurveCurveIntersector2d(line1, line2);

            if (intersector.NumberOfIntersectionPoints > 0)
            {
                pt = intersector.GetIntersectionPoint(0);
            }
            return(pt);
        }
コード例 #4
0
        private double?[,] GetZArray(Point2dCollection[] collections, double sizeX)
        {
            var distance    = TechProcess.Tool.Diameter / 2;
            var countX      = (int)(sizeX / StepX2) + 1;
            var zArray      = new double?[collections.Length, countX];
            var intersector = new CurveCurveIntersector2d();

            Acad.SetLimitProgressor(collections.Length);

            var rays = Enumerable.Range(0, countX).Select(p => new Ray2d(new Point2d(p * StepX2, 0), Vector2d.YAxis)).ToList();

            for (int i = 0; i < collections.Length; i++)
            {
                Acad.ReportProgressor();

                if (collections[i] == null)
                {
                    continue;
                }

                var polylene    = new PolylineCurve2d(collections[i]);
                var offsetCurve = polylene.GetTrimmedOffset(distance, OffsetCurveExtensionType.Fillet)[0];

                for (int j = 0; j < countX; j++)
                {
                    intersector.Set(offsetCurve, rays[j]);
                    if (intersector.NumberOfIntersectionPoints == 1)
                    {
                        zArray[i, j] = intersector.GetIntersectionPoint(0).Y - distance;
                    }
                }
                //if (i < 50)
                //{
                //    Draw.Pline(polylene.GetSamplePoints(10).Select(p => new Point3d(p.X + i * 100, p.Y + 1000, 0)));
                //    Draw.Pline(offsetCurve.GetSamplePoints(10).Select(p => new Point3d(p.X + i * 100, p.Y + 1000, 0)));
                //}
                //else
                //{
                polylene.Dispose();
                offsetCurve.Dispose();
                //}
            }
            rays.ForEach(p => p.Dispose());
            intersector.Dispose();

            return(zArray);
        }
コード例 #5
0
ファイル: LongitudinalSection.cs プロジェクト: sunjini/CADDev
        /// <summary> 纵断面中某个桩号所对应的填方高度,如果为负值,则代表挖方高度 </summary>
        /// <param name="station"></param>
        /// <returns></returns>
        public double GetFillHeight(double station)
        {
            var intersVerticalRoad = new CurveCurveIntersector2d(RoadCurve2d,
                                                                 new Line2d(new Point2d(station, 0), new Vector2d(0, 1)));
            var intersVerticalGround = new CurveCurveIntersector2d(GroundCurve2d,
                                                                   new Line2d(new Point2d(station, 0), new Vector2d(0, 1)));

            if (intersVerticalRoad.NumberOfIntersectionPoints == 0 ||
                intersVerticalGround.NumberOfIntersectionPoints == 0)
            {
                // 这种情况一般不会出现
            }
            else
            {
                var yRoad   = intersVerticalRoad.GetIntersectionPoint(0).Y;
                var yGround = intersVerticalGround.GetIntersectionPoint(0).Y;
                return(yRoad - yGround);
            }
            return(0.0);
        }
コード例 #6
0
        /// <summary> 低填路堤 </summary>
        /// <param name="centerAxis"></param>
        /// <param name="width"> 左右路堤坡底之间的宽度</param>
        /// <param name="height"> 自然地面以下地基加固的高度</param>
        /// <returns></returns>
        public static bool IsThinFill(Database db, SubgradeSection centerAxis, out double width, out double height)
        {
            var center = centerAxis.XData;

            height = 0.0;
            width  = 0.0;
            // 1. 基本判断标准
            var depth = center.CenterElevation_Road - center.CenterElevation_Ground;

            double leftWidth1  = 0.0;
            double rightWidth1 = 0.0;

            // 道路中心为填方,而且左右至少有一侧为填方边坡
            if (depth >= 0 && depth <= _criterion.低填最大高度 &&
                ((center.LeftSlopeFill == null || center.LeftSlopeFill.Value) ||
                 (center.RightSlopeFill == null || center.RightSlopeFill.Value)))
            {
                // 道路中心线 与 自然地面线的交点
                var centerGroundPt = new Point3d(center.CenterX, center.GetYFromElev(center.CenterElevation_Ground), 0);

                // 左侧低填处理的宽度
                var leftRoadWidth = center.CenterX - center.LeftRoadEdge.X;
                if (center.LeftSlopeFill == null || !center.LeftSlopeFill.Value)
                {
                    // 无边坡线或者是挖方
                    leftWidth1 = leftRoadWidth;
                }
                else
                {
                    var leftSlope = center.LeftSlopeHandle.GetDBObject <Polyline>(db);
                    if (leftSlope == null)
                    {
                        leftWidth1 = leftRoadWidth;
                    }
                    else
                    {
                        // 先计算填方边坡线与
                        var leftInters = new CurveCurveIntersector2d(leftSlope.Get2dLinearCurve(),
                                                                     new Ray2d(centerGroundPt.ToXYPlane(), new Vector2d(-1, 0)));
                        if (leftInters.NumberOfIntersectionPoints == 0)
                        {
                            leftWidth1 = leftRoadWidth;
                        }
                        else
                        {
                            leftWidth1 = Math.Abs(leftInters.GetIntersectionPoint(0).X - center.CenterX);
                        }
                    }
                }

                // 右侧低填处理的宽度
                var rightRoadWidth = center.RightRoadEdge.X - center.CenterX;
                if (center.RightSlopeFill == null || !center.RightSlopeFill.Value)
                {
                    // 无边坡线或者是挖方
                    rightWidth1 = rightRoadWidth;
                }
                else
                {
                    var rightSlope = center.RightSlopeHandle.GetDBObject <Polyline>(db);
                    if (rightSlope == null)
                    {
                        rightWidth1 = rightRoadWidth;
                    }
                    else
                    {
                        // 先计算填方边坡线与
                        var rightInters = new CurveCurveIntersector2d(rightSlope.Get2dLinearCurve(),
                                                                      new Ray2d(centerGroundPt.ToXYPlane(), new Vector2d(1, 0)));
                        if (rightInters.NumberOfIntersectionPoints == 0)
                        {
                            rightWidth1 = rightRoadWidth;
                        }
                        else
                        {
                            rightWidth1 = Math.Abs(rightInters.GetIntersectionPoint(0).X - center.CenterX);
                        }
                    }
                }

                width = leftWidth1 + rightWidth1;
                //
                if (width > 0)
                {
                    // 低填路堤的自然地面下部地基处理的高度
                    height = _criterion.低填处理高度 - (center.CenterElevation_Road - center.CenterElevation_Ground);
                    if (height < 0)
                    {
                        height = 0;
                    }
                    return(true);
                }
            }
            return(false);
        }
コード例 #7
0
        /// <summary>
        /// 判断某一侧边坡是否为陡坡路堤
        /// </summary>
        /// <param name="slp">某一侧边坡,其值可能为null,表示此侧没有边坡线 </param>
        /// <param name="ground">边坡所对应的自然地面线</param>
        /// <param name="treatedWidth"></param>
        /// <param name="setReinforcement">是否要设置加筋结构,比如铺设三层土工格栅</param>
        /// <returns></returns>
        private bool IsSteepFill(SectionInfo sec, bool left, SlopeLine slp, Polyline ground, out double treatedWidth,
                                 out double stairArea, out bool setReinforcement)
        {
            treatedWidth     = 0;
            stairArea        = 0;
            setReinforcement = false;
            var slopeFill = (slp == null) || slp.XData.FillCut;

            // ----------------------------------------------------------------------------------------
            // 确定进行搜索的左右边界:路基边缘(或边坡脚) 到 道路中线
            var    cGround = ground.Get2dLinearCurve();
            double edgeXleft;
            double edgeXright;
            var    succ = sec.GetFillSlopeXRange(left, slp, cGround, _docMdf.acDataBase, out edgeXleft, out edgeXright);

            if (!succ)
            {
                return(false);
            }
            // ----------------------------------------------------------------------------------------
            // ---------此时 [edgeXleft ~ edgeXright] 区间内应该都是填方区域 --------------------------

            //
            var segCounts = (int)Math.Ceiling((edgeXright - edgeXleft) / _criterion.最小迭代宽度); // 其值最小为1
            var xInterval = (edgeXright - edgeXleft) / segCounts;
            var xYs       = new List <double[]>();
            var cSlope    = slp?.Pline.Get2dLinearCurve();

            for (int i = 0; i <= segCounts; i++)
            {
                var    x = edgeXleft + i * xInterval;
                double yGround;
                var    inters = new CurveCurveIntersector2d(cGround, new Line2d(new Point2d(x, 0), new Vector2d(0, 1)));
                // 没有交点的情况一般不会出现,因为自然地面线的范围很广
                yGround = inters.NumberOfIntersectionPoints == 0 ? 0 : inters.GetIntersectionPoint(0).Y;

                double ySlope;
                if (cSlope == null) // 表示没有边坡线
                {
                    ySlope = 0;
                }
                else
                {
                    inters = new CurveCurveIntersector2d(cSlope, new Line2d(new Point2d(x, 0), new Vector2d(0, 1)));

                    // 没有交点的情况必然会出现,即x对应路基位置,而不是对应边坡位置,比如当路基下的自然地面线是向路基中心倾斜时。
                    ySlope = inters.NumberOfIntersectionPoints == 0 ? sec.CenterY : inters.GetIntersectionPoint(0).Y;
                }
                //
                xYs.Add(new double[3] {
                    x, yGround, ySlope
                });
            }

            // 每隔x间距时,自然地面的Y值
            var xyGround = xYs.Select(r => new double[] { r[0], r[1] }).ToList();

            // 开始求斜率(集合中至少有两个元素)。每个元素为三分量向量,分别为 X 坐标、X对应的自然地面的Y坐标,X对应的边坡的Y坐标
            double maxRatio = 0;
            double maxYFill;

            var lastX = xYs[0];

            maxYFill = lastX[2] - lastX[1];
            for (int i = 1; i < xYs.Count; i++)
            {
                var thisX = xYs[i];
                maxRatio = Math.Max(maxRatio, Math.Abs((thisX[1] - lastX[1]) / (thisX[0] - lastX[0])));
                maxYFill = Math.Max(maxYFill, Math.Abs(thisX[2] - thisX[1]));
                //
                lastX = thisX;
            }
            // 判断是否为陡坡路堤
            if (maxRatio >= (1 / _criterion.陡坡坡比))
            {
                // 道路中心与边坡均为填方
                treatedWidth = edgeXright - edgeXleft;
                stairArea    = CalculateStairArea(xyGround, edgeXleft, edgeXright);

                if (slopeFill && treatedWidth > 0 && maxYFill >= _criterion.加筋体对应填方段最小高度)
                {
                    setReinforcement = true;
                }
                return(true);
            }
            //
            return(false);
        }
コード例 #8
0
        /// <summary> 初始化每一个填挖交界点所占据的几何区间 </summary>
        /// <param name="longitudinalSection"></param>
        /// <returns></returns>
        private void ConstructIntersectRange(LongitudinalSection longitudinalSection)
        {
            var inters = longitudinalSection.Intersects;

            //

            // 将结果整理为二维数组,用来进行表格输出
            var rows   = new List <object[]>();
            var header = new object[] { "交界点坐标", "交界方式", "10m填方段最大高度", "10m挖方段最大高度", "处理方式" };

            rows.Add(header);

            int interval        = 2;
            var fillLargerThan  = 5.0;
            int fillCheckLength = 10;
            var arrCutToFill    = ArrayConstructor.FromRangeAri(0, fillCheckLength, interval);
            var arrFillToCut    = ArrayConstructor.FromRangeAri(0, -fillCheckLength, -interval);

            var blocks = Options_Collections.RangeBlocks;

            for (int i = 0; i < inters.NumberOfIntersectionPoints; i++)
            {
                var ptRoad   = inters.GetPointOnCurve1(i);
                var ptGround = inters.GetPointOnCurve2(i);

                // 排除桥梁等结构区域
                if (blocks.Any(r => r.ContainsStation(ptRoad.Point.X)))
                {
                    continue;
                }
                //
                var fillToCut = longitudinalSection.FilltoCut(ptRoad, ptGround);
                var arrDx     = fillToCut ? arrFillToCut : arrCutToFill;
                var intersX   = ptRoad.Point.X;

                // 填挖交界处的路基,在填方段10m范围内高度H<5m时,按断面A实施,H>5m时,按断面B实施。
                var maxVerticalDiff_Fill = 0.0;
                foreach (var dx in arrDx)
                {
                    var x = intersX + dx;
                    var intersVerticalRoad = new CurveCurveIntersector2d(longitudinalSection.RoadCurve2d,
                                                                         new Line2d(new Point2d(x, 0), new Vector2d(0, 1)));
                    var intersVerticalGround = new CurveCurveIntersector2d(longitudinalSection.GroundCurve2d,
                                                                           new Line2d(new Point2d(x, 0), new Vector2d(0, 1)));
                    if (intersVerticalRoad.NumberOfIntersectionPoints == 0 ||
                        intersVerticalGround.NumberOfIntersectionPoints == 0)
                    {
                        break;
                    }
                    else
                    {
                        var verticalDiff = intersVerticalRoad.GetIntersectionPoint(0).Y -
                                           intersVerticalGround.GetIntersectionPoint(0).Y;
                        if (verticalDiff > maxVerticalDiff_Fill)
                        {
                            maxVerticalDiff_Fill = verticalDiff;
                        }
                    }
                }

                var maxVerticalDiff_Cut = 0.0;
                foreach (var dx in arrDx)
                {
                    var x = intersX - dx;
                    var intersVerticalRoad = new CurveCurveIntersector2d(longitudinalSection.RoadCurve2d,
                                                                         new Line2d(new Point2d(x, 0), new Vector2d(0, 1)));
                    var intersVerticalGround = new CurveCurveIntersector2d(longitudinalSection.GroundCurve2d,
                                                                           new Line2d(new Point2d(x, 0), new Vector2d(0, 1)));
                    if (intersVerticalRoad.NumberOfIntersectionPoints == 0 ||
                        intersVerticalGround.NumberOfIntersectionPoints == 0)
                    {
                        break;
                    }
                    else
                    {
                        var verticalDiff = intersVerticalGround.GetIntersectionPoint(0).Y -
                                           intersVerticalRoad.GetIntersectionPoint(0).Y;

                        if (verticalDiff > maxVerticalDiff_Cut)
                        {
                            maxVerticalDiff_Cut = verticalDiff;
                        }
                    }
                }

                string fill      = fillToCut ? "填 - 挖" : "挖 - 填";
                var    reinforce = (maxVerticalDiff_Fill > fillLargerThan) ? "超挖换填 + 土工格栅" : "超挖换填";
                //
                rows.Add(new object[]
                {
                    ptRoad.Point.X, fill, maxVerticalDiff_Fill, maxVerticalDiff_Cut, reinforce
                });
            }

            var sheetArr = ArrayConstructor.FromList2D(listOfRows: rows);
            // sheetArr = sheetArr.InsertVector<object, string, object>(true, new[] { header }, new[] { -1.5f, });

            // 输出到表格
            var sheet_Infos = new List <WorkSheetData>
            {
                new WorkSheetData(WorkSheetDataType.SteepSlope, "纵向填挖交界", sheetArr)
            };

            ExportWorkSheetDatas(sheet_Infos);
            //
        }
コード例 #9
0
ファイル: SectionInfo.cs プロジェクト: sunjini/CADDev
        /// <summary>
        /// 计算道路横断面的某一侧中,从路面中心到边坡外边缘的范围内,属于填方的区域在 AutoCAD 几何中的 X 范围
        /// </summary>
        /// <param name="sec"></param>
        /// <param name="left"></param>
        /// <param name="slp"> 某一侧边坡,其值可能为null,表示此侧没有边坡线 </param>
        /// <param name="cGround"></param>
        /// <param name="db"></param>
        /// <param name="edgeXleft">此侧边坡的填方左边界</param>
        /// <param name="edgeXright">此侧边坡的填方右边界</param>
        /// <returns>如果没有填方区域,则返回 false </returns>
        public bool GetFillSlopeXRange(bool left, SlopeLine slp, CompositeCurve2d cGround, Database db,
                                       out double edgeXleft, out double edgeXright)
        {
            edgeXleft  = 0.0;
            edgeXright = 0.0;
            var centerFill = IsCenterFill();
            var slopeFill  = slp == null || slp.XData.FillCut;

            if (!centerFill && (slp == null || !slopeFill))
            {
                return(false);
            }

            // 确定进行搜索的左右边界:路基边缘(或边坡脚) 到 道路中线
            double roadEdge = left ? LeftRoadEdge.X : RightRoadEdge.X;

            double slopeEdge = roadEdge; // 边坡的坡脚的 X 值

            if (slp != null && slp.XData.Slopes.Count > 0)
            {
                var data = slp.XData;
                slopeEdge = data.Slopes[data.Slopes.Count - 1].OuterPoint.X;
            }
            if (centerFill && slopeFill)
            {
                // 道路中心与边坡均为填方
                double edgeX1 = CenterX;

                edgeXleft  = Math.Min(edgeX1, slopeEdge);
                edgeXright = Math.Max(edgeX1, slopeEdge);
            }
            else
            {
                // 说明 坡脚与道路中心这二者中有一个为挖方,另一个为填方
                var    roadSurfHandle = left ? LeftRoadSurfaceHandle : RightRoadSurfaceHandle;
                var    roadSurf       = roadSurfHandle.GetDBObject <Polyline>(db);
                var    cRoad          = roadSurf.Get2dLinearCurve();
                var    inters         = new CurveCurveIntersector2d(cRoad, cGround);
                double iX;
                if (inters.NumberOfIntersectionPoints > 0)
                {
                    iX = inters.GetIntersectionPoint(0).X;
                }
                else
                {
                    // 这种情况极少会出现,但测试中确实会有,即自然地面线与挖方坡底边沟相交,而不与路面相交
                    iX = roadEdge;
                }
                // 自然地面与路面的交点
                var roadWidth  = Math.Abs((roadEdge - CenterX));
                var innerRatio = Math.Abs((iX - CenterX) / roadWidth);
                if ((centerFill && innerRatio > 0.5))
                {
                    // 靠道路中心为填方,边坡为挖方
                    if (left)
                    {
                        edgeXleft  = iX;
                        edgeXright = CenterX;
                    }
                    else
                    {
                        edgeXleft  = CenterX;
                        edgeXright = iX;
                    }
                }
                else if (!centerFill && innerRatio <= 0.5)
                {
                    // 靠道路中心为挖方,边坡为填方
                    if (left)
                    {
                        edgeXleft  = slopeEdge;
                        edgeXright = iX;
                    }
                    else
                    {
                        edgeXleft  = iX;
                        edgeXright = slopeEdge;
                    }
                }
                else
                {
                    // 填方区域太小
                    return(false);
                }
            }
            return(true);
        }
コード例 #10
0
ファイル: BuilderUtils.cs プロジェクト: airmay/CAM
        public static List <Point2d> GetProcessPoints1(Curve profile, int index, double step, double shift, bool isMinToolCoord, double?begin, double?end, bool isProfileStep = false)  //, bool isExactlyBegin, bool isExactlyEnd)
        {
            var result    = new List <Point2d>();
            var start     = 10000D;
            var rayVector = index == 0 ? -Vector2d.YAxis : -Vector2d.XAxis;

            var p0  = begin ?? Math.Max(profile.StartPoint[index], profile.EndPoint[index]);
            var p1  = end ?? Math.Min(profile.StartPoint[index], profile.EndPoint[index]);
            var dir = Math.Sign(p1 - p0);

            using (var curve = profile.ToCompositeCurve2d())
                using (var ray = new Ray2d())
                    using (var intersector = new CurveCurveIntersector2d())
                    {
                        var     pos       = p0;
                        Point2d?point0    = null;
                        var     length    = profile.Length();
                        int     curveSign = dir * Math.Sign(curve.EndPoint[index] - curve.StartPoint[index]);
                        double? dist      = null;

                        while (dir > 0 ? pos <p1 : pos> p1)
                        {
                            double?max = null;
                            for (int i = 0; i <= 10; i++)
                            {
                                var rayPoint = GetPoint(pos + i * (shift / 10) * dir, start, index);
                                ray.Set(rayPoint, rayVector);
                                intersector.Set(curve, ray);
                                if (intersector.NumberOfIntersectionPoints > 0)
                                {
                                    var intersect = intersector.GetIntersectionPoint(0);
                                    max = Math.Max(max ?? double.MinValue, intersect[1 - index]);
                                    if (!point0.HasValue && i == 0)
                                    {
                                        point0 = intersect;
                                    }
                                }
                            }
                            if (max.HasValue)
                            {
                                var toolCoord = pos + shift * dir * (isMinToolCoord ^ dir < 0 ? 0 : 1);
                                result.Add(GetPoint(toolCoord, max.Value, index));
                            }
                            if (isProfileStep && point0.HasValue)
                            {
                                if (!dist.HasValue)
                                {
                                    dist = curve.GetLength(0, curve.GetParameterOf(point0.Value));
                                }
                                dist += step * curveSign;
                                if (dist < 0 || dist > length)
                                {
                                    break;
                                }
                                var point = curve.EvaluatePoint(curve.GetParameterAtLength(0, dist.Value, true));
                                pos = point[index];
                            }
                            else
                            {
                                pos += step * dir;
                            }
                        }
                    }
            return(result);
        }
コード例 #11
0
        /// <summary>
        /// 计算一段填方区间(填方段的两个边界交点之间的区间)的挖台阶量
        /// </summary>
        /// <param name="startStation"></param>
        /// <param name="endStation"></param>
        private List <LongitudinalStairExcav> CalculateFillRange(double startStation, double endStation)
        {
            if (endStation - startStation < _criterion.最小区间宽度)
            {
                return(null);
            }

            // 求分段交点(集合中至少有两个值)
            var xy = new List <double[]>();

            for (double x = startStation; x < endStation; x += _criterion.台阶宽度)
            {
                var intersVerticalGround = new CurveCurveIntersector2d(_longitudinalSection.GroundCurve2d,
                                                                       new Line2d(new Point2d(x, 0), new Vector2d(0, 1)));
                xy.Add(new double[] { x, intersVerticalGround.GetIntersectionPoint(0).Y });
            }

            var stairsInFillZone = new List <LongitudinalStairExcav>();

            // 计算此区间内所有坡度较陡的台阶
            for (int i = 0; i < xy.Count - 1; i++)
            {
                var ratio = Math.Abs((xy[i + 1][1] - xy[i][1]) / ((xy[i + 1][0] - xy[i][0])));
                if (ratio > _criterion.临界纵坡)
                {
                    // 挖台阶的三角形面积
                    var area = Math.Abs((xy[i + 1][0] - xy[i][0]) * (xy[i + 1][1] - xy[i][1])) / 2;
                    stairsInFillZone.Add(new LongitudinalStairExcav(xy[i][0], xy[i + 1][0], stairArea: area));
                }
            }

            // 这里为了避免区间太密,作出一个强制处理:对同一个填方桩号区间内的所有满足条件的台阶区间进行合并,保证合并后的每一个区间的长度不小于设定的最小宽度
            // 但是处理之后,总的挖台阶面积还是此区间内有效的台阶的三角形面积之和
            int count = stairsInFillZone.Count;

            if (count == 0 ||
                stairsInFillZone[count - 1].EndStation - stairsInFillZone[0].StartStation < _criterion.最小区间宽度)
            {
                // 表示此填方区间内,所有的台阶(算上分离的)之间的距离都小于 10 m,此时认为不作挖台阶处理
                return(null);
            }
            else
            {
                var stairsInFillZone1 = new List <LongitudinalStairExcav>();
                // 将一些分离的台阶进行合并,确保其距离不小于10m;但是处理之后,总的挖台阶面积还是此区间内有效的台阶的三角形面积之和
                // 1. 将直接相连的台阶进行合并
                var lastStair = stairsInFillZone[0];
                LongitudinalStairExcav thisStair;
                stairsInFillZone1.Add(lastStair);
                for (int i = 1; i < count; i++)
                {
                    thisStair = stairsInFillZone[i];
                    if (lastStair.IsMergeable(thisStair))
                    {
                        lastStair.Merge(thisStair);
                    }
                    else
                    {
                        lastStair = thisStair;
                        stairsInFillZone1.Add(thisStair);
                    }
                }
                // 合并后,整个填方区间内,剩下相互分离的多个台阶子区间
                // 2. 对于初步合并后自身宽度不足10m,左右10m内又没有其他台阶的项,直接删除
                count = stairsInFillZone1.Count;
                if (count == 1)
                {
                    // 如果合并后只剩一段,则直接返回
                    return(stairsInFillZone1);
                }
                else
                {
                    // 从小桩号往大桩号前进式合并
                    stairsInFillZone = new List <LongitudinalStairExcav>();
                    LongitudinalStairExcav validatedStair;
                    LongitudinalStairExcav backStair  = stairsInFillZone1[0];
                    LongitudinalStairExcav frontStair = stairsInFillZone1[1];
                    // 整个填方段起码有三段分离的台阶子区间
                    for (int i = 0; i < count - 1; i++)
                    {
                        frontStair     = stairsInFillZone1[i + 1];
                        validatedStair = MergeSeperatedStair(backStair, ref frontStair);
                        if (validatedStair != null)
                        {
                            stairsInFillZone.Add(validatedStair);
                        }
                        backStair = frontStair;
                    }
                    // 最后一个子区间
                    if (frontStair.GetLength() >= _criterion.最小区间宽度)
                    {
                        stairsInFillZone.Add(frontStair);
                    }
                    return(stairsInFillZone);
                }
            }
        }
コード例 #12
0
        protected override void BuildProcessing(MillingCommandGenerator generator)
        {
            var toolThickness = Tool.Thickness.Value;
            var profile       = ProcessingArea[0].GetCurve();

            if (Delta != 0)
            {
                profile = (Curve)profile.GetOffsetCurves(Delta)[0];
            }

            var zMax = profile.GetStartEndPoints().Max(p => p.Y);

            generator.SetZSafety(ZSafety, zMax);
            var xMax = 0D;

            using (var curve = profile.ToCompositeCurve2d())
                using (var ray = new Ray2d())
                    using (var intersector = new CurveCurveIntersector2d())
                    {
                        var angleC = 360;
                        var gCode  = 2;

                        for (var z = StartZ; z > 0; z -= StepZ)
                        {
                            var xMin = RadiusMin;
                            for (int i = 0; i < 3; i++)
                            {
                                ray.Set(new Point2d(0, z + i * toolThickness / 2), Vector2d.XAxis);
                                intersector.Set(curve, ray);
                                if (intersector.NumberOfIntersectionPoints == 1)
                                {
                                    xMin = Math.Max(xMin, intersector.GetIntersectionPoint(0).X);
                                }
                            }
                            if (xMin == 0)
                            {
                                throw new Exception("Нет точек пересечения с профилем");
                            }

                            var x         = Math.Max(xMin, RadiusMax - Penetration);
                            var s         = x - xMin;
                            int passCount = (int)Math.Ceiling(s / Penetration);
                            var dx        = s > Consts.Epsilon ? s / passCount : 1;

                            if (generator.IsUpperTool)
                            {
                                generator.Move(0, -x - ZSafety, angleC: 0, angleA: 90);
                            }
                            else
                            {
                                generator.Transition(y: -x - ZSafety, feed: CuttingFeed);
                            }
                            generator.Transition(z: z);
                            do
                            {
                                var arc = new Arc(new Point3d(0, 0, z), x, Math.PI * 1.5, Math.PI * 1.5 - Consts.Epsilon);
                                generator.Cutting(0, -x, z, PenetrationFeed);
                                generator.GCommand(CommandNames.Cutting, gCode, angleC: angleC, curve: arc, center: arc.Center.To2d(), feed: CuttingFeed);
                                angleC = 360 - angleC;
                                gCode  = 5 - gCode;
                                x     -= dx;
                            }while (x >= xMin - Consts.Epsilon);

                            xMax = Math.Max(xMin, RadiusMax);
                        }
                        generator.Transition(y: -xMax - ZSafety, feed: PenetrationFeed);
                        generator.Uplifting();
                    }
        }
コード例 #13
0
        /// <summary>
        /// 判断某一侧边坡的填方边坡类型
        /// </summary>
        /// <param name="slp">某一侧边坡,其值可能为null,表示此侧没有边坡线 </param>
        /// <param name="ground">边坡所对应的自然地面线</param>
        /// <param name="treatedWidth"></param>
        /// <param name="stairArea">某一侧边坡所挖台阶面积</param>
        /// <returns></returns>
        private FillSlopeType GetFillSlopeType(SectionInfo sec, bool left, SlopeLine slp, Polyline ground,
                                               out double treatedWidth, out double stairArea)
        {
            treatedWidth = 0;
            stairArea    = 0.0;
            double edgeXleft;
            double edgeXright;
            var    cGround = ground.Get2dLinearCurve();
            var    succ    = sec.GetFillSlopeXRange(left, slp, cGround, _docMdf.acDataBase, out edgeXleft, out edgeXright);

            if (!succ)
            {
                return(FillSlopeType.Other);
            }

            // 必须是填方边坡
            if ((left && (sec.LeftSlopeFill == null || !sec.LeftSlopeFill.Value)) ||
                (!left && (sec.RightSlopeFill == null || !sec.RightSlopeFill.Value)))
            {
                return(FillSlopeType.Other);
            }

            // 有路肩墙
            if ((left && sec.LeftRetainingWallType == RetainingWallType.路肩墙) || (!left && sec.RightRetainingWallType == RetainingWallType.路肩墙))
            {
                return(FillSlopeType.Other);
            }

            //
            var segCounts = (int)Math.Ceiling((edgeXright - edgeXleft) / _criterion.最小迭代宽度); // 其值最小为1
            var xInterval = (edgeXright - edgeXleft) / segCounts;
            var xYs       = new List <double[]>();

            for (int i = 0; i <= segCounts; i++)
            {
                var    x = edgeXleft + i * xInterval;
                double yGround;
                var    inters = new CurveCurveIntersector2d(cGround, new Line2d(new Point2d(x, 0), new Vector2d(0, 1)));
                // 没有交点的情况一般不会出现,因为自然地面线的范围很广
                yGround = inters.NumberOfIntersectionPoints == 0 ? 0 : inters.GetIntersectionPoint(0).Y;
                //
                xYs.Add(new double[] { x, yGround });
            }
            // 开始求斜率(集合中至少有两个元素)。每个元素为三分量向量,分别为 X 坐标、X对应的自然地面的Y坐标,X对应的边坡的Y坐标
            double maxRatio      = 0;
            bool   hasStairExcav = false;
            var    lastX         = xYs[0];

            for (int i = 1; i < xYs.Count; i++)
            {
                var thisX    = xYs[i];
                var segRatio = Math.Abs((thisX[1] - lastX[1]) / (thisX[0] - lastX[0]));
                if ((segRatio > 1 / _criterion.填方坡比下限) && (segRatio > 1 / _criterion.填方坡比下限))
                {
                    hasStairExcav = true;
                }
                maxRatio = Math.Max(maxRatio, segRatio);
                //
                lastX = thisX;
            }
            if (!hasStairExcav)
            {
                return(FillSlopeType.Other);
            }
            else
            {
                //  判断是否为陡坡路堤,如果是,则不计入挖台阶工程量表中(因为在陡坡路堤工程量表中已经计入)
                if (maxRatio >= (1 / _criterion.陡坡坡比))
                {
                    treatedWidth = 0;
                    return(FillSlopeType.SteepSlope);
                }
                else
                {
                    //
                    treatedWidth = edgeXright - edgeXleft;
                    stairArea    = Exporter_SteepSlope.CalculateStairArea(xYs, edgeXleft, edgeXright);
                    return(FillSlopeType.StairExcav);
                }
            }
        }