/// <summary> /// 範囲を反転する /// </summary> /// <param name="r">範囲</param> /// <returns>反転された範囲</returns> public static DegRange Not(DegRange r) { r.NormalizeSelf(); r.Start += r.Size; r.Size = Degree.Full - r.Size; return(r); }
/// <summary> /// 2つの範囲を包含する範囲を作成する /// </summary> /// <param name="r1">範囲1</param> /// <param name="r2">範囲2</param> /// <returns>r1 と r2 を包含した範囲</returns> public static DegRange Union(DegRange r1, DegRange r2) { // 正規化しサイズが大きい方をメインr1とする r1.NormalizeSelf(); r2.NormalizeSelf(); if (r1.Size < r2.Size) { var t = r1; r1 = r2; r2 = t; } // 既にフルサイズかチェック if (Degree.Full <= r1.Size) { return(r1); } // r1 の開始点を0として r2 をシフトする var start2 = Degree.Sub(r2.Start, r1.Start); var end2 = start2 + r2.Size; // 既に r2 が r1 に包含されているかチェック if (0 <= start2 && end2 <= r1.Size) { return(r1); } // r2 の開始点が r1 の範囲内なら r1 のサイズを拡張する if (0 <= start2 && start2 <= r1.Size) { if (Degree.Full <= end2) { return(new DegRange(r1.Start, Degree.Full)); } r1.Size = end2; return(r1); } // r2 の終点が r1 の範囲内なら r1 の開始位置をシフトしサイズも拡張する if (0 <= end2 && end2 <= r1.Size) { if (Degree.Full + start2 <= r1.Size) { return(new DegRange(r1.Start, Degree.Full)); } return(new DegRange(Degree.Normalize(r1.Start + start2), r1.Size - start2)); } // r2 が r1 と接触していないなら r2 の開始点または終点の近い方と結合する var dstart = Math.Abs(Degree.Sub(start2, r1.Size)); var dend = Math.Abs(Degree.Sub(end2, 0)); if (dstart <= dend) { return(new DegRange(r1.Start, r1.Size + r2.Size + dstart)); } else { return(new DegRange(r2.Start, r1.Size + Math.Abs(start2))); } }