private static List <BridgePoints> GetBridgeByCircle(Circle circle, UnitPoint p1, UnitPoint p2, BridgingModel param) { List <BridgePoints> retPoints = new List <BridgePoints>(); var line = DrawingOperationHelper.GetLineEquation(p1, p2); double width = param.Width / 2; List <UnitPoint> points = DrawingOperationHelper.GetIntersectPointByLineAndCircle(line.Item1, line.Item2, line.Item3, circle.Center, circle.Radius); var hasPoints = points?.Where(p => !p.IsEmpty && HitUtil.IsPointInLine(p1, p2, p, 0.000001f)).ToList(); if (hasPoints != null && hasPoints.Count > 0) { //根据宽度求点 double angle = width / circle.Radius * (circle.IsClockwise ? 1 : -1); List <UnitPointBulge> temps = new List <UnitPointBulge>(); hasPoints?.ForEach(p => { double lineAngle = HitUtil.LineAngleR(circle.Center, p, 0); double angle1 = lineAngle + angle; double angle2 = lineAngle - angle; //第一个位置点 UnitPoint retPoint1 = HitUtil.PointOnCircle(circle.Center, circle.Radius, angle1); //第二个位置点 UnitPoint retPoint2 = HitUtil.PointOnCircle(circle.Center, circle.Radius, angle2); BridgePoints bridges = new BridgePoints(circle, 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> CalCompensationsBy2Line(UnitPointBulge p1, UnitPointBulge p2, UnitPointBulge p3, int indexCur, CompensationModel compensationParam, bool isOutside) { var retPoints = new List <UnitPointBulge>(); var cPoints1 = GetCompensationsPoint(p1, p2, compensationParam.Size, isOutside); var cPoints2 = GetCompensationsPoint(p2, p3, compensationParam.Size, isOutside); //如果两点距离在误差范围内,当做同一个点处理 if (HitUtil.Distance(cPoints1.Item2.Point, cPoints2.Item1.Point) < errorRange) { retPoints.Add(new UnitPointBulge(cPoints1.Item2.Point, p2.Bulge, hasMicroConn: p2.HasMicroConn, position: indexCur)); return(retPoints); } var line1 = DrawingOperationHelper.GetLineEquation(cPoints1.Item1.Point, cPoints1.Item2.Point); var line2 = DrawingOperationHelper.GetLineEquation(cPoints2.Item1.Point, cPoints2.Item2.Point); UnitPoint point = DrawingOperationHelper.GetIntersectionPointBy2Line(line1.Item1, line1.Item2, line1.Item3, line2.Item1, line2.Item2, line2.Item3); if (double.IsNaN(point.X) || double.IsNaN(point.Y)) { //平行 retPoints.Add(new UnitPointBulge(cPoints1.Item2.Point, p2.Bulge, hasMicroConn: p2.HasMicroConn, position: indexCur)); return(retPoints); } else { bool pointInLine = HitUtil.IsPointInLine(cPoints1.Item1.Point, cPoints1.Item2.Point, point, errorRange); if (compensationParam.IsSmooth && !pointInLine) { //圆角处理,转换为带弧度的点 bool closewise = HitUtil.IsClockwiseByCross(cPoints1.Item1.Point, cPoints1.Item2.Point, p2.Point); double bulge = BulgeHelper.GetBulgeFromTwoPointsAndCenter(p2.Point, cPoints1.Item2.Point, cPoints2.Item1.Point, closewise); retPoints.Add(new UnitPointBulge(cPoints1.Item2.Point, bulge, hasMicroConn: p2.HasMicroConn, position: -1 - indexCur)); retPoints.Add(new UnitPointBulge(cPoints2.Item1.Point, p2.Bulge, hasMicroConn: p2.HasMicroConn, position: indexCur)); return(retPoints); } else { retPoints.Add(new UnitPointBulge(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> 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); }
private static List <BridgePoints> GetBridgeByMultiSegLine(MultiSegmentLineBase multiSegLine, UnitPoint p1, UnitPoint p2, BridgingModel param) { List <BridgePoints> retPoints = new List <BridgePoints>(); var line = DrawingOperationHelper.GetLineEquation(p1, p2); double width = param.Width / 2; var oriPoints = multiSegLine.Points; for (int index = 0; index < oriPoints.Count; index++) { int next = (index + 1 == oriPoints.Count) ? 0 : index + 1; UnitPointBulge point1 = oriPoints[index]; UnitPointBulge point2 = oriPoints[next]; if (!multiSegLine.IsCloseFigure && index == oriPoints.Count - 1) { break; } if (!double.IsNaN(point1.Bulge)) { //圆弧 ArcModelMini arcMini = DrawingOperationHelper.GetArcParametersFromBulge(point1.Point, point2.Point, (float)point1.Bulge); arcMini.StartAngle = (float)HitUtil.RadiansToDegrees(arcMini.StartAngle); arcMini.EndAngle = (float)HitUtil.RadiansToDegrees(arcMini.EndAngle); List <UnitPoint> points = DrawingOperationHelper.GetIntersectPointByLineAndCircle(line.Item1, line.Item2, line.Item3, arcMini.Center, arcMini.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) { arcMini.StartAngle = (float)HitUtil.DegreesToRadians(arcMini.StartAngle); arcMini.EndAngle = (float)HitUtil.DegreesToRadians(arcMini.EndAngle); //根据宽度求点 double arcLength = DrawingOperationHelper.GetArcLength(arcMini.Radius, arcMini.SweepAngle); hasPoints?.ForEach(p => { double percent = DrawingOperationHelper.GetPercentInArcByPoint(arcMini, p); //第一个位置点 double length1 = arcLength * (1 - percent) + width; UnitPointBulge retP1 = GetEndPointByLength(oriPoints, index, length1, false); //第二个位置点 double length2 = arcLength * percent + width; UnitPointBulge retP2 = GetEndPointByLength(oriPoints, index, length2, true); var bridge = new BridgePoints(multiSegLine, retP1, retP2, HitUtil.Distance(p1, p)); retPoints.Add(bridge); }); } } else { //直线 var lineABC = DrawingOperationHelper.GetLineEquation(point1.Point, point2.Point); UnitPoint point = DrawingOperationHelper.GetIntersectionPointBy2Line(line.Item1, line.Item2, line.Item3, lineABC.Item1, lineABC.Item2, lineABC.Item3); if (!point.IsEmpty && HitUtil.IsPointInLine(point1.Point, point2.Point, point, 0.000001f) && HitUtil.IsPointInLine(p1, p2, point, 0.000001f)) { //第一个位置点 double lenght1 = HitUtil.Distance(point2.Point, point) + width; UnitPointBulge retP1 = GetEndPointByLength(oriPoints, index, lenght1, false); //第二个位置点 double lenght2 = HitUtil.Distance(point1.Point, point) + width; UnitPointBulge retP2 = GetEndPointByLength(oriPoints, index, lenght2, true); var bridge = new BridgePoints(multiSegLine, retP1, retP2, HitUtil.Distance(p1, point)); retPoints.Add(bridge); } } } return(retPoints); }
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); }