public override bool Equals(object obj) { if (this == obj) { return(true); } if (obj == null || !GetType().IsEquivalentTo(obj.GetType())) { return(false); } ArcSegment other = (ArcSegment)obj; return(BeginPoint.Equals(other.BeginPoint) && EndPoint.Equals(other.EndPoint) && Center.Equals(other.Center) && ArcDirection.Equals(other.ArcDirection)); }
/// <summary> /// 给定圆弧,计算圆弧与圆弧之间的公切线段集合 /// </summary> /// <param name="rightArcSegment"></param> /// <returns></returns> public List <LineSegment> GetCommonTangentLinebyArcs(ArcSegment other) { ArcSegment leftArcSegment = null; ArcSegment rightArcSegment = null; if (this.Center.X < other.Center.X) { leftArcSegment = this; rightArcSegment = other; } else { leftArcSegment = other; rightArcSegment = this; } ArcSegmentArcRelationShipType type = leftArcSegment.GetRelationShipWithArc(rightArcSegment); //相交,外切,相离会用到两条 if (type == ArcSegmentArcRelationShipType.Insert || type == ArcSegmentArcRelationShipType.Apart || type == ArcSegmentArcRelationShipType.OuterTangent) { double r1 = leftArcSegment.Radius; double r2 = rightArcSegment.Radius; double dis = leftArcSegment.Center.DisTo(rightArcSegment.Center); double x = Math.Abs(dis * r1 / (r2 - r1)); double angle = Math.Asin(r1 / x); double dir0 = new LineSegment(leftArcSegment.Center, rightArcSegment.Center).GetDirection() - Math.PI / 2; LineSegment lineRadius = null; LineSegment lineRadius2 = null; if (r1 > r2) { lineRadius = new LineSegment(leftArcSegment.Center, rightArcSegment.Center); lineRadius.Rotate(leftArcSegment.Center, angle, ArcDirctionType.CLOCK_WISE); lineRadius.Move(dir0 + angle, r1); lineRadius2 = new LineSegment(leftArcSegment.Center, rightArcSegment.Center); lineRadius2.Rotate(leftArcSegment.Center, angle, ArcDirctionType.UNCLOCK_WISE); lineRadius2.Move(dir0 + Math.PI - angle, r1); } else { lineRadius = new LineSegment(leftArcSegment.Center, rightArcSegment.Center); lineRadius.Rotate(leftArcSegment.Center, angle, ArcDirctionType.UNCLOCK_WISE); lineRadius.Move(dir0 - angle, r1); lineRadius2 = new LineSegment(leftArcSegment.Center, rightArcSegment.Center); lineRadius2.Rotate(leftArcSegment.Center, angle, ArcDirctionType.CLOCK_WISE); lineRadius2.Move(dir0 - Math.PI + angle, r1); } List <LineSegment> list = new List <LineSegment>(); if (leftArcSegment.GetRelationShipwithLine(lineRadius) == LineArcRelationShipType.Tangent && rightArcSegment.GetRelationShipwithLine(lineRadius) == LineArcRelationShipType.Tangent) { list.Add(lineRadius); } if (leftArcSegment.GetRelationShipwithLine(lineRadius2) == LineArcRelationShipType.Tangent && rightArcSegment.GetRelationShipwithLine(lineRadius2) == LineArcRelationShipType.Tangent) { list.Add(lineRadius2); } return(list); } return(null); }
/// <summary> /// 给定直线段,计算圆弧和直线段所在直线间的公切圆,并返回满足指定半径的圆弧 /// </summary> /// <param name="line"></param> /// <param name="radius"></param> /// <returns></returns> public List <ArcSegment> GetCommonTangentArcsbyArcandLine(LineSegment line, double radius) { List <ArcSegment> list = new List <ArcSegment>(); List <Point3D> cacheList = new List <Point3D>(); double dir = line.GetDirection(); LineSegment line1 = line.CopyMove(dir - Math.PI / 2, radius) as LineSegment; //公切圆圆心所在的直线1 LineSegment line2 = line.CopyMove(dir + Math.PI / 2, radius) as LineSegment; //公切圆圆心所在的直线2 var r = this.Radius + radius; var r2 = Math.Abs(this.Radius - radius); //构造假想圆弧 ArcSegment arc = new ArcSegment(this.Center, r); ArcSegment arc2 = new ArcSegment(this.Center, r2); //1.如果圆弧与直线相切,最多存在四个所求圆 //2.如果圆弧与直线相交,最多存在八个所求圆 //3.如果圆弧与直线相离,可能存在两个所求圆 LineArcRelationShipType lineArcRelationShipType = GetRelationShipwithLine(line); if (lineArcRelationShipType == LineArcRelationShipType.Tangent || lineArcRelationShipType == LineArcRelationShipType.TangentWithArc) { var list1 = arc.GetIntersectPointsWithLine(line1); if (list1 != null && list1.Count > 0) { cacheList.AddRange(list1); } var list2 = arc2.GetIntersectPointsWithLine(line1); if (list2 != null && list2.Count > 0) { cacheList.AddRange(list2); } var list3 = arc.GetIntersectPointsWithLine(line2); if (list3 != null && list3.Count > 0) { cacheList.AddRange(list3); } var list4 = arc2.GetIntersectPointsWithLine(line2); if (list4 != null && list4.Count > 0) { cacheList.AddRange(list4); } } else if (lineArcRelationShipType == LineArcRelationShipType.Insert || lineArcRelationShipType == LineArcRelationShipType.InsertWithArc || lineArcRelationShipType == LineArcRelationShipType.InsertWithArcSegmentAndArc) { var list1 = arc.GetIntersectPointsWithLine(line1); if (list1 != null && list1.Count > 0) { cacheList.AddRange(list1); } var list2 = arc2.GetIntersectPointsWithLine(line1); if (list2 != null && list2.Count > 0) { cacheList.AddRange(list2); } var list3 = arc.GetIntersectPointsWithLine(line2); if (list3 != null && list3.Count > 0) { cacheList.AddRange(list3); } var list4 = arc2.GetIntersectPointsWithLine(line2); if (list4 != null && list4.Count > 0) { cacheList.AddRange(list4); } } else if (lineArcRelationShipType == LineArcRelationShipType.Apart) { var list1 = arc.GetIntersectPointsWithLine(line1); if (list1 != null && list1.Count > 0) { cacheList.AddRange(list1); } var list2 = arc.GetIntersectPointsWithLine(line2); if (list2 != null && list2.Count > 0) { cacheList.AddRange(list2); } } else if (lineArcRelationShipType == LineArcRelationShipType.Others) { return(null); } foreach (Point3D p in cacheList) { PointArcRelationShipType t = GetRelationShipWithPoint(p); if (t == PointArcRelationShipType.On_ArcSegment || t == PointArcRelationShipType.In_ArcSegment_Center || t == PointArcRelationShipType.To_ArcSegment_Center) { list.Add(new ArcSegment(p, radius)); } } return(list); }