I have array of CGPoint indicated in red. I must connect all consecutive points with CGRect as shown in the rough figure to form an array of CGRect. Consider all rect has a constant width and each point could be the mid point of the sides formed from width of the rect. How could I form this array of CGRect?
EDIT:
Here is what I am trying to do. As described in my previous question, I am trying to introduce an eraser function.
I have a set of straight lines (in green). I basically contain the start and end points of the line in model. When in eraser mode, user is allowed to draw freely and all draw points are connected by stroke (in purple).
When any green line is completely covered, the line must be identified to be erased. But, I couldn't able to determine if the line is completed covered by the eraser's draw points.
As in comments, I tried to follow the answer here. All I have is CGPoints and I have no CGRects. I check the intersection of both green and purple path as below and it returns false.
public override func draw(_ rect: CGRect) {
let wallPath = UIBezierPath()
wallPath.move(to: CGPoint(x: 50.0, y: 50.0))
wallPath.addLine(to: CGPoint(x: 50.0, y: 400.0))
wallPath.addLine(to: CGPoint(x: 300.0, y: 400.0))
wallPath.addLine(to: CGPoint(x: 300.0, y: 50.0))
let wallLayer = CAShapeLayer()
wallLayer.path = wallPath.cgPath
wallLayer.lineWidth = 10
wallLayer.strokeColor = UIColor.green.cgColor
wallLayer.fillColor = nil
layer.addSublayer(wallLayer)
let eraserPath = UIBezierPath()
eraserPath.move(to: CGPoint(x: 40.0, y: 75.0))
eraserPath.addLine(to: CGPoint(x: 120.0, y: 75.0))
let eraserLayer = CAShapeLayer()
eraserLayer.path = eraserPath.cgPath
eraserLayer.lineWidth = 15
eraserLayer.strokeColor = UIColor.purple.cgColor
layer.addSublayer(eraserLayer)
if wallPath.cgPath.intersects(eraserPath.cgPath) {
print("Overlapping")
} else {
print("Not overlapping")
}
}
To make it more clear about the requirement, when user draws in eraser mode, based on the draw points, I have to identify which green line falls completely in the purple stroke's coverage and the identified green line must be taken for further processing. Multiple green lines could be selected at the same time.



CGPathhas an.lineIntersection(_:using:)method that can come in really handy here...Let's start with a single line path:
We create an "eraser" path - using
strokingWithWidthinstead of.lineWidthso we get a "filled" outline path - and cross the path:When we call:
That returns a new path, consisting of
.move(to: pt1)and.addLine(to: pt2)- if we draw thatiPthin cyan we see:We can then easily compare the resulting path to the original path and determine that the original is not completely encompassed.
If we continue defining our eraser path:
and call
segPth.lineIntersection(eraserPth)again, it will return a path ofmove to+line to+move to+line to:and again, we can easily determine that it is not the same path as the original line segment.
If we keep adding points to the eraser path until we get this:
segPth.lineIntersection(eraserPth)will now return a path:That matches the original.
So... a couple notes first...
Define your "walls" path as a series of "line segments" rather than a single path:
That makes it easy to:
.lineIntersection()Next, because
pointsuse floating-point values, and UIKit likes whole numbers, we can save ourselves some headaches byroundingeverything.For example, if we have a line from
20, 10to80, 10, and we have an eraser path that encompasses the entire line path, we might get a returned path from.lineIntersection()with points like20.00001, 10.0to79.99997, 10.000001.Here is a complete example to play with...
The
LineSegmentstruct:extensionto round the x,y values of a point:This
extensionto return the points of a path (found here: How to get the CGPoint(s) of a CGPath):A
UIViewsubclass, with shape layers, path logic, and touch handling:and a simple view controller to show it in use:
Here's what it looks like when running: