/// <summary> /// Gets the parameters required to draw an arc. /// </summary> private void GetArcParameters(C2DArc Arc, C2DRect Rect, ref int nStartAngle, ref int nSweepAngle) { C2DPoint Centre = Arc.GetCircleCentre(); Rect.Set(Centre.x - Arc.Radius, Centre.y + Arc.Radius, Centre.x + Arc.Radius, Centre.y - Arc.Radius); ScaleAndOffSet(Rect.TopLeft); ScaleAndOffSet(Rect.BottomRight); ScaleAndOffSet(Centre); // CR 19-1-09 C2DPoint bottomRightTemp = new C2DPoint(Rect.BottomRight); // to make valid // CR 11-3-09 Rect.BottomRight.Set(Rect.TopLeft); // to make valid // CR 11-3-09 Rect.ExpandToInclude(bottomRightTemp); // to make valid // CR 11-3-09 C2DPoint pt1 = Arc.Line.GetPointFrom(); C2DPoint pt2 = Arc.Line.GetPointTo(); this.ScaleAndOffSet(pt1); this.ScaleAndOffSet(pt2); C2DVector vec1 = new C2DVector(Centre, pt1); C2DVector vec2 = new C2DVector(Centre, pt2); C2DVector vecx = new C2DVector(100, 0); // x - axis double dStartAngle = vecx.AngleToLeft(vec1) * Constants.conDegreesPerRadian; double dSweepAngle = 0; bool bAlreadyFlipped = Scale.x * Scale.y < 0; if (Arc.ArcOnRight ^ bAlreadyFlipped) { dSweepAngle = vec1.AngleToLeft(vec2) * Constants.conDegreesPerRadian; } else { dSweepAngle = -vec1.AngleToRight(vec2) * Constants.conDegreesPerRadian; } nStartAngle = (int)dStartAngle; if (nStartAngle == 360) { nStartAngle = 0; } nSweepAngle = (int)dSweepAngle; }
/// <summary> /// True if this crosses a curved line. /// </summary> /// <param name="Other">The other arc.</param> /// <param name="IntersectionPts">The interection point list to recieve the result.</param> public bool Crosses(C2DArc Other, List <C2DPoint> IntersectionPts) { C2DCircle TestCircleThis = new C2DCircle(GetCircleCentre(), Radius); C2DCircle TestCircleOther = new C2DCircle(Other.GetCircleCentre(), Other.Radius); List <C2DPoint> IntPtsTemp = new List <C2DPoint>(); if (TestCircleThis.Crosses(TestCircleOther, IntPtsTemp)) { for (int i = IntPtsTemp.Count - 1; i >= 0; i--) { if ((Line.IsOnRight(IntPtsTemp[i]) ^ ArcOnRight) || Other.Line.IsOnRight(IntPtsTemp[i]) ^ Other.ArcOnRight || IntPtsTemp[i].PointEqualTo(Line.point) || IntPtsTemp[i].PointEqualTo(Line.GetPointTo()) || IntPtsTemp[i].PointEqualTo(Other.GetPointFrom()) || IntPtsTemp[i].PointEqualTo(Other.GetPointTo())) { IntPtsTemp.RemoveAt(i); } } if (IntPtsTemp.Count == 0) { return(false); } else { IntersectionPts.InsertRange(0, IntPtsTemp); // IntPtsTemp.CopyTo( IntersectionPts ); // (*IntersectionPts) << IntPtsTemp; return(true); } } else { return(false); } }
/// <summary> /// The distance between this and another arc. /// </summary> /// <param name="Other">The test point.</param> /// <param name="ptOnThis">The closest point on this to the other as a returned value.</param> /// <param name="ptOnOther">The closest point on the other to this as a returned value.</param> public double Distance(C2DArc Other, C2DPoint ptOnThis, C2DPoint ptOnOther) { List <C2DPoint> IntPts1 = new List <C2DPoint>(); List <C2DPoint> IntPts2 = new List <C2DPoint>(); C2DPoint ptThisCen = new C2DPoint(GetCircleCentre()); C2DPoint ptOtherCen = new C2DPoint(Other.GetCircleCentre()); C2DCircle CircleThis = new C2DCircle(ptThisCen, Radius); C2DCircle CircleOther = new C2DCircle(ptOtherCen, Other.Radius); if (CircleThis.Crosses(CircleOther, IntPts1)) { for (int i = 0; i < IntPts1.Count; i++) { if ((Line.IsOnRight(IntPts1[i]) == ArcOnRight) && (Other.Line.IsOnRight(IntPts1[i]) == Other.ArcOnRight)) { ptOnThis.Set(IntPts1[i]); ptOnOther.Set(IntPts1[i]); return(0); } } IntPts1.Clear(); } C2DLine LineCenToOther = new C2DLine(); LineCenToOther.point = new C2DPoint(ptThisCen); LineCenToOther.vector = new C2DVector(ptThisCen, ptOtherCen); LineCenToOther.GrowFromCentre(Math.Max(Radius, Other.Radius) * 10); double dMinDist = 1.7E308; double dDist = 0; if (Crosses(LineCenToOther, IntPts1) && Other.Crosses(LineCenToOther, IntPts2)) { for (int i = 0; i < IntPts1.Count; i++) { for (int j = 0; j < IntPts2.Count; j++) { dDist = IntPts1[i].Distance(IntPts2[j]); if (dDist < dMinDist) { ptOnThis.Set(IntPts1[i]); ptOnOther.Set(IntPts2[j]); dMinDist = dDist; } } } } C2DPoint ptOnThisTemp = new C2DPoint(); dDist = Distance(Other.GetPointFrom(), ptOnThisTemp); if (dDist < dMinDist) { ptOnThis.Set(ptOnThisTemp); ptOnOther.Set(Other.GetPointFrom()); dMinDist = dDist; } dDist = Distance(Other.GetPointTo(), ptOnThisTemp); if (dDist < dMinDist) { ptOnThis.Set(ptOnThisTemp); ptOnOther.Set(Other.GetPointTo()); dMinDist = dDist; } C2DPoint ptOnOtherTemp = new C2DPoint(); dDist = Other.Distance(GetPointFrom(), ptOnOtherTemp); if (dDist < dMinDist) { ptOnThis.Set(GetPointFrom()); ptOnOther.Set(ptOnOtherTemp); dMinDist = dDist; } dDist = Other.Distance(GetPointTo(), ptOnOtherTemp); if (dDist < dMinDist) { ptOnThis.Set(GetPointTo()); ptOnOther.Set(ptOnOtherTemp); dMinDist = dDist; } return(dMinDist); }
/// <summary> /// Gets the parameters required to draw an arc. /// </summary> private void GetArcParameters(C2DArc Arc, C2DRect Rect, ref int nStartAngle, ref int nSweepAngle) { C2DPoint Centre = Arc.GetCircleCentre(); Rect.Set(Centre.x - Arc.Radius, Centre.y + Arc.Radius, Centre.x + Arc.Radius, Centre.y - Arc.Radius); ScaleAndOffSet(Rect.TopLeft); ScaleAndOffSet(Rect.BottomRight); ScaleAndOffSet(Centre); // CR 19-1-09 C2DPoint bottomRightTemp = new C2DPoint(Rect.BottomRight); // to make valid // CR 11-3-09 Rect.BottomRight.Set(Rect.TopLeft); // to make valid // CR 11-3-09 Rect.ExpandToInclude(bottomRightTemp); // to make valid // CR 11-3-09 C2DPoint pt1 = Arc.Line.GetPointFrom(); C2DPoint pt2 = Arc.Line.GetPointTo(); this.ScaleAndOffSet(pt1); this.ScaleAndOffSet(pt2); C2DVector vec1 = new C2DVector(Centre, pt1); C2DVector vec2 = new C2DVector(Centre, pt2); C2DVector vecx = new C2DVector(100, 0); // x - axis double dStartAngle = vecx.AngleToLeft(vec1) * Constants.conDegreesPerRadian; double dSweepAngle = 0; bool bAlreadyFlipped = Scale.x * Scale.y < 0; if (Arc.ArcOnRight ^ bAlreadyFlipped) dSweepAngle = vec1.AngleToLeft(vec2) * Constants.conDegreesPerRadian; else dSweepAngle = -vec1.AngleToRight(vec2) * Constants.conDegreesPerRadian; nStartAngle = (int)dStartAngle; if (nStartAngle == 360) nStartAngle = 0; nSweepAngle = (int)dSweepAngle; }
/// <summary> /// The distance between this and another arc. /// </summary> /// <param name="Other">The test point.</param> /// <param name="ptOnThis">The closest point on this to the other as a returned value.</param> /// <param name="ptOnOther">The closest point on the other to this as a returned value.</param> public double Distance(C2DArc Other, C2DPoint ptOnThis, C2DPoint ptOnOther) { List<C2DPoint> IntPts1 = new List<C2DPoint>(); List<C2DPoint> IntPts2 = new List<C2DPoint>(); C2DPoint ptThisCen = new C2DPoint( GetCircleCentre() ); C2DPoint ptOtherCen = new C2DPoint(Other.GetCircleCentre()); C2DCircle CircleThis = new C2DCircle( ptThisCen, Radius); C2DCircle CircleOther = new C2DCircle( ptOtherCen, Other.Radius ); if (CircleThis.Crosses( CircleOther , IntPts1 ) ) { for (int i = 0; i < IntPts1.Count; i++) { if ( (Line.IsOnRight( IntPts1[i] ) == ArcOnRight ) && (Other.Line.IsOnRight( IntPts1[i] ) == Other.ArcOnRight ) ) { ptOnThis.Set(IntPts1[i]); ptOnOther.Set(IntPts1[i]); return 0; } } IntPts1.Clear(); } C2DLine LineCenToOther = new C2DLine(); LineCenToOther.point = new C2DPoint(ptThisCen); LineCenToOther.vector = new C2DVector(ptThisCen, ptOtherCen); LineCenToOther.GrowFromCentre( Math.Max(Radius, Other.Radius) * 10); double dMinDist = 1.7E308; double dDist = 0; if ( Crosses(LineCenToOther, IntPts1) && Other.Crosses(LineCenToOther, IntPts2)) { for (int i = 0 ; i < IntPts1.Count; i++) { for (int j = 0 ; j < IntPts2.Count; j++) { dDist = IntPts1[i].Distance(IntPts2[j]); if (dDist < dMinDist) { ptOnThis.Set( IntPts1[i]); ptOnOther.Set( IntPts2[j]); dMinDist = dDist; } } } } C2DPoint ptOnThisTemp = new C2DPoint(); dDist = Distance(Other.GetPointFrom(), ptOnThisTemp); if (dDist < dMinDist) { ptOnThis.Set(ptOnThisTemp); ptOnOther.Set(Other.GetPointFrom()); dMinDist = dDist; } dDist = Distance(Other.GetPointTo(), ptOnThisTemp); if (dDist < dMinDist) { ptOnThis.Set(ptOnThisTemp); ptOnOther.Set(Other.GetPointTo()); dMinDist = dDist; } C2DPoint ptOnOtherTemp = new C2DPoint(); dDist = Other.Distance(GetPointFrom(), ptOnOtherTemp); if (dDist < dMinDist) { ptOnThis.Set( GetPointFrom()); ptOnOther.Set( ptOnOtherTemp); dMinDist = dDist; } dDist = Other.Distance(GetPointTo(), ptOnOtherTemp); if (dDist < dMinDist) { ptOnThis.Set( GetPointTo()); ptOnOther.Set( ptOnOtherTemp); dMinDist = dDist; } return dMinDist; }
/// <summary> /// True if this crosses a curved line. /// </summary> /// <param name="Other">The other arc.</param> /// <param name="IntersectionPts">The interection point list to recieve the result.</param> public bool Crosses(C2DArc Other, List<C2DPoint> IntersectionPts) { C2DCircle TestCircleThis = new C2DCircle (GetCircleCentre(), Radius); C2DCircle TestCircleOther= new C2DCircle (Other.GetCircleCentre(), Other.Radius); List<C2DPoint> IntPtsTemp = new List<C2DPoint>(); if (TestCircleThis.Crosses(TestCircleOther, IntPtsTemp)) { for (int i = IntPtsTemp.Count - 1; i >= 0 ; i--) { if ((Line.IsOnRight(IntPtsTemp[i]) ^ ArcOnRight) || Other.Line.IsOnRight(IntPtsTemp[i]) ^ Other.ArcOnRight || IntPtsTemp[i].PointEqualTo( Line.point) || IntPtsTemp[i].PointEqualTo( Line.GetPointTo()) || IntPtsTemp[i].PointEqualTo( Other.GetPointFrom()) || IntPtsTemp[i].PointEqualTo( Other.GetPointTo())) { IntPtsTemp.RemoveAt(i); } } if (IntPtsTemp.Count == 0) return false; else { IntersectionPts.InsertRange(0, IntPtsTemp); // IntPtsTemp.CopyTo( IntersectionPts ); // (*IntersectionPts) << IntPtsTemp; return true; } } else { return false; } }