Skip to main content
Corrected function name
Source Link
private bool EitherAngleStartsBetweenOthersRange(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  if (FirstAngleRange._from > SecondAngleRange._from 
      && FirstAngleRange._from < SecondAngleRange._to)
  {
     return true;
  }
  if (SecondAngleRange._from > FirstAngleRange._from 
      && SecondAngleRange._from < FirstAngleRange._to)
  {
     return true;
  }

  return false;
}

private bool EitherAngleFinishBetweenOthersRangeEitherAngleEndsBetweenOthersRange(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  if (FirstAngleRange._to > SecondAngleRange._from 
      && FirstAngleRange._to < SecondAngleRange._to)
  {
     return true;
  }
  if (SecondAngleRange._to > FirstAngleRange._from 
      && SecondAngleRange._to < FirstAngleRange._to)
  {
     return true;
  }

  return false;
}
private bool EitherAngleStartsBetweenOthersRange(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  if (FirstAngleRange._from > SecondAngleRange._from 
      && FirstAngleRange._from < SecondAngleRange._to)
  {
     return true;
  }
  if (SecondAngleRange._from > FirstAngleRange._from 
      && SecondAngleRange._from < FirstAngleRange._to)
  {
     return true;
  }

  return false;
}

private bool EitherAngleFinishBetweenOthersRange(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  if (FirstAngleRange._to > SecondAngleRange._from 
      && FirstAngleRange._to < SecondAngleRange._to)
  {
     return true;
  }
  if (SecondAngleRange._to > FirstAngleRange._from 
      && SecondAngleRange._to < FirstAngleRange._to)
  {
     return true;
  }

  return false;
}
private bool EitherAngleStartsBetweenOthersRange(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  if (FirstAngleRange._from > SecondAngleRange._from 
      && FirstAngleRange._from < SecondAngleRange._to)
  {
     return true;
  }
  if (SecondAngleRange._from > FirstAngleRange._from 
      && SecondAngleRange._from < FirstAngleRange._to)
  {
     return true;
  }

  return false;
}

private bool EitherAngleEndsBetweenOthersRange(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  if (FirstAngleRange._to > SecondAngleRange._from 
      && FirstAngleRange._to < SecondAngleRange._to)
  {
     return true;
  }
  if (SecondAngleRange._to > FirstAngleRange._from 
      && SecondAngleRange._to < FirstAngleRange._to)
  {
     return true;
  }

  return false;
}
Source Link

Your method name should probably be "AngleRangesIntersect" looking at its return type. Seems like your one little function is trying to do a bit too much. It's not merging the angle ranges but checking if there's an intersection between them. First let's get this logic a function of its own, then we can build a "MergeAngleRanges" one on top of that.

Something like this should do the trick for checking if they intersect:

private bool AngleRangesIntersect(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  if (FirstAngleRange._from > SecondAngleRange._from 
      && FirstAngleRange._from < SecondAngleRange._to)
  {
     return true;
  }
  if (SecondAngleRange._from > FirstAngleRange._from 
      && SecondAngleRange._from < FirstAngleRange._to)
  {
     return true;
  }
  if (FirstAngleRange._to > SecondAngleRange._from 
      && FirstAngleRange._to < SecondAngleRange._to)
  {
     return true;
  }
  if (SecondAngleRange._to > FirstAngleRange._from 
      && SecondAngleRange._to < FirstAngleRange._to)
  {
     return true;
  }

  return false;
}

Obviously this is a bit of a hot mess riddled with duplication so I'd probably extract these conditionals out into their own private functions:

private bool EitherAngleStartsBetweenOthersRange(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  if (FirstAngleRange._from > SecondAngleRange._from 
      && FirstAngleRange._from < SecondAngleRange._to)
  {
     return true;
  }
  if (SecondAngleRange._from > FirstAngleRange._from 
      && SecondAngleRange._from < FirstAngleRange._to)
  {
     return true;
  }

  return false;
}

private bool EitherAngleFinishBetweenOthersRange(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  if (FirstAngleRange._to > SecondAngleRange._from 
      && FirstAngleRange._to < SecondAngleRange._to)
  {
     return true;
  }
  if (SecondAngleRange._to > FirstAngleRange._from 
      && SecondAngleRange._to < FirstAngleRange._to)
  {
     return true;
  }

  return false;
}

Then we can pop the refactor in and enjoy a much nicer Check:

public bool AngleRangesIntersect(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  if (EitherAngleStartsBetweenOthersRange(FirstAngleRange, SecondAngleRange))
  {
    return true;
  }
  if (EitherAngleEndsBetweenOthersRange(FirstAngleRange, SecondAngleRange))
  {
    return true;
  }

  return false;
}

Now that we have that bit of the logic squared away we can mosey on to the merging of the angles. Now as far as I understand it what you're trying to do is:

If the angles intersect, create one god angle with the max upper and lower bound.

for that we'd probably stick a couple of extra functions in to return the min and max for angles.

private double GetSmallestLowerBound(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  // Allow for cases like (355, 10) merging with (5, 350)
  if (FirstAngleRange._from < SecondAngleRange._from ||
      FirstAngleRange._from > SecondAngleRange._to)
  {
    return FirstAngleRange._from;
  }
  
  return SecondAngleRange._from;
}

private double GetLargestUpperBound(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  // Allow for cases like (20, 10) merging with (15, 25) 
  if (FirstAngleRange._to > SecondAngleRange._to ||
      FirstAngleRange._to < SecondAngleRange._from)
  {
    return FirstAngleRange._to;
  }
  
  return SecondAngleRange._to;
}

Now that we have all the pieces we can put together our final merge method:

public AngleRange MergeAngleRanges(AngleRange FirstAngleRange, AngleRange SecondAngleRange)
{
  if (AngleRangesIntersect(FirstAngleRange, SecondAngleRange))
  {
    return new AngleRange(GetSmallestLowerBound(FirstAngleRange, SecondAngleRange),
                          GetLargestUpperBound(FirstAngleRange, SecondAngleRange)));
  }
  return new AngleRange(0.0f, 0.0f);
}

Any troubles give me a shout.