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
Related
We are creating an app which is used for calculating measurements of any a window/door using Project tango Device. For that we need to follow below mentioned steps:
1. Capture Image (normal 2D image). Store this image.
2. Also capture point cloud while capturing the Image. Store the point cloud in a PCD file.
3. Indicate the position of the window/door in the image displayed on a canvas by drawing a rectangle on the image. See Image.
4. As the rectangle is drawn automatically calculate width and height of the window/door using the stored PointCloud data.
We have managed to do 1, 2 and 3.
For 4 we have two issues:
A. Determine the Points in the PointCloud corresponding to the drawn rectangle i.e. the window/door. We believe that this involves determining the plane in which the window/door is located e.g. Assuming that the axis along the depth (i.e. from the camera to the object) is Z-axis then we need to determine the value(s) of Z that correspond to the plane in which the window/door is located in PointCloud. How can this be done? Please can someone suggest a feasible and an efficient way of doing so?
B. Once we determine the sub-PointCloud corresponding to the drawn rectangle find the distance between the minimum and maximum points along the X & Y axis to determine the width and height respectively. How can this be done?
Any help with demo code or app reference is appreciated.enter image description here
enter image description here
find contour of the point cloud. Use iterative ransac to fit lines to the contour. Intersect the lines and get the corner points
for 3d, compute the surface normals. Then compute the curvature which is a differential of the surface normal. These are corner points.
PCL (Point Cloud Library) has all of these functions.
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.
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
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!
I have a drawing application in Android that allows the user to draw with their finger, and then stores the resulting shapes as Android Paths. To allow the user to delete individual Paths they have drawn, I have implemented this solution that uses a bounding Rect for each Path, and then uses an inner multi-dimensional binary array to represent the pixels inside the bounding Rect. I then populate the array by taking the Path's control points and track along it using the mathematical equation for a quadratic bezier curve, setting each element in the array that would have a pixel underneath it to 1.
Using the above setup, when in erasing mode, I first check for collision between the users finger and the bounding Rect, and if that collides, I then check to see if the pixel being touched by the user is set to a 1 in the array.
Now, when a user loads a note, I load all of the shapes into an ArrayList of 'stroke' objects so that I can then easily display them and can loop through them checking for collision when in erase mode. I also store the Rect and binary array with the strokes in the custom object. Everything is working as expected, but the memory footprint of storing all of this data, specifically the binary array for each Path's bounding Rect, is getting expensive, and when a user has a large number of strokes I am getting a java.lang.OutOfMemoryError on the portion of my code that is creating the array for each stroke.
Any suggestions on a better way to accomplish this? Essentially, I am trying to determine collision between two Android Paths (the drawing Path, and then a Path that the user creates when in erase mode), and while the above works in theory, in practice it is not feasible.
Thanks,
Paul
What is the actual representation of the "binary array"? I think if you tweak the representation to reflect the actual data you need to store (for example RLE encode the bits: at this y starting at this x and for z pixels) you will be able to store what you need to without excessive size.
Storing an actual array of bytes with one byte per pixel, or per 8 pixels (if that is what you are doing) isn't necessary for this use.
Another alternative is not to store a bitmap at all, just the control points and bounding boxes. If a touch intersects a bounding box, you calculate the bitmap on the fly from the control points.