/// <summary>
        /// 得到直线或者圆弧的标准补偿点
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="isOutside"></param>
        /// <returns></returns>
        public static Tuple <UnitPointBulge, UnitPointBulge> GetCompensationsPoint(UnitPointBulge p1, UnitPointBulge p2, double size, bool isOutside, bool isUpdateBulge = false)
        {
            UnitPointBulge up1 = new UnitPointBulge();
            UnitPointBulge up2 = new UnitPointBulge();

            if (!double.IsNaN(p1.Bulge))//圆弧
            {
                var    arc = DrawingOperationHelper.GetArcParametersFromBulge(p1.Point, p2.Point, (float)p1.Bulge);
                double r   = arc.Clockwise ? arc.Radius - size : arc.Radius + size;
                if (isOutside)
                {
                    r = arc.Clockwise ? arc.Radius + size : arc.Radius - size;
                }
                if (r > 0)
                {
                    UnitPoint point1 = HitUtil.GetLinePointByDistance(arc.Center, p1.Point, r, true);
                    UnitPoint point2 = HitUtil.GetLinePointByDistance(arc.Center, p2.Point, r, true);
                    up1 = new UnitPointBulge()
                    {
                        Point = point1, Bulge = p1.Bulge, HasMicroConn = p1.HasMicroConn
                    };
                    up2 = new UnitPointBulge()
                    {
                        Point = point2, Bulge = p2.Bulge, HasMicroConn = p2.HasMicroConn
                    };
                    if (isUpdateBulge)
                    {
                        up1.Bulge = BulgeHelper.GetBulgeFromTwoPointsAndCenter(arc.Center, up1.Point, up2.Point, arc.Clockwise);
                    }
                }
            }
            else //直线
            {
                var       line1d1 = DrawingOperationHelper.GetLinePointByVerticalLine(p1.Point, p2.Point, size);
                var       line1d2 = DrawingOperationHelper.GetLinePointByVerticalLine(p2.Point, p1.Point, size);
                UnitPoint point1  = !isOutside ? line1d1.Item2 : line1d1.Item1;
                UnitPoint point2  = !isOutside ? line1d2.Item1 : line1d2.Item2;
                up1 = new UnitPointBulge()
                {
                    Point = point1, Bulge = p1.Bulge, HasMicroConn = p1.HasMicroConn
                };
                up2 = new UnitPointBulge()
                {
                    Point = point2, Bulge = p2.Bulge, HasMicroConn = p2.HasMicroConn
                };
            }

            return(Tuple.Create(up1, up2));
        }
Beispiel #2
0
        /// <summary>
        /// 根据长度获取多段线的点坐标
        /// </summary>
        /// <param name="points">多段线的点</param>
        /// <param name="index">当前开始的索引位置</param>
        /// <param name="length">长度</param>
        /// <param name="isPositive">是否正向计算长度,否则从反向计算长度</param>
        /// <returns></returns>
        private static UnitPointBulge GetEndPointByLength(List <UnitPointBulge> points, int index, double length, bool isPositive)
        {
            int       next = index + 1 >= points.Count ? 0 : index + 1;
            var       p1   = points[index];
            var       p2   = points[next];
            UnitPoint end  = UnitPoint.Empty;

            if (!double.IsNaN(p1.Bulge))
            {
                ArcModelMini arc       = DrawingOperationHelper.GetArcParametersFromBulge(p1.Point, p2.Point, (float)p1.Bulge);
                double       curLength = DrawingOperationHelper.GetArcLength(arc.Radius, arc.SweepAngle);
                if (length < curLength)
                {
                    float angle = (float)((isPositive ? length : (curLength - length)) / curLength) * arc.SweepAngle;
                    angle = arc.StartAngle + (float)HitUtil.DegreesToRadians(angle);
                    end   = HitUtil.PointOnCircle(arc.Center, arc.Radius, angle);
                }
                else if (!double.IsNaN(length - curLength))
                {
                    int nextIndex = isPositive ? next : (index - 1) < 0 ? points.Count - 1 : (index - 1);
                    return(GetEndPointByLength(points, nextIndex, length - curLength, isPositive));
                }
            }
            else
            {
                double curLength = HitUtil.Distance(p1.Point, p2.Point);
                if (length < curLength)
                {
                    if (isPositive)
                    {
                        end = HitUtil.GetLinePointByDistance(p1.Point, p2.Point, length);
                    }
                    else
                    {
                        end = HitUtil.GetLinePointByDistance(p2.Point, p1.Point, length);
                    }
                }
                else if (!double.IsNaN(length - curLength))
                {
                    int nextIndex = isPositive ? next : (index - 1) < 0 ? points.Count - 1 : (index - 1);
                    return(GetEndPointByLength(points, nextIndex, length - curLength, isPositive));
                }
            }
            return(new UnitPointBulge(end, bulge: p1.Bulge, position: index));
        }
        /// <summary>
        /// 圆弧到直线,补偿求交点
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <param name="indexCur"></param>
        /// <returns></returns>
        private static List <UnitPointBulge> CalCompensationsByArcLine(UnitPointBulge p1, UnitPointBulge p2, UnitPointBulge p3, int indexCur, CompensationModel compensationParam, bool isOutside)
        {
            var          retPoints = new List <UnitPointBulge>();
            ArcModelMini arc       = DrawingOperationHelper.GetArcParametersFromBulge(p1.Point, p2.Point, (float)p1.Bulge);
            var          cPoints   = GetCompensationsPoint(p2, p3, compensationParam.Size, isOutside);
            double       r         = arc.Clockwise ? arc.Radius - compensationParam.Size : arc.Radius + compensationParam.Size;

            if (isOutside)
            {
                r = arc.Clockwise ? arc.Radius + compensationParam.Size : arc.Radius - compensationParam.Size;
            }
            UnitPoint point1 = HitUtil.GetLinePointByDistance(arc.Center, p2.Point, r, true);

            //如果两点距离在误差范围内,当做同一个点处理
            if (HitUtil.Distance(point1, cPoints.Item1.Point) < errorRange)
            {
                retPoints.Add(new UnitPointBulge(point1, p2.Bulge, hasMicroConn: p2.HasMicroConn, position: indexCur));
                return(retPoints);
            }
            var       line               = DrawingOperationHelper.GetLineEquation(cPoints.Item1.Point, cPoints.Item2.Point);
            var       intersects         = DrawingOperationHelper.GetIntersectPointByLineAndCircle(line.Item1, line.Item2, line.Item3, arc.Center, r);
            var       validPoint         = new UnitPoint(double.NaN, double.NaN);
            UnitPoint intersecteArcPoint = new UnitPoint(double.NaN, double.NaN);

            //筛选有交点,如果有两个点就选距离p2近的点
            if (intersects.Count == 1)
            {
                validPoint = intersects[0];
            }
            else if (intersects.Count == 2)
            {
                validPoint = HitUtil.Distance(intersects[0], p2.Point) < HitUtil.Distance(intersects[1], p2.Point) ? intersects[0] : intersects[1];
            }

            if (validPoint.IsEmpty) //|| !HitUtil.IsPointInLine(cPoints.Item1.Point, cPoints.Item2.Point, validPoint, errorRange))
            {
                //求圆弧的切线的交点
                if (arc.Clockwise != HitUtil.IsClockwiseByCross(p2.Point, point1, cPoints.Item1.Point))
                {
                    var l1 = DrawingOperationHelper.GetLineEquationByVerticalLine(point1, p2.Point);
                    intersecteArcPoint = DrawingOperationHelper.GetIntersectionPointBy2Line(l1.Item1, l1.Item2, l1.Item3, line.Item1, line.Item2, line.Item3);
                }
            }
            bool completedSmooth = false;   //是否完成圆角处理

            if (compensationParam.IsSmooth) //圆角处理
            {
                if (!intersecteArcPoint.IsEmpty ||
                    (!validPoint.IsEmpty && !HitUtil.IsPointInLine(cPoints.Item1.Point, cPoints.Item2.Point, validPoint, errorRange)))
                {
                    bool   closewise = HitUtil.IsClockwiseByCross(p2.Point, cPoints.Item1.Point, cPoints.Item2.Point);
                    double bulge     = BulgeHelper.GetBulgeFromTwoPointsAndCenter(p2.Point, point1, cPoints.Item1.Point, closewise);
                    retPoints.Add(new UnitPointBulge(point1, bulge, hasMicroConn: p2.HasMicroConn, position: -1 - indexCur));
                    retPoints.Add(new UnitPointBulge(cPoints.Item1.Point, p2.Bulge, hasMicroConn: p2.HasMicroConn, position: indexCur));
                    completedSmooth = true;
                }
            }
            if (!completedSmooth)
            {
                if (!intersecteArcPoint.IsEmpty)
                {
                    retPoints.Add(new UnitPointBulge(point1, position: indexCur));
                    retPoints.Add(new UnitPointBulge(intersecteArcPoint, position: indexCur));
                }
                else if (!validPoint.IsEmpty)
                {
                    retPoints.Add(new UnitPointBulge(validPoint, p2.Bulge, hasMicroConn: p2.HasMicroConn, position: indexCur));
                    return(retPoints);
                }
                else
                {
                    retPoints.Add(new UnitPointBulge(point1, position: indexCur));
                    retPoints.Add(new UnitPointBulge(p2.Point, position: indexCur));
                    retPoints.Add(new UnitPointBulge(cPoints.Item1.Point, p2.Bulge, hasMicroConn: p2.HasMicroConn, position: indexCur));
                }
            }
            return(retPoints);
        }
        /// <summary>
        /// 圆弧到圆弧,补偿求交点
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <param name="indexCur"></param>
        /// <returns></returns>
        private static List <UnitPointBulge> CalCompensationsBy2Arc(UnitPointBulge p1, UnitPointBulge p2, UnitPointBulge p3, int indexCur, CompensationModel compensationParam, bool isOutside)
        {
            var          retPoints = new List <UnitPointBulge>();
            ArcModelMini arc1      = DrawingOperationHelper.GetArcParametersFromBulge(p1.Point, p2.Point, (float)p1.Bulge);
            ArcModelMini arc2      = DrawingOperationHelper.GetArcParametersFromBulge(p2.Point, p3.Point, (float)p2.Bulge);
            double       r1        = arc1.Clockwise ? arc1.Radius - compensationParam.Size : arc1.Radius + compensationParam.Size;
            double       r2        = arc2.Clockwise ? arc2.Radius - compensationParam.Size : arc2.Radius + compensationParam.Size;

            if (isOutside)
            {
                r1 = arc1.Clockwise ? arc1.Radius + compensationParam.Size : arc1.Radius - compensationParam.Size;
                r2 = arc2.Clockwise ? arc2.Radius + compensationParam.Size : arc2.Radius - compensationParam.Size;
            }
            UnitPoint point1 = HitUtil.GetLinePointByDistance(arc1.Center, p2.Point, r1, true);
            UnitPoint point2 = HitUtil.GetLinePointByDistance(arc2.Center, p2.Point, r2, true);

            if (HitUtil.Distance(point1, point2) < errorRange)
            {
                retPoints.Add(new UnitPointBulge(point2, p2.Bulge, hasMicroConn: p2.HasMicroConn, position: indexCur));
                return(retPoints);
            }

            var       intersects         = DrawingOperationHelper.GetIntersectPointBy2Circle(arc1.Center, r1, arc2.Center, r2);
            var       validPoint         = new UnitPoint(double.NaN, double.NaN);
            UnitPoint intersecteArcPoint = new UnitPoint(double.NaN, double.NaN);

            //筛选有交点,如果有两个点就选距离p2近的点
            if (intersects.Count == 1)
            {
                validPoint = intersects[0];
            }
            else if (intersects.Count == 2)
            {
                validPoint = HitUtil.Distance(intersects[0], p2.Point) < HitUtil.Distance(intersects[1], p2.Point) ? intersects[0] : intersects[1];
            }

            bool closewise = HitUtil.IsClockwiseByCross(p2.Point, point1, point2);

            if (validPoint.IsEmpty)
            {
                if (arc1.Clockwise != closewise || arc2.Clockwise != closewise)//求两个圆弧的切线的交点
                {
                    var line1 = DrawingOperationHelper.GetLineEquationByVerticalLine(point1, arc1.Center);
                    var line2 = DrawingOperationHelper.GetLineEquationByVerticalLine(point2, arc2.Center);
                    intersecteArcPoint = DrawingOperationHelper.GetIntersectionPointBy2Line(line1.Item1, line1.Item2, line1.Item3, line2.Item1, line2.Item2, line2.Item3);
                }
            }
            bool completedSmooth = false;   //是否完成圆角处理

            if (compensationParam.IsSmooth) //圆角处理
            {
                bool needSmooth = false;
                if (!validPoint.IsEmpty)
                {
                    double lineAngle  = HitUtil.LineAngleR(arc1.Center, validPoint, 0);
                    bool   pointInArc = HitUtil.IsPointInArc(HitUtil.RadiansToDegrees(lineAngle), HitUtil.RadiansToDegrees(arc1.StartAngle), HitUtil.RadiansToDegrees(arc1.EndAngle), arc1.Clockwise);
                    needSmooth = !pointInArc;
                }
                if (!intersecteArcPoint.IsEmpty || needSmooth)
                {
                    double bulge = BulgeHelper.GetBulgeFromTwoPointsAndCenter(p2.Point, point1, point2, closewise);
                    retPoints.Add(new UnitPointBulge(point1, bulge, hasMicroConn: p2.HasMicroConn, position: -1 - indexCur));
                    retPoints.Add(new UnitPointBulge(point2, p2.Bulge, hasMicroConn: p2.HasMicroConn, position: indexCur));
                    completedSmooth = true;
                }
            }
            if (!completedSmooth)
            {
                if (!validPoint.IsEmpty)
                {
                    retPoints.Add(new UnitPointBulge(validPoint, p2.Bulge, hasMicroConn: p2.HasMicroConn, position: indexCur));
                    return(retPoints);
                }
                else if (!intersecteArcPoint.IsEmpty)
                {
                    retPoints.Add(new UnitPointBulge(point1, position: indexCur));
                    retPoints.Add(new UnitPointBulge(intersecteArcPoint, position: indexCur));
                    retPoints.Add(new UnitPointBulge(point2, p2.Bulge, hasMicroConn: p2.HasMicroConn, position: indexCur));
                }
                else
                {
                    retPoints.Add(new UnitPointBulge(point1, position: indexCur));
                    retPoints.Add(new UnitPointBulge(p2.Point, position: indexCur));
                    retPoints.Add(new UnitPointBulge(point2, p2.Bulge, hasMicroConn: p2.HasMicroConn, position: indexCur));
                }
            }
            return(retPoints);
        }