/// <summary> /// 给定方向计算圆弧切线 /// </summary> /// <param name="dir"></param> /// <returns></returns> public List <LineSegment> GetTangentPointbyDir(double dir) { List <LineSegment> list = new List <LineSegment>(); LineSegment line = new LineSegment(this.Center, 1000, dir); line.Move(Math.PI / 2 + dir, this.Radius); LineArcRelationShipType type = GetRelationShipwithLine(line); if (type == LineArcRelationShipType.Tangent) //直线为圆弧的切线的情况下 { list.Add(line); } LineSegment line2 = new LineSegment(this.Center, 1000, dir); line2.Move(-Math.PI / 2 + dir, this.Radius); //相反方向移动 LineArcRelationShipType type2 = GetRelationShipwithLine(line2); if (type2 == LineArcRelationShipType.Tangent) //直线为圆弧的切线的情况下 { list.Add(line2); } return(list); }
/// <summary> /// 计算传入的射线和当前圆弧位置关系 /// </summary> /// <param name="line">传入的射线</param> /// <returns></returns> public override LineCurveRelationShipType GetCurveCurveRelationShipType(LineSegment line) { LineArcRelationShipType type = GetRelationShipwithLine(line); var dir = line.GetTurnDirection(this.Center); if (type == LineArcRelationShipType.Apart) //相离 { if (dir == TurnDirectionType.Left) { return(LineCurveRelationShipType.Left); } else { return(LineCurveRelationShipType.Right); } } else if (type == LineArcRelationShipType.Insert) //和圆弧相交 { if (this.BeginPoint.Equals(this.EndPoint)) { return(LineCurveRelationShipType.Intersect); } else { //1.半圆情况下,可能begin,end点为交点,则onleft或onright /* * (1)过begin,end点做直线 * (2)过直线中心做垂线,交圆弧于点p * (3)判断点p和直线的位置关系 */ //2.交点存在非begin,end点,则为intersect TurnDirectionType dirB = line.GetTurnDirection(this.BeginPoint); TurnDirectionType dirE = line.GetTurnDirection(this.EndPoint); if (dirB == TurnDirectionType.Stright && dirE == TurnDirectionType.Stright) { Point3D lineCenterPoint = new Point3D() { X = (this.BeginPoint.X + this.EndPoint.X) / 2, Y = (this.BeginPoint.Y + this.EndPoint.Y) / 2, Z = (this.BeginPoint.Z + this.EndPoint.Z) / 2 }; LineSegment centerLine = new LineSegment(lineCenterPoint, 1, line.GetDirection() + Math.PI / 2); List <Point3D> listPoint = this.GetIntersectPointsWithLine(centerLine.BeginPoint, centerLine.EndPoint); if (listPoint != null && listPoint.Count > 0) { if (line.GetTurnDirection(listPoint[0]) == TurnDirectionType.Right) { return(LineCurveRelationShipType.On_Right); } else if (line.GetTurnDirection(listPoint[0]) == TurnDirectionType.Left) { return(LineCurveRelationShipType.On_Left); } } } else { return(LineCurveRelationShipType.Intersect); } } } else if (type == LineArcRelationShipType.InsertWithArc) //和圆弧所在的圆相交 { if (this.BeginPoint.Equals(this.EndPoint)) { } else { //只有半圆存在该情况 if (line.GetTurnDirection(this.BeginPoint) == TurnDirectionType.Left) { return(LineCurveRelationShipType.Left); } else { return(LineCurveRelationShipType.Right); } } } else if (type == LineArcRelationShipType.InsertWithArcSegmentAndArc) //和圆弧,圆弧所在的圆分别相交 { if (this.BeginPoint.Equals(this.EndPoint)) { } else { //只有半圆存在该情况 TurnDirectionType dirB = line.GetTurnDirection(this.BeginPoint); TurnDirectionType dirE = line.GetTurnDirection(this.EndPoint); if ((dirB == TurnDirectionType.Right && dirE == TurnDirectionType.Left) || (dirB == TurnDirectionType.Left && dirE == TurnDirectionType.Right)) { return(LineCurveRelationShipType.Intersect); } else if ((dirB == TurnDirectionType.Right && dirE == TurnDirectionType.Stright) || (dirB == TurnDirectionType.Stright && dirE == TurnDirectionType.Right)) { return(LineCurveRelationShipType.On_Right); } else if ((dirB == TurnDirectionType.Left && dirE == TurnDirectionType.Stright) || (dirB == TurnDirectionType.Stright && dirE == TurnDirectionType.Left)) { return(LineCurveRelationShipType.On_Left); } } } else if (type == LineArcRelationShipType.Tangent) //和圆弧相切 { if (dir == TurnDirectionType.Left) { return(LineCurveRelationShipType.On_Left); } else { return(LineCurveRelationShipType.On_Right); } } else if (type == LineArcRelationShipType.TangentWithArc) //和圆弧所在的圆相切 { if (this.BeginPoint.Equals(this.EndPoint)) { } else { //只有半圆存在该情况 if (dir == TurnDirectionType.Left) { return(LineCurveRelationShipType.Left); } else { return(LineCurveRelationShipType.Right); } } } return(LineCurveRelationShipType.Others); }
/// <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); }
public void GetRelationShipwithLineTest() { //Case1: 相离 Point3D p11 = new Point3D() { X = 1.5, Y = 1, Z = 0 }; Point3D p12 = new Point3D() { X = 1.4, Y = -1, Z = 0 }; LineSegment line1 = new LineSegment(p11, p12); LineArcRelationShipType type11 = this.ArcSegment_Part.GetRelationShipwithLine(line1); Assert.AreEqual(type11, LineArcRelationShipType.Apart); LineArcRelationShipType type12 = this.ArcSegment_Full.GetRelationShipwithLine(line1); Assert.AreEqual(type12, LineArcRelationShipType.Apart); //Case2: 相切(线段) Point3D p21 = new Point3D() { X = 1, Y = 1, Z = 0 }; Point3D p22 = new Point3D() { X = 1, Y = -1, Z = 0 }; LineSegment line2 = new LineSegment(p21, p22); LineArcRelationShipType type21 = this.ArcSegment_Part.GetRelationShipwithLine(line2); Assert.AreEqual(type21, LineArcRelationShipType.Tangent); LineArcRelationShipType type22 = this.ArcSegment_Full.GetRelationShipwithLine(line2); Assert.AreEqual(type22, LineArcRelationShipType.Tangent); //Case3: 相切(线段所在的圆) Point3D p31 = new Point3D() { X = -1, Y = 1, Z = 0 }; Point3D p32 = new Point3D() { X = -1, Y = -1, Z = 0 }; LineSegment line3 = new LineSegment(p31, p32); LineArcRelationShipType type31 = this.ArcSegment_Part.GetRelationShipwithLine(line3); Assert.AreEqual(type31, LineArcRelationShipType.TangentWithArc); //Case4: 相交(线段) Point3D p41 = new Point3D() { X = 1, Y = 0, Z = 0 }; Point3D p42 = new Point3D() { X = 0, Y = 1, Z = 0 }; LineSegment line4 = new LineSegment(p41, p42); LineArcRelationShipType type41 = this.ArcSegment_Part.GetRelationShipwithLine(line4); Assert.AreEqual(type41, LineArcRelationShipType.Insert); LineArcRelationShipType type42 = this.ArcSegment_Full.GetRelationShipwithLine(line4); Assert.AreEqual(type42, LineArcRelationShipType.Insert); //Case5: 相交(线段所在的圆) Point3D p51 = new Point3D() { X = -1, Y = 0, Z = 0 }; Point3D p52 = new Point3D() { X = 0, Y = -1, Z = 0 }; LineSegment line5 = new LineSegment(p51, p52); LineArcRelationShipType type51 = this.ArcSegment_Part.GetRelationShipwithLine(line5); Assert.AreEqual(type51, LineArcRelationShipType.InsertWithArc); //Case6: 相交(线段和线段所在的圆) Point3D p61 = new Point3D() { X = 1, Y = 0, Z = 0 }; Point3D p62 = new Point3D() { X = 0, Y = -1, Z = 0 }; LineSegment line6 = new LineSegment(p61, p62); LineArcRelationShipType type61 = this.ArcSegment_Part.GetRelationShipwithLine(line6); Assert.AreEqual(type61, LineArcRelationShipType.InsertWithArcSegmentAndArc); Point3D p71 = new Point3D() { X = 0.5, Y = 0.5, Z = 0 }; Point3D p72 = new Point3D() { X = -0.5, Y = -0.5, Z = 0 }; LineSegment line7 = new LineSegment(p71, p72); LineArcRelationShipType type71 = this.ArcSegment_Part.GetRelationShipwithLine(line7); Assert.AreEqual(type71, LineArcRelationShipType.InsertWithArcSegmentAndArc); }