I implement a free hand drawing module using UIBezierPath, but i want to get the all frame of the curve after i finish drawing, how can i do it.
And if there a way to get the path point for a connected path, it will be great.
Your question is not entirely clear, but if you want the bounding rectangle of a UIBezierPath, there is a bounds property.
If you want to know the position of the last point to connect another path, there is the currentPoint property.
If you want to examine the different parts of the path, you'll have to go down to the underlying CGPath, and the CGPathApply function.
If you want to test if a point is inside the path (would be filled), you can use the containsPoint: method, and if you want to test if a point is part of the path, you will have to do the math yourself using the Bézier formulas...
Related
I am working on creating a way for a user to move polygons on screen and change their shape by dragging their corner vertices. I then need to be able to re-draw those modified polygons on other devices - so I need to be able to get final positions of all vertices for all polygons on screen.
This is what I am currently doing:
I draw polygons using UIBezierPath for each shape in the override of the drawRect function. I then allow user to drag them around the screen by applying CGAffineTransformMakeTranslation function and the x and y coordinate deltas in touchedMoved function override. I have the initial control points from which initial polygons are drawn (as described here). But once a path instance is moved on screen, those values don't change - so I am only able to get initial values.
Is there something built - in in the Core Graphics framework that will allow me to grab a set of current control points in a UIBezierPath instance? I am trying to avoid keeping track of those points manually. I will consider using other ways to draw if:
there is a built - in way to detect if a point lies within that polygon (such as UIBezierPath#contains method
A way to easily introduce constraints so user can't move a polygon out of bounds of the superview (I need the whole polygon to be visible)
A way to grab all points easily when user is done
Everything can run under 60fps on iPhone 5.
Thanks for your time!
As you're only applying the transform to the view/layer, to get the transformed control points from the path, simply apply that same transform to the path, and then fetch the control points. Something like:
UIBezierPath* copiedPath = [myPath copy];
[copiedPath applyTransform:[view transform]];
[self yourExistingMethodToFetchPointsFromPath:copiedPath];
The way that you're currently pulling out points from a path is unfortunately at the only API available for re-fetching points from an input UIBezierPath. However - you might be interested in a library I wrote to make working with Bezier path's much simpler: PerformanceBezier. This library makes it significantly easier to get the points from a path:
for(NSInteger i=0;i<[path elementCount];i++){
CGPathElement element = [path elementAtIndex:n];
// now you know the element.type and the element.points
}
In addition to adding functionality to make paths easier to work with, it also adds a caching layer on top of the existing API to make the performance hit of working with paths much much smaller. Depending on how much CPU time you're spending on UIBezierPath methods, this library will make a significant improvement. I saw between 2x and 10x improvement, depending on the operations I was using.
I want to draw a path and then change it's shape by touching the control points of the path, would it be better to use uibezierpath or core graphics for this purpose and why? I want to get access to the path after im done with modifying it's shape. Thank you.
You're going to want to keep the control points in your own data structure, because neither UIBezierPath nor CGPath provides a convenient way to get at or modify the existing control points of the path.
That said, it's generally easier to use the UIKit drawing API if it covers your needs, so you'll want to convert your data structure to a UIBezierPath to draw it each time the user makes a change.
I want to achieve the following by code:
Based on a circular path or arc, I need to place other views evenly around the perimeter.
Is this possible without hardcoding the frames? If so, how?
In addition to that, can I make a view to follow a path ? if so, how?
Update:
I found this answer helpful, but it seems to use a lot of code though...
Place images along a bezier path
It's easy. A view is a layer.
A layer is positioned by its anchor point. So place the layer's anchor point at the center of the circular path, and define the anchor point at a sufficient size to move the layer away from the center to lie on the desired radius.
Moreover, a layer is rotated around around its anchor point, so now just apply a rotation transform in an increment of nths of a circle, where, n is the number of views.
As you can see, I can easily draw your sub-circles evenly spaced out, given any number of desired sub-circles:
I want to have a path that my node can travel around on demand.
For example, I want to have a circle in the middle of the screen and when i tap the left side of the screen, my SKSpriteNode will move in a counter-clockwise direction on the circle (and the same if i tap the right side of the screen).
From what I've researched, I can create the circular path using SKShapeNode, CGPathRef, or even UIBezierPath. Creating the path isn't the issue. In all the instances I've seen researching this topic, most people just use [SKAction followPath:path duration:1.0] and this makes the node go around the the circular path ENTIRELY in 1.0 seconds. I want to be able to tap left/right and only move incremental amount of space per tap. (If anyone's played Super Hexagon, think of the fluid circular motion of that game)
*Note: I only use a circular path as an example so I don't particularly need specific pointers on how to move around a circle per se, but more of ANY path of any shape.
You can create any kind path shape you want using CGPath. This gives you the ability to create only the path for which you need to move your node. To use your circle example, create a 90 degree arc path and your node will move 4 separate times to complete a full circle.
If you do not want to use a path, you can also use the SKAction moveBy x,y,duration command. Tie a couple of those together and use them in a block sequence and you have yourself a generic path function.
I have a bezier path that comes into my program having been created from an SVG and the problem is it is just an outline. I need to perform hit detection on it, anywhere on the interior of the shape. Is there an equivalent of CGPathCreateCopyByStrokingPath for filling it?
CGContextFillPath will fill a path within a context when it is drawn.
CGPathCreateCopyByStrokingPath takes a path and returns a new path describing the outline of the shape that would be formed when stroking that path. It returns a CGPathRef. So if you can perform hit detection on the results of that, then you can perform them directly on your original path. You don't need a conversion.
Supposing I've misunderstood the question, you can use CGPathContainsPoint to test whether a point is inside a path. Use that directly on what you get from your SVG.