UIBezierPath combine shapes - ios

This is not asking the same question as How can I combine UIBezierPath drawings? even though the name is similar
I have a shape that needs to be able to scale vertically and on one side of it are rounded corners and the other side is some other path. I have drawn the following image to show what I am talking about, but this is not the exact shape I am making, but conceptually it is the same idea.
In this image, the left side is half of a rounded rectangle and the right side is half of a circle.
So I am wanting to take and essentially cut a rounded rectangle in half and basically "merge" it with another path. How can I do this?
I guess one way would be to have two layers: the top layer contains the shape on the right and the bottom layer contains the rounded rectangle, and the top layer occludes half of the rectangle. But I was hoping to not have to use two different layers, and instead be able to put all of this in one layer, so I was wondering if it was possible to merge the shapes like I mentioned.

Related

Figure out if points lays in area

Given and image and 4 corner points of an area inside the image, I want to figure out if a point p (x,y) lays inside the given area. The area is not necessarily in form of a rectangle, as the area is the result of a perspective projection of some other image.
For example:
Here I want to figure out if the pink point actually lays within the shape inside the image. In this case it does.
I was thinking about drawing an contour with drawContours and then using pointPolygonTest but I was wondering if there is an easier and more tailored way of doing it.

Curved Shape Background Header in Flutter

I have a list view with "Hero" icons on the left. When I click a list item, it loads the next screen with the article text and the Hero image (which animates nicely/automatically to the correct spot on the 2nd screen).
I would have thought that was the "tough" part, but I'm now trying to get a curved shape as the top background of the 2nd screen. I would love to make it a drawn vector shape, as opposed to a bitmap and even have it drip/bounce onto the page, but at the moment...
I'm just trying to figure out how to:
draw a vector shape
have it as the background of a screen with other widgets on top (see purple curve on 2nd screen below)
I made a full sample for your curved shape in a gist here
I used CustomPainter to draw on a canvas then, with some geometric calculations, I achieved the curved shape.
Final result
How I draw it?
Before coding and on a Whiteboard I determined somethings:
My Canvas Area:
The canvas dimensions I need to draw that shape (which equals to Flutter widget's dimensions).
How and where my brush will move?
how means: what are the APIs I need to draw that shape on the canvas using the Path class.
e.g. lineTo() for a straight line, quadraticBezierTo() for a curve.
where means: Where are the points (coordinates) I need to draw the whole shape. (see yellow and green dots in the image above)
Points (coordinates) Calculations:
I used some geometric equations to calculate the coordinates. e.g. Point on a circle’s circumference
All of my calculations depend on the canvas size, that gives me a responsive shape.
Full sample here!

Rounding corner causes top edge to blur

I have a UIButton subclass that I am rounding the corners of. Using either the usual cornerRadius property on its layer, or creating a rounded mask and applying that to the layer, I always get the effect shown in the image below (blown up so you can see it clearly). The top pixel is slightly transparent, making the edge look soft. If I remove the rounded corners, the edge goes back to solid (like the bottom edge in the image), so I know it's not just trying to draw the view between pixels.
Any ideas?
Be sure that the frame and the mask are fully composed of integers not floats, in case use floor or ceil to get the closest integer rounding by low or top.
With frames CGRectIntegral is very helpful. Floats values automatically create a sort of antialiasing while rendering on screen.
What you see is anti-aliasing (on by default) to make the edges look smooth. This is the only way to make rounded corners look smooth and not stair stepped. If you want rough edges, set the allowsEdgeAntialiasing and edgeAntialiasingMask

How can I visually display points in a UIBezierPath?

I'm trying to change the shape of a CAShapeLayer from a circle to a different shape. Looking at this question:
Smooth shape shift animation
I found the solution but my question is how can I visually see how many points a UIBezierPath has. Is there a way to color a point different than the line it produces?
For example,it's simple with a line to understand that there are two point, but if we make a circle with bezierPathWithRoundedRect, does that count as one point or are there more?
You would need to add the circle yourself to visually see the dots. Just keep track of the CGPoints you give to the path and draw a circle around each one.
Btw.. if you use PaintCode, you can edit the bezier path and see the point -- it's very useful.

Curve line into circle in iOS

I have this idea of transforming a straight line into a circle but the offset of a cell drag in a table view.
As I drag the cell, I want the line to curve into a circle around an image.
I've included a picture below to help demonstrate different states with different drag offsets.
Im not sure where to start, was thinking of maybe using UIBezierPath to draw but not sure if that's the best solution.
If you want it to animate then you have your work cut out for you.
Core Animation of curves is based on CGPath objects, which is the underlying Core Foundation class behind UIBezierPath.
The secret to making a curve animate from one shape to another is to use the same number and type of control points. You won't be able to use any of the standard arc or oval shortcuts (which generate more complex bezier curves that look like arcs.)
Instead, you'll have to build an approximation of a circle piecewise out of a linked series of cubic bezier curves. You should be able to get fairly close with 4 linked cubic bezier curves who's endpoints line are at the N/S/E/W compass points of a circle, and the intermediate control points are spaced evenly outside the circle. A couple of years ago I looked up an article on the net for approximating a circle using Bezier points. I would suggest doing some searching on that.
Alternately, I guess you could generate a circle bezier curve using one of the CGPath or UIBezier shortcuts, then deconstruct the resulting path into the primitives that make it up. Erica Sadun's outstanding iOS Developer's Cookbook series includes a recipe that shows how to deconstruct a UIBezier path into it's primitives.
Once you have a set of control points for a circle, you would need to re-map them into control points that make your line. (A Bezier curve always passes through it's beginning and end points, and if you put the inner 2 control points of a Cubic Bezier on a line, it will turn the curve into a line.)
Now you have 2 shapes made up of the same number of bezier curves and the same number of control points: A circle and a line. You can transform the line into the circle or the circle into the line by moving each of the control points to different x/y coordinates.
Then you might be able to apply a linear interpolation between the starting and ending coordinates of your control points. Use the user's drag of the table view to generate a value from 0 to 1, and apply that to your interpolated control point values (at 0.0, your control points would be at their "straight line" position and your curve would draw as a straight line. At 1.0, they'd be at their circle position, and your curve would draw as a circle. At points between, they'd be a fraction of the way between their beginning and ending positions, and you'd get a shape that was between a line and a circle.
Once you have figured out how to generate the control points to create a curve that moves smoothly from a straight line to a circle, you are ready to tackle doing it using Core Animation and a CAShapeLayer.
If that makes sense then you can probably figure out how to do this. If you have no idea what I am talking about they you are probably in over your head.
(I'm a senior Cocoa/iOS developer. I've done a lot of Core Animation and it would probably take me 3 or 4 hours to get what you are after to work, once I had the circle bezier control points to start from.)
Come to think of it, it would probably be a lot simpler to use UIView keyframe animation. That lets you specify an array of control points that ALL lie on the desired curve, and generates a smooth curve from those points.. Best yet, it is a UIView animation, which is a heck of a lot easier to use than CAAnimation.
Take a look at my demo project RandomBlobs on github. That should give you a head start on using UIView keyframe animation. The method you want is called animateKeyframesWithDuration:delay:options:animations:completion:.
The down-side of point-based keyframe animation is that sometimes the curve you get has "kinks" or loops in it that you don't expect or want. You have to avoid sharp bends. In sketching it out, though, I think a line-to-circle transition might work with keyframe view animation.

Resources