/// <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)); }
/// <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); }