COMP 1601 2021W Tutorial 3 Solutions 1. What is the initial coordinates of the box? Of the circle? What are these coordinates relative to? The initial coordinates of the box is (200, 400), while the circle is at (185, 100). These coordinates are relative to the top left corner of the screen but just below the "Drag the circle" Text. The circle and square are placed inside of a region that contains the whole screen except for what was used by the info bar at the top and the Text view. We can verify this by setting the coordinates for both to zero and seeing where the origin is. 2. How do you change the drag gesture to be processed "OnEnded" rather than "OnDrag"? How does this change the behaviour of the program? On line 35 just change the ".onChanged" to ".onEnded". This change makes it so the circle doesn't move during the drag, but once the user ends the drag (by lifting up their finger) the circle will appear wherever their finger last was. 3. Where does the circle have to be to get the success menu? Be precise in terms of coordinates. The center of the circle has to have the x and y coordinate of its center position within 20 pixels of the center of the box, i.e., the absolute value of box's x coordinate minus the circle's x coordinate should be less than 20, and the same for the y coordinates. This is what lines 44 and 45 calculate. 4. Where is view state being stored? Where is it being used? View state is being stored in the properties marked with a @State attribute in ContentView (location, line 10) and MovableCircle (isDragging, line 27). It is being used in the views with @Binding attributes marking location in MovableCircle (line 26) and SucessMsg (line 41). 5. How would you make the lines of the rectangle thinner? To make the rectangle lines thinner, reduce the lineWidth parameter being passed to the stroke method on line 16, in the ContentView view. 6. Can you make it impossible for the ball to enter the square (but allow it to be dragged everywhere else on the screen)? Yes, it is possible, we just have to constrain the position the onChanged handler of the drag gesture (lines 36 and 37). One way to do this is by replacing the handler as follows: .onChanged {value in let dx: Double = Double(abs(value.location.x - boxLocation.x)) let dy: Double = Double(abs(value.location.y - boxLocation.y)) let rectWidth = 200.0 let rectHeight = 200.0 let r = 64.0 if (dx > (rectWidth/2 + r)) || (dy > (rectHeight/2 + r)) { self.location = value.location } if (dx <= (rectWidth/2) || dy <= (rectHeight/2)) { return } let cdx = (dx - rectWidth/2.0) let cdy = (dy - rectHeight/2.0); let cornerDistance_sq = cdx * cdx + cdy * cdy if cornerDistance_sq > (r * r) { self.location = value.location } }) This answer is based on the following (2nd answer): https://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection 7. Do you see any regular closures here? If so, where are they being used and for what purpose? (Do not consider closures that are actually Views.) The only regular closure is the onChanged handler for the drag gesture on lines 35 and 36. We can tell it is a closure as it takes a parameter in with the "in" keyword.