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); }
public static ArcModelMini GetArcParametersFromThreePoints(UnitPoint startPoint, UnitPoint midPoint, UnitPoint endPoint) { ArcModelMini arcModel = new ArcModelMini(); arcModel.Clockwise = HitUtil.IsClockwiseByCross(startPoint, midPoint, endPoint); arcModel.Center = HitUtil.CenterPointFrom3Points(startPoint, midPoint, endPoint); arcModel.Radius = (float)HitUtil.Distance(arcModel.Center, startPoint); arcModel.StartAngle = (float)HitUtil.RadiansToDegrees(HitUtil.LineAngleR(arcModel.Center, startPoint, 0)); float EndAngle = (float)HitUtil.RadiansToDegrees(HitUtil.LineAngleR(arcModel.Center, endPoint, 0)); arcModel.SweepAngle = (float)HitUtil.CalAngleSweep(arcModel.StartAngle, EndAngle, arcModel.Clockwise); return(arcModel); }
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); }
//TODO:此方法可能存在问题 public static bool IsLineOnArc(UnitPoint p1, UnitPoint p2, UnitPoint center, float radius, double startAngle, double angleSweep, bool clockwise, float thWidth) { List <UnitPoint> unitPoints = HitUtil.GetIntersectPointLineWithCircle(p1, p2, center, radius, thWidth); for (int i = 0; i < unitPoints.Count; i++) { double angle = HitUtil.LineAngleR(center, unitPoints[i], 0); angle = HitUtil.RadiansToDegrees(angle); double sweepAngle = HitUtil.CalAngleSweep(startAngle, angle, clockwise); if (Math.Abs(angleSweep) > Math.Abs(sweepAngle)) { return(true); } } return(false); }
private void CalAngleAndDirection(UnitPoint lastPoint) { double angle = HitUtil.LineAngleR(this.FirstPoint, lastPoint, 0); double angle2 = HitUtil.LineAngleR(this.FirstPoint, this.ThirdPoint, 0); this.LastPoint = this.ThirdPoint; double theta = angle2 - angle; if (theta > Math.PI) { theta -= Math.PI * 2; } else if (theta < -Math.PI) { theta += Math.PI * 2; } clockwise = theta >= 0 ? false : true; this.rotateAngle = Math.Abs(HitUtil.RadiansToDegrees(theta)); }
/// <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); }
private static List <IDrawObject> ConvertToMultiSegLine(ArcBase arc, List <BridgePoints> bridges) { List <IDrawObject> retObjects = new List <IDrawObject>(); if (bridges.Count == 2) { double angle1 = HitUtil.LineAngleR(arc.Center, bridges[0].Point1.Point, 0); double angle2 = HitUtil.LineAngleR(arc.Center, bridges[1].Point1.Point, 0); angle1 = HitUtil.CalAngleSweep(arc.StartAngle, HitUtil.RadiansToDegrees(angle1), arc.IsClockwise); angle2 = HitUtil.CalAngleSweep(arc.StartAngle, HitUtil.RadiansToDegrees(angle2), arc.IsClockwise); if (angle1 > angle2) { bridges.Reverse(); } double bulge1 = BulgeHelper.GetBulgeFromTwoPointsAndCenter(arc.Center, arc.startPoint, bridges[0].Point1.Point, arc.IsClockwise); retObjects.Add(new MultiSegmentLineBase() { IsCloseFigure = false, LayerId = arc.LayerId, GroupParam = CopyUtil.DeepCopy(arc.GroupParam), Points = new List <UnitPointBulge>() { new UnitPointBulge(arc.startPoint, bulge1), bridges[0].Point1 } }); bridges[0].Point2.Bulge = BulgeHelper.GetBulgeFromTwoPointsAndCenter(arc.Center, bridges[0].Point2.Point, bridges[1].Point1.Point, arc.IsClockwise);; retObjects.Add(new MultiSegmentLineBase() { IsCloseFigure = false, LayerId = arc.LayerId, GroupParam = CopyUtil.DeepCopy(arc.GroupParam), Points = new List <UnitPointBulge>() { bridges[0].Point2, bridges[1].Point1 } }); bridges[1].Point2.Bulge = BulgeHelper.GetBulgeFromTwoPointsAndCenter(arc.Center, bridges[1].Point2.Point, arc.endPoint, arc.IsClockwise);; retObjects.Add(new MultiSegmentLineBase() { IsCloseFigure = false, LayerId = arc.LayerId, GroupParam = CopyUtil.DeepCopy(arc.GroupParam), Points = new List <UnitPointBulge>() { bridges[1].Point2, new UnitPointBulge(arc.endPoint, bridges[1].Point2.Bulge) } }); } else if (bridges.Count == 1) { double bulge1 = BulgeHelper.GetBulgeFromTwoPointsAndCenter(arc.Center, arc.startPoint, bridges[0].Point1.Point, arc.IsClockwise); retObjects.Add(new MultiSegmentLineBase() { IsCloseFigure = false, LayerId = arc.LayerId, GroupParam = CopyUtil.DeepCopy(arc.GroupParam), Points = new List <UnitPointBulge>() { new UnitPointBulge(arc.startPoint, bulge1), bridges[0].Point1 } }); bridges[0].Point2.Bulge = BulgeHelper.GetBulgeFromTwoPointsAndCenter(arc.Center, bridges[0].Point2.Point, arc.endPoint, arc.IsClockwise);; retObjects.Add(new MultiSegmentLineBase() { IsCloseFigure = false, LayerId = arc.LayerId, GroupParam = CopyUtil.DeepCopy(arc.GroupParam), Points = new List <UnitPointBulge>() { bridges[0].Point2, new UnitPointBulge(arc.endPoint, bridges[0].Point2.Bulge) } }); } return(retObjects); }