I am trying to make an iPhone application which can draw a path between two points (similar to Google Maps) but instead of the map i want to use any other image as a background, this path between the two points might not be straight and there might be multiple paths to get from one point to another then I want to draw the shortest path between the two points.
I tried using the CGContext & CGPath but I got stacked.
Can you help me plz.
Thanx,
Ghaith
I think you're looking for UIBezierPath. You can add simple lines/polygons with something like:
UIBezierPath* path = [UIBezierPath bezierPath];
[aPath moveToPoint:CGPointMake(50.0, 50.0)];
[aPath addLineToPoint:CGPointMake(10.0, 10.0)];
[aPath addLineToPoint:CGPointMake(10.0, 50.0)];
[aPath closePath];
You can also, of course, add curves (bezier ones!) and other shapes. Then to draw it use the [aPath stroke] call in your view's drawRect method.
For more information see the iPad Programming Guide
This seems like a problem that's not really related to drawing the route.
You want to find the shortest path from one point to another, given certain criteria - where you can and cannot move, for example. I don't see this problem as something you can solve with drawing, but with actually calculating the different possible ways and then compare them. When you have decided which is the best route. Drawing is pretty simple.
How you would go by deciding I'm actually not sure - sorry 'bout that. But you should probably have a look at some shortest path algorithms. But that probably means you have to represent the underlying image as a pattern, or a series of nodes but graphical problems are not my cup of tea, so I'm not really sure how.
Just a side note - If the number of possible ways of getting from point A to point B are great, this can become a computational problem, and you have to make sure that the iPhone can manage.
(this should probably be a comment somewhere, but since I can't yet and I still wanted to share my two cents, it became an answer.)
Edit:
I just thought of really naive aproach! - for fun mostly, but I couldn't keep myself from posting.
Suppose you have a representation of the image. What parts can't be traveled on and what parts can be. Each pixel that can be travelled on is represented by a 1, and every other pixel is represented by a 0. Thus the pixels represented by 1s can be seen as nodes on which we can travel.
Each node can reach, at most, 8 other nodes - the adjacent pixels. And the weight of travelling between any two nodes could be set as 1. But we have to account that travelling in a diagonal is a greater distance so that weight should be sqrt(2).
Now we have a great bunch of nodes - each with weights in between them. From here we can apply a djikstra-algorithm to find the best route. (maybe some other algorithm is more beneficial at this point - but djikstras is the only one I'm familiar with).
hum, wonder how bad of a solution this would be. ... again, you probably don't want this solution...
EDIT 2:
I will say this again that this is probably not the best way to do this! You should seriously ask someone with more experience in algorithms and in graphical problems. - This was something I thought of at 3am and was mostly for laughs.
If your question is about calculating routes instead of drawing routes, that's a whole different problem. The standard algorithm for finding efficient routes through a given space are the "A*" (pronounced A-star) algorithms, which are typically what real-time strategy games use when you click a unit and tell it to "go there". It's also got many uses in AI when searching for a transition through a space.
It's not easy to get right, though. It might be easier to find a good game engine that already includes an A* implementation and integrate that into your software.
Related
I'm working on MATLAB on some regions inside an image. I'm at a point in which I would like to be able to separate regions which exhibit some kind of regularity (e.g., being circle-ish or square-ish) from regions which does not resemble any known figure and which for my application are mere noise. I'll illustrate this using a descriptive MS Paint image:
Is there any tool that, most of the times (or even less, I know this can't be 100/100) will recognize the red thing as being different?
I'll deal with many shapes in a single image, so I don't mind if I carry on some red monsters along the way, as long as the majority of them is kicked out. Of course I know the indices of these regions, so I can manipulate them in MATLAB.
Many algorithms come to mind, e.g., getting the boundary and checking for its regularity/the number of times it changes curvature/..., checking for variations in vertical length through different columns (nearly 0 for the linear feature, really high for the red stuff), ...
However I was hoping in some help from a tool out there. It doesn't matter if this tool won't cover all cases (for example, will kick out circles), I've been very broad to get the maximum number of inputs from you guys - any tool will be inspiring and helpful (and, however, we can't expect a perfect answer for the deeper question - recognizing regular shapes - which seems more like a AI field of research). I also think that, while being broad, this is totally non-subjective so should fit in SO. Thank you.
Side note 1: I'll deal mostly with elongated, extended features like the top-right one, so circles are not that relevant.
Side note 2: To be 100% clear, I would need something (be it an already existant tool, or some ideas pointed out by you) that acts on the indices of the shapes, in terms of rows-columns into the original image, or on the boundary of the shape itself.
Side note 3: Apart from tools/suggestions/ideas, you are welcomed to write down some lines of code ;) I'm getting the regions as connected components from bwconncomp.
I had to solve a similar problem recently that involved counting the number of indentations on blobs within in an image (basically, the connected components returned by bwconncomp). The method I used was to look at curvature changes along the boundary calculated via the FFT. In your case, the red blobs would have a large number of curvature variations, whereas the black regions would not. It's a pretty easy calculation and relatively fast. The code is on github here:
https://github.com/mjsottile/blobdents
The file of interest is src/countindents.m. A short description of the approach is here:
http://arxiv.org/abs/1501.07692
I went for the easier road as suggested by #Mikhail in comments.
I found out regionprops has a really helpful tool called Solidity. Quoting docs,
Returns a scalar specifying the proportion of the pixels in the convex hull that are also in the region. Computed as Area/ConvexArea.
Convex hull is defined as the smallest convex polygon that can contain the region. So Solidity goes up to 1 if the shape is kind of regular and has no convexity changes; down to 0 for my red shape, which leaves space between itself and the convex polygon.
Of course it never reaches 0, lowest value should belong to a kind of +-shaped sign.
Given a set of non-rotated AABB bounds, I'm hoping to create a simpler set of bounds from the original set, that allows for a specified amount of inaccuracy.
Some examples:
I'm working with this in Unity with Bounds, but it's just basic AABB comparison stuff, nothing Unity-specific. I figure someone must have worked out a system for this at some point in the past, but I had no luck searching around. Encapsulating bounds are easy but this is harder, since you can't just iterate through each bounds one by one. Sometimes a simpler solution can only be seen by looking at the whole thing.
Fast performance isn't critical but would be nice. Inaccuracy is OK in both directions (i.e. the bounds may cover a little less than the actual size or a little more). If it helps, I can expect all bounds in the original set to be connected somewhere - no free-floating pieces in a separate group.
I don't expect anyone to write up a whole system to solve this, I'm more hoping that it's already been solved or that maybe there's an obvious process to achieve it that I haven't thought of yet.
This sounds something that could be handled with Surface Area Heuristics (SAH). SAH is commonly used in ray tracing to build better tree like structures were the triangles are stored. There are multiple sources discussing it more. One good is Wald's thesis chapter 7.3.
The basic idea in the SAH built is to start with the whole space and divide it recursively. Division position is decided by sweeping through all reasonable positions and calculating surface area of both child nodes. The reasonable positions are the positions were any triangle has its upper or lower bound. After sweeping through all the candidates, the division with the smallest total surface area in the children is used.
If SAH is not a good idea for your application, you could use similar sweeping through all candidates, but calculate for example the extra space inside the AABBs.
I am interested in using the CGContextEOFillPath feature provided by apple. I am guessing with the way the EOFill works, it probably has a way to take the filled in areas and calculate an area.
So my question is does anyone know of a way to use CGContextEOFillPath and find the area of the filled in sections.
If this isn't something that is easily done, maybe some pointers to a better way of doing this would be helpful. Though I need to use the EO style graphing.
Thanks.
What do you mean "Calculate the area"?
As in calculate the surface area of a complex shape?
It depends on your shapes.
Are they all polygons?
What about circles?
There are well known formulas for calculating the area of a polygon. (Wikipedia has it) Part of that calculation involves using an ABS() function because shapes drawn "counterclockwise" have the opposite sign as those drawn "clockwise". If you're looking to simulate the EO behavior, you can simply ignore the sign change, because, for you, it's desirable.
If you have more complicated shapes that involve curves, then you need to break the problem down into multiple parts - one part to solve for polygons - one to solve for circles - one to solve for other shapes, etc.
My Question is something similar to this.
I have 2 CGPathRef and 1 will be moved by finger touch. I want to find that whether the 2 CGPathRef are intersected? That question was asked almost 2 years ago and I want to know whether something has been found in the mean time.
This is fairly old, but I found it looking for a similar solution, in my problem I wanted to find when a circle overlapped with a path (a special case of your question).
I solved this by using CGPathCreateCopyByStrokingPath to create a stroked version of the original path using the radius of the circle as the stroke width. If the center point of the circle overlaps the stroked path then the original path overlaps the circle.
BOOL CGPathIntersectsCircle(CGPathRef path, CGPoint center, CGFloat radius)
{
CGPathRef fuzzyPath;
fuzzyPath = CGPathCreateCopyByStrokingPath(path, NULL, radius,
kCGLineCapRound,
kCGLineJoinRound, 0.0);
if (CGPathContainsPoint(fuzzyPath, NULL, center, NO))
{
CGPathRelease(fuzzyPath);
return YES;
}
CGPathRelease(fuzzyPath);
return NO;
}
Edit: A minor bug where the fuzzyPath was not released.
I have written a small pixel based path collision detection API for CGPathRefs. It requires that you add a few source directories to your project, and it only works with ARC, but it should at least show you how one might do something like this. It basically draws the two paths on two separate contexts, and then does pixel-by-pixel checks to see if any pixels are on both paths. Obviously this would be slow to run every time the user drags their finger, but it certainly could be done once every half second or so, maybe not even on the main thread.
This is the easiest way I've found of doing something like this, and it may easily be that there's no better way, besides using lots of math.
The source on Github
A quick Youtube demo.
Generally speaking, finding the intersection of two arbitrary CGPaths is going to be very complex.
There are ways to do approximations. Checking the intersections of the bounding boxes is a good first step. You can also subdivide the curve and repeat the process to get better approximations. Another option is to flatten the paths and see if any of the line segments of the flattened paths intersect.
For the general case, however, things get very nasty very fast. Consider, for example, the fact that two cubic bezier segments (never mind an entire path... just one segment) can intersect with another segment at up to 6 points. The more segments in your path, the more potential intersections. There is also the problem of degenerate bezier curves where a segment has a cusp that just touches one point of another segment. Does that count as an intersection? (sometimes yes, sometimes no)
It's not clear from your question, but you might also want to consider the intersections of the strokes that are applied to the curves, and correctly account for line joins and miters. That that gets even harder. Macromedia FreeHand (a drawing program similar to Adobe Illustrator) had a very large, complex, intensely mathematical library for discovering arbitrary bezier curve intersections. The problem is not easily solved.
To find the intersection of two CAShapeLayers, we can use below method, CAShapeLayer won't return frame. But we can get the refPath frame using CGPathGetBoundingBox. But this one will give the frame in rectangle.I thing you may understand.
if (CGRectIntersectsRect(CGPathGetBoundingBox(layer.path), CGPathGetBoundingBox(layer.path)))
I have a path drawn in OpenGL ES. I can convert it to a CGPath if needed.
How would I check if it intersects itself (If the user created a complete loop)?
Graham Cox has some very interesting thoughts on how to detect the intersection of a CGPathRef and a CGRect, which is similar to your problem and may be educational. The underlying problem is difficult, and most practical solutions are going to be approximations.
You may also want to look at this SO article on CGPathRef intersection, which is also simliar to your problem, and some of the proposed solutions are in the same space as Graham's above.
Note: This answer is to an earlier version of the question, where I thought the problem was to determine if the path was closed or not.
I think a path is considered closed iff the current point == the starting point.
The easiest way I know of to check this is to keep track of these two points on your own, and check for equality. You can also use CGPathGetCurrentPoint, and only track the starting point to compare with this.
Here's a roundabout way to find the starting point, if it's hard to just keep track of it directly:
make a copy of the path
store its current point
call CGPathCloseSubpath
check to see if the current point changed
If it did change, the original path was open; otherwise closed.
This is a way to check if a path composed of a single continuous segment is self-intersecting.
I'm sure that if you wanted a faster implementation, you could get one by using some good thinking and full access to the CGPath internal data. This idea focuses on quick coding, although I suspect it will still be reasonably fast:
Basically, take two copies of the path, and fill it in two different ways. One fill uses CGContextEOFillPath, while the other uses CGContextFillPath. The results will be different iff the path is self-intersecting.
You can check if the result is different by blending the results together in difference blend mode, and testing if the resulting raw image data is all 0 (all black).
Hacky, yes. But also (relatively) easy to code.
** Addendum ** I just realized this won't work 100% of the time - for example, it won't detect a figure eight, although it will detect a pretzel.