increase number of touch points in a Path - android

I am drawing a path when a user drags his finger across screen. If, however, he does this too fast, I get too few points in path. Is there some way, I can increase the number of points in path after the user has drawn it?
I need this because I am comparing each point of path1 to all points on path2 to see when these two paths are intersecting.

If the user has already completed drawing a path, the best you can do is work with the points you have and guess at what goes between them. Two popular methods of guessing are to insert line segments between points, which gives a very jagged look, or you can use spline interpolation, which gives a very smooth look, but involves a more complicated calculation.
More info on spline interpolation: http://en.wikipedia.org/wiki/Spline_interpolation
Whether you use line segments or splines, you'll need to mathematically find the intersection by using the equations for the path1 segment/spline and the path2 segment/spline. You'll have two equations, two variables and so you should be able to solve the system to find the values for x and y that satisfy both equations, making that point the intersection.
http://en.wikipedia.org/wiki/Line-line_intersection

Related

convex path - how to?

Could someone explain me how convex path is calculated? I need to draw some cubic and additionally some lines but then path is shown as non convex. However when I leave only lines or just cubic it is then convex. The problem is that I need some non regular shaped background and need Convex path for shadow outline but can't get how I could connect drawing cubic with some lines to make convex path if it is even possible
A path is convex if it has a single contour, and only ever curves in a single direction.
Convex means it keeps bending / rotating in one direction, and one direction only. You really have to make sure that all your angles and curves add up. If your curve connects to a line it has to have the same angle or be "more convex", I hope the following 2 images will clear this up.
The picture below is not convex. That's also likely your problem. The line connects to a curve, but the curve has a different angle than the line and it will change the direction where it connects. See where the line goes down but instead of continuing the downwards-motion it suddenly goes up again. Instead of keeping one direction it will change for a moment where line and curve meet.
The above Image is exaggerated for clarity, but even small errors in the connection between the line and curve will trigger an error.
The next line connects to a curve with a steeper angle. This is convex and won't be a problem. See how the whole contour keeps a single motion in one direction, depending in which direction you follow it it keeps turning left/right.
I answered because I was facing a similar issue recently and I feel your pain. I recommend pen and paper to double and triple check the math and to use a small epsilon value to account for rounding errors etc... You really have to nail the math, because if your line and curve connection is just off by very little it will throw that exception.
Sorry for my bad paint skills

Calculate the distance between the point that the user and a <svg:g > element in Android

I want to render my svg in Android via the AndroidSVG library (but I'm open to use another solution). When receiving a Touchevent I want to calculate the distance between the touch event and a given svg element. Specifically a <svg:g id:"myElement"> element. That element inturn cotnains a bunch of <svg:path ...> children.
At the moment I have no idea how to go about the task. Even when there's no library available that supports this function by default I would appreciate if someone could point me to an algorithm that I could implement.
A group element does not have a shape of its own. So you have to look at its content.
If the group element has some transformation, you might either apply this transformation to each child element, or apply the reverse operation to the current mouse position. In the latter case, you will have to apply some correction to the final result, since the distance will be in transformed coordinates so you have to revert it back to untransformed coordinates.
There are several ways how you could define the shape of a path, and each definition yields a different distance metric. Ordered from fast but crude to slow but exact, the options that I can think of are
Axis-aligned bounding box. Simply take all points, including Bézier control points, and take the minimum and maximum for each coordinate. This defines a bounding rectangle, and you can compute the distance to that.
Convex hull. Take all points, again including control points, and compute the convex hull of these. The path will be contained within that hull. Compute the distance to that.
Point cloud. Take all the points, perhaps again including control points but perhaps not, and find the closest one to our input. Use the distance to that.
Piecewise linear. Ignore control points, but consider your path as a sequence of line segments. Compute the distance to each, then take the minimum.
Flattened path. Use De Casteljau's algorithm to approximate curved paths by piecewise linear paths until some error bound is met, then do as described above.
Mathematically exact. Look at each curved segment, and actually compute the minimal distance. For this you need to find the points where the tangent to the curve is orthogonal to the vector towards your input point. This would be a question in its own right for Math SE but please search before you post.

Best way to store points of a curve created by touch movements?

We are creating an app where it is necessary to draw lines (curves) based on touch events but we also need to store the points that correspond to specific lines.
Android.Graphics.Path gave us really nice smooth lines as we dragged our finger. However, there does not seem to be anyway to access the points from the Path objects.
What we do now is basically connect lines as a person drags their finger (using y=mx+b). So if the last recognized touch place was 0,0 and then they move past our threshold to (4,4) we call a function to make points from the line connecting these two ((0,0),(1,1),(2,2),(3,3),(4,4)). These points we add to an ArrayList.
This is giving us kinda choppy curves (obviously cause we are using y=mx+b), but more importantly it slows our program considerably after several lines are drawn.
Is there a better way to generate the points of a curve that follows a user's swipe movements? Or a better way to store these? Path seems to do it so well, is there any reason it hides the actual points?
Thanks!
A way to achieve smoothness is using the Path class' method quadTo.
quadTo(float x1, float y1, float x2, float y2) Add a quadratic bezier
from the last point, approaching control point (x1,y1), and ending at
(x2,y2).
Bezier curves are what you want to solve this problem. You should be able to detect a change in direction of the user's finger and stop the current curve and start a new one at that point. You really don't want to be storing every point along a path as I could just let my finger linger on the screen and clog up the datastructure.

Creating a Region from a Path in Android

I'm a new Android developer that's developing a simple twist on the Tron game with GPS movement, but I'm having trouble implementing player's intersecting.
Right now, my player's trails are Paths that I move to co-ordinates and draw the co-ordinate difference as a line on the canvas.
The path class offers no such intersection method that I can find, so I resorted to using Regions which I've tested an intersection to work with 2 regular Rectangles, but I can't make a Region using Region.setPath for some reason. From my understanding, the path needs to be closed to form an area for it to create a Region, which isn't exactly what I need.
Is there a way to create a region off a path, and not the area the path creates? ie: If the path were a straight line of 10px thick, how do I make a region that is a line of 10px thick?
Here's a short code sample I'm doing:
Path p1path = new Path();
p1path.moveTo(startPos,startPos);
p1path.lineTo(newPos,newPos);
p1path.moveTo(newPos, newPos);
Region p1region = new Region();
p1region.setPath(p1path, new Region(0,0,480,800); // this is where the region isn't setting as I thought it would...
// do same for p2
if(p1.quickReject(p2)) // checks for intersection
Thanks :)
So I've solved this quite some time ago, but to help those who eventually stumble onto this and want some similar functionality:
This post is quite some time ago - so let me remember what happened.
Creating a Region around a path actually did work but for a very limited set of Paths. What I mean by "Creating a region around a Path" is that for a Path that goes from x1,y1 to x2,y2 create a rectangular Region that covers (for example) x1-50,y1-50 to x2+50,y2+50 where 50 is the pixel weight stroke of the Path.
If you can visualise it, it basically creates a rectangular region that covers the Path and it's 50px stroke so you can "fake" Path intersection using Regions. Wherever a Path is, a Region is and so when 2 Paths "intersect", you can check for Region intersection (which you can do but I've forgotten the method names).
This however proved to work only for a few Paths. Though I'd like to think my Math proficiency is adequate, I could not get it so that for whichever direction the Path went the Region would work. Different angles, different directions etc. caused the Region not properly drawing under the Path. My above example of using the 50 stroke width would only work for going a particular direction.
The solution my parter and I stumbled onto was creating a 2D integer array that mapped onto the screen. Wherever a Path went into a certain direction, we would fill every array cell the Path mapped onto with a specific value (1). We would do the same for the other Path, but with a different value (2). Each move you make you would check the 2D array against the Path co-ordinate to see if it has been occupied or not. There was an important mathematical formula that would extrapolate which cells were visited when you go from x1,y2 to x2,y2 that proved very helpful - I believe it was called something along Brasenheim's formula, or something.
It's not the most elegant solution, but it ended up faking Path intersection well. If anyone is interested in a better explanation, you can message me.
Good luck!

Android: Determine what pixels an Android Path occupies

I have a a drawing program where a user can trace with their finger, and in a manner similar to the FingerPaint program, a series of Path's are drawn to represent the lines.
Now, I am doing some collision detection to allow the user to enter an 'erase' mode and delete selected lines, and am trying to determine how to track the individual pixels of the Path. Essentially, I am tracking the RectF that encompasses the Path, and if the RectF is intersected when in erase mode, I'd like to then do pixel-by-pixel intersection tests. So, I need to create some structure for storing the pixels, likely a two dimensional array where each element will be a 1 or 0, based on whether or not the underlying pixel is occupied by the drawn Path.
It is this last part that I am struggling with. While the user is drawing the line, I am feeding the passed X/Y values in as control points for a quadratic bezier curve via Path.quadTo(). The problem is that while Path uses these points to represent a continuous line, I am only being fed discontinous X/Y points from the touch device. Essentially, I need a way to duplicate what the Path object itself is doing, and take the passed X/Y points and interpolate that into a continous curve, but as a set of X/Y coordinates rather than a Path object...
Any pointers to get started on this?
Thanks
EDIT/MORE:
Ok, so as I mentioned, each Path is created (roughly) using the method found in FingerPaint, which means that it is a series of segments, where each segment is a quadratic bezier curve. Given that I know P0, P1 and P2 when I add these curved segments to the larger Path, I can determine the X/Y coordinates along the curve with:
So, my only problem now is determining a 'continous' set of adjacent X/Y coordinates, such that there are no gaps in this set that a user's finger might pass through without hitting one. This would mean determining each X/Y point at 1 pixel intervals. As the above formula would yield points at an infinite number of intervals, given the values of T ranging from 0 through 1, any idea how to programmatically determine the right values of T that will yield points at 1 pixel intervals?
I would do all collision detection using not curves or pixels, but just lines, it's much easier to find intersecting lines, i.e. the intersection of two sequential x/y coordinates of the user's swipe, and the lines of existing lines

Categories

Resources