Find points on the line in point cloud - point-clouds

I am using Point Cloud Library. I know there is a function to find lines using RANSAC method, but I want to do opposite of that. I have a point cloud, I have an equation of line, now, I would like to find all the points on or near(within given threshold) the line.
Is there any function/s I can use to achieve my goal?
I would really appreciate any kind of help.

I have attempted to use PCL a few times for Kinect processing but it hasn't worked out too well for me. So I attempted to create my own algorithms to do what I want, and for the application, they work much faster than the PCL ones :)
The project I am working on is on GitHub and you can find some code that may help in the bool ConvexHull::addPoint(double newX, double newY, double newZ) found here.
This utilises a 3D plane equation generated using RANSAC and then compares each point to it, calculating the distance between the point and the plane, just like Oscee said.
Here's the juicy bit of the code which I think may help you:
// Find the distance from point to plane.
// http://mathworld.wolfram.com/Point-PlaneDistance.html
dist = newX * plane.a;
dist += newY * plane.b;
dist += newZ * plane.c;
dist += plane.d;
dist /= sqrt(pow(plane.a, 2) + pow(plane.b, 2) + pow(plane.c, 2));
dist = (dist >= 0) ? dist : -dist; // Absolute distance.
if (dist > tolerance) {
return false; // Return false as point is outside of tolerance.
}
With this function I pass in every point from the 640*480 Kinect image that has a depth value greater than 0.
And for me, this works quite fast :)
I hope this helps.

I don't think you need any special function to do that - simply go through all your points, calculate the point-line distance and accept the ones within your threshold and reject/delete the ones outside.

Related

Understanding the rotation math in this code snippet

Here is my code specific to rotation things, given by pseudo-code.
var rad = (targettransform.rotationEuler.y) * Math.PI / 180;
var difVec = targettransform.pos - othertransform.pos;
//the difVec.z which means radius
this._targetPos.z -= difVec.z * (1 - Math.cos(rad));
this._targetPos.x += difVec.z * Math.sin(rad);
this.transform.position = this._targetPos;
this.transform.lookAt(targettransform.position, Utils.UnitY);
The above pseudo-code is nothing more than just rotating, but I don't understand what 1 - Math.cos(rad) does, it could be some derivation relative to trigonometric. Would someone explain that math in detail.
Edit
Sorry, my mistake, the main purpose of the code snippet is to offset "_targetpos" by vec3(difVec.z * Math.sin(rad),0,this._targetPos.z) on x-z plane. I manage to rewrite the pseudocode to make sense. It seems that the code snippets only implement the function of keeping relative distance and look at target.
1 - cos(Θ)= 2 sin²(Θ/2) and sin(Θ) = 2 sin(Θ/2) cos(Θ/2), so that you are multiplying the scalar δ by 2 sin(Θ/2), and by a vector in the direction -Θ/2, which is added to the target position.
We can see such terms (1-Cos(Fi)) and (Sin(Fi)) in rotation formula around arbitrary axis by Rodrigues
But question does not provide enough details to be sure what that code really does.

How to convert an image to a Box2D polygon using the alpha layer and triangulation?

I'm coding a game using Box2D and SFML, and I'd like to let my users import their own textures to use as physics polygons. The polygons are created using the images' alpha layer. It doesn't need to be pixel perfect, and this is where my problem is. If it's pixel-perfect, it's going to be way too buggy when the player gets stuck between two rather complex shapes. I have a working edge-detection algorithm, and it produces something like this. It's pixel per pixel (and the shape it's tracing is simply a square with an dip). After that, I have a simplifying algorithm that produces this. It works fine to me, but if every single corner is traced like that, I'm going to have some problems. The code for the vector-simplifying is this:
//borders is a std::vector containing simple Box2D b2Vec2 (2D vector class containing an x and a y)
//vector shortener
for(unsigned int i = 0; i < borders.size(); i++)
{
int x = 0, y = 0;
int counter = 0;
//get the values for x and y that need to be added to check whether in a line or not
x = borders[i].x - borders[i-1].x;
y = borders[i].y - borders[i-1].y;
//while points are aligned..
while((borders[i].x + x*counter == borders[i + counter].x) && (borders[i].y + y*counter == borders[i+counter].y))
{
counter++;
}
if(counter-1 > i)
{
borders.erase(borders.begin() + i, borders.begin() + i + counter -1);
}
}
So my question is, how can I transform the previous set of vectors into something a bit less precise? Are there any rounding algorithms out there? If so, which is best? Any tips you can give me? It doesn't matter whether the resulting polygon is convex or concave, I'm triangulating it anyways.
Thanks,
AsterAlff

Implementing Bezier Curves

I am trying to implement Bezier Curves for an assignment. I am trying to move a ball (using bezier curves) by giving my function an array of key frames. The function should give me all the frames in between the key frames ... or control points ... but although I'm using the formula found on wikipedia... it is not really working :s
her's my code:
private void interpolate(){
float x,y,b, t = 0;
frames = new Frame[keyFrames.length];
for(int i =0;i<keyFrames.length;++i){
t+=0.001;
b = Bint(i,keyFrames.length,t);
x = b*keyFrames[i].x;
y = b*keyFrames[i].y;
frames[i] = new Frame(x,y);
}
}
private float Bint(int i, int n, float t){
float Cni = fact(n)/(fact(i) * fact(n-i));
return Cni * pow(1-t,n-i) * pow(t,i);
}
Also I've noticed that the frames[] array should be much bigger but I can't find any other text which is more programmer friendly
Thanks in advance.
There are lots of things that don't look quite right here.
Doing it this way, your interpolation will pass exactly through the first and last control points, but not through the others. Is that what you want?
If you have lots of key frames, you're using a very-high-degree polynomial for your interpolation. Polynomials of high degree are notoriously badly-behaved, you may get your position oscillating wildly in between the key frame positions. (This is one reason why the answer to question 1 should probably be no.)
Assuming for the sake of argument that you really do want to do this, your value of t should go from 0 at the start to 1 at the end. Do you happen to have exactly 1001 of these key frames? If not, you'll be doing the wrong thing.
Evaluating these polynomials with lots of calls to fact and pow is likely to be inefficient, especially if n is large.
I'm reluctant to go into much detail about what you should do without knowing more about the scope of your assignment -- it will do no one any good for Stack Overflow to do your homework for you! What have you already been told about Bezier curves? What exactly does your assignment ask you to do?
EDITED to add:
The simplest way to do interpolation using Bezier curves is probably this. Have one (cubic) Bezier curve between each pair of key-points. The endpoints (first and last control points) of each Bezier curve are those keypoints. You need two more control points. For motion to be smooth as you move through a given keypoint, you need (keypoint minus previous control point) = (next control point minus keypoint). So you're choosing a single vector at each keypoint, which will determine where the previous and subsequent control points go. As you move through each keypoint, you'll be moving in the direction of that vector, and the longer the vector is the faster you'll be moving. (If the vector is zero then your cubic Bezier degenerates into a simple straight-line path.)
Choosing that vector so that everything looks nice is highly nontrivial, but you probably aren't really being asked to do that at this stage. So something pretty simple will probably be good enough. You might, e.g., take the vector to be proportional to (next keypoint minus previous keypoint). You'll need to do something a bit different at the start and end of your path if you do that.
Finally got What I needed! Here's what I did:
private void interpolate() {
float t = 0;
float x,y,b;
for(int f =0;f<frames.length;f++) {
x=0;
y=0;
for(int i = 0; i<keyFrames.length; i++) {
b = Bint(i,keyFrames.length-1,map(t,0,time,0,1));
x += b*keyFrames[i].x;
y += b*keyFrames[i].y;
}
frames[f] = new Frame(x,y);
t+=partialTime;
}
}
private void createInterpolationData() {
time = keyFrames[keyFrames.length-1].time -
keyFrames[0].time;
noOfFrames = 60*time;
partialTime = time/noOfFrames;
frames = new Frame[ceil(noOfFrames)];
}

Pseudocode for Swept AABB Collision

I think swept means determining if objects will collide at some point, not just whether they are currently colliding, but if I'm wrong tell me.
I have objects with bounded boxes that are aligned on an axis. The boxes of objects can be different sizes, but they are always rectangular.
I've tried and tried to figure out an algorithm to determine if two moving AABB objects will collide at some point, but I am having a really hard time. I read a question on here about determining the time intervals when the two objects will pass at some point, and I didn't have a problem visualizing it, but implementing it was another story. It seems like there are too many exceptions, and it doesn't seem like I am doing it correctly.
The objects are only able to move in straight lines (though obviously they can change direction, e.g. turn around, but they are always on the axis. If they try to turn off the axis then it just doesn't work), and are bound to the axis. Their bounded boxes don't rotate or do anything like that. Velocity can change, but it doesn't matter since the point of the method is to determine whether, given the objects' current state, they are on a "collision course". If you need any more information let me know.
If someone could provide some pseudocode (or real code) that would be great. I read a document called Intersection of Convex Objects: The Method of Separating Axes but I didn't understand some of the pseudocode in it (what does Union mean)?
Any help is appreciated, thanks.
When a collision occurs, the boxes will touch on one side. You could check whether they would be touching for pairs of sides (LR, RL, UD, DU).
If it would simplify the problem, you could translate the boxes so the first box is at the origin and is not moving.
Something like the following code:
dLR = B.L - A.R;
dRL = A.L - B.R;
dUD = B.U - A.D;
dDU = A.U - B.D;
vX = A.xV - B.xV;
vY = A.yV - B.yV;
tLR = dLR / vX;
tRL =-dRL / vX;
tUD = dUD / vY;
tDU =-dDU / vY;
hY = dUD + dDU; //combined height
hX = dLR + dRL;
if((tLR > 0) && (abs(dDU + vY*tLR) < hY)) return true;
if((tRL > 0) && (abs(dUD - vY*tRL) < hY)) return true;
if((tUD > 0) && (abs(dRL + vX*tUD) < hX)) return true;
if((tDU > 0) && (abs(dLR - vX*tDU) < hX)) return true;
return false;

Compressing GPS Points

I have a device that records GPS data. A reading is taken every 2-10 seconds. For an activity taking 2 hours there are a lot of GPS points.
Does anyone know of an algorithm for compressing the dataset by removing redundant data points. i.e. If a series of data points are all in a straight line then only the start and end point are required.
check out the Douglas Peucker Algorithm which is used to simplify a polygon. i´ve used this successfully to reduce the amount of gps waypoints when trasmitted to clients for displaying purposes.
You probably want to approximate your path x(t), y(t) with a polynomial approximation of it. Are you looking for something like this: http://www.youtube.com/watch?v=YtcZXlKbDJY ???
You can remove redundant points by performing a very basic simplification based on calculation of slope between subsequent points.
Here is a bit of but not complete C++ code presenting possible algorithm:
struct Point
{
double x;
double y;
};
double calculate_slope(Point const& p1, Point const& p2)
{
// dy y2 - y1
// m = ---- = ---------
// dx x2 - x1
return ((p2.y - p1.y) / (p2.x - p1.x));
}
// 1. Read first two points from GPS stream source
Point p0 = ... ;
Point p1 = ... ;
// 2. Accept p0 as it's first point
// 3. Calculate slope
double m0 = calculate_slope(p0, p1);
// 4. next point is now previous
p0 = p1;
// 5. Read another point
p1 = ... ;
double m1 = calculate_slope(p0, p1);
// 6. Eliminate Compare slopes
double const tolerance = 0.1; // choose your tolerance
double const diff = m0 - m1;
bool if (!((diff <= tolerance) && (diff >= -tolerance)))
{
// 7. Accept p0 and eliminate p1
m0 = m1;
}
// Repeat steps from 4 to 7 for the rest of points.
I hope it helps.
There is a research paper on Compressing GPS Data on Mobile Devices.
Additionally, you can look at this CodeProject article on Writing GPS Applications. I think the problem you will have is not for straight points, but curved roads. It all depends on how precise you want your path to be.
The code given above has a couple of issues that might make it unsuitable:
"same slope" tolerance measures difference in gradient rather than angle, so NNE to NNW is considered a much bigger difference than NE to SE (assuming y axis runs North-South).
One way of addressing this would be for the tolerance to measure how the dot product of two segments compares with the product of their lengths. (It might help understanding to remember that dot product of two vectors is the product of their lengths and the cosine of the angle between them.) However, see next point.
Considers only slope error rather than position error, so a long ENE segment followed by long ESE segment is just as likely to be compressed to a single segment as a string of short segments alternating between ENE and ESE.
The approach that I was thinking of would be to look at what vector graphics applications do to convert a list of cursor coordinates into a sequence of curves. E.g. see lib2geom's bezier-utils.cpp. Note that (i) it's almost entirely position-based rather than direction-based; and (ii) it gives cubic bézier curves as output rather than a polyline, though you could use the same approach to give polyline output if that's preferred (in which case the Newton-Raphson step becomes essentially just a simple dot product).

Resources