I am trying to write a function that will handle an array of arrays of CGRect containers, i.e. [[T]], where T is a struct containing a CGRect member called area. Some of these sub-arrays in some sense have a parallel start to each other: for the first member of each array, the CGRects overlap in one axis, and there is a fudge factor called overlapTolerance to capture CGRect's that almost overlap.
The function will return the indices of the parallel arrays, so [[Int]] with each [Int] containing two members. Unfortunately, it turns out the overlap could be either on the X axis or the Y axis, and I am struggling how to handle this elegantly.
Currently, the function looks like this, and is only built to handle parallel-ness in the y axis.
func findParallelSections(regions: [[T]], overlapTolerance: Double) throws -> [[Int]] {
var parallelRegionArray: [[Int]] = []
for mainRegion in regions {
if let mainRegionFirstMember = mainRegion.first {
// Get the upper bound and lower bound of the first member of each region, and add a little "fudge factor"
let upperBound = mainRegionFirstMember.area.maxY + (mainRegionFirstMember.area.height * overlapTolerance)
let lowerBound = mainRegionFirstMember.area.minY - (mainRegionFirstMember.area.height * overlapTolerance)
// Then get the middle of the first member of each of the other regions, and check if they are within the upper and lower bounds
for otherRegion in regions {
guard let otherRegionFirstMemberMiddle = otherRegion.first?.area.midY else {
throw AreaProcessingError.emptyRegion
}
if lowerBound < otherRegionFirstMemberMiddle, otherRegionFirstMemberMiddle < upperBound {
// Then the indexes of the arrays are added to parallelRegionArray, and there is some extra clean up of this array before it is returned.
I would like to make this able to handle either x or y axis overlap by doing something like this:
func findParallelSections(regions: [[T]], overlapTolerance: Double, axis: String) throws -> [[Int]] {
var parallelRegionArray: [[Int]] = []
switch axis {
case "x", "X":
var span: CGRect.width
var upperLimit: CGRect.maxX
var lowerLimit: CGRect.minX
var middle: CGRect.midX
case "y", "Y":
var span: CGRect.height
var upperLimit: CGRect.maxY
var lowerLimit: CGRect.minY
var middle: CGRect.midY
default:
throw AreaProcessingError.invalidAxis
}
// Then go on to leave the rest of the function unchanged except swapping in the right general overlap terms, e.g.
...
let upperBound = mainRegionFirstMember.area.upperLimit + (mainRegionFirstMember.area.span * overlapTolerance)
let lowerBound = mainRegionFirstMember.area.lowerLimit - (mainRegionFirstMember.area.span * overlapTolerance)
// etc.
However, when I try to set up the switch statement, I get the following kind of error for every variable in the switch:
Property 'width' is not a member type of 'CGRect'
What is going wrong? Width is a member of CGRect! Please tell me how I am being stupid.