private static List <BridgePoints> GetBridgeByArc(ArcBase arc, UnitPoint p1, UnitPoint p2, BridgingModel param) { List <BridgePoints> retPoints = new List <BridgePoints>(); var line = DrawingOperationHelper.GetLineEquation(p1, p2); double width = param.Width / 2; ArcModelMini arcMini = new DrawModel.ArcModelMini() { Center = arc.Center, Radius = arc.Radius, StartAngle = arc.StartAngle, EndAngle = arc.EndAngle, SweepAngle = arc.AngleSweep, Clockwise = arc.IsClockwise }; List <UnitPoint> points = DrawingOperationHelper.GetIntersectPointByLineAndCircle(line.Item1, line.Item2, line.Item3, arc.Center, arc.Radius); var hasPoints = points?.Where(p => !p.IsEmpty && (HitUtil.IsPointOnArc(p, 0.000001f, arcMini) && HitUtil.IsPointInLine(p1, p2, p, 0.000001f))).ToList(); if (hasPoints != null && hasPoints.Count > 0) { //根据宽度求点 double angle = width / arc.Radius * (arc.IsClockwise ? 1 : -1); hasPoints?.ForEach(p => { double lineAngle = HitUtil.LineAngleR(arcMini.Center, p, 0); double angle1 = lineAngle + angle; double angle2 = lineAngle - angle; UnitPoint retPoint1 = UnitPoint.Empty; UnitPoint retPoint2 = UnitPoint.Empty; if (HitUtil.IsPointInArc(HitUtil.RadiansToDegrees(angle1), arcMini.StartAngle, arcMini.EndAngle, arcMini.Clockwise)) { //第一个位置点 retPoint1 = HitUtil.PointOnCircle(arcMini.Center, arcMini.Radius, angle1); } if (HitUtil.IsPointInArc(HitUtil.RadiansToDegrees(angle2), arcMini.StartAngle, arcMini.EndAngle, arcMini.Clockwise)) { //第二个位置点 retPoint2 = HitUtil.PointOnCircle(arcMini.Center, arcMini.Radius, angle2); } BridgePoints bridges = new BridgePoints(arc, new UnitPointBulge(retPoint1), new UnitPointBulge(retPoint2), HitUtil.Distance(p1, p)); retPoints.Add(bridges); }); } 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); }