Sign in to follow this  

point cloud alignment

This topic is 3196 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to do basically do point cloud alignment, but aligning to a specific plane. I'm generating a heightmap form the points, but they're slightly sloped, with that i mean, the ground plane isn't on the x and y plane, but rather sloped up. so i want to align it back down, in order for the heightmap to not be rotated by a certain angle. i calculated my eigenvectors and ended up with -0.8703 -0.0393 -0.0905 0.0000 -0.3573 -0.6427 0.0002 -0.3027 -0.6972 but then i'm stuck, i don't know what to do next in order to do what i want. i've tried multiplying all 3d points with a matrix made up of the eigenvector, and that didn't work, i tried multiplying them by a 3x3 rotation matrix created by using the 1st and 2nd eigenvectors and this code,
float** MathUtil::calculateAlignmentRotMat(float* a, int al, float* b, int bl) {

    float angle = acosf(dot3(a, b));
    float* rotationAxis = cross3(a, b);

    return calculateRotationMat(rotationAxis, angle);
}

float** MathUtil::calculateRotationMat(float* rotationAxis, float angle) {
    float **result = new float*[3];

    for (int i = 0; i < 3; i++)
        result[i] = new float[3];

    float rx = rotationAxis[0];
    float ry = rotationAxis[1];
    float rz = rotationAxis[2];

    delete[] rotationAxis;

    float cosAngle = cosf(angle);
    float sinAngle = sinf(angle);
    float c = 1.0 - cosAngle;

    result[0][0] = cosAngle + rx * rx * c;
    result[1][0] = rz * sinAngle + ry * rx * c;
    result[2][0] = -ry * sinAngle + rz * rx * c;
    result[0][1] = -rz * sinAngle + rx * ry * c;
    result[1][1] = cosAngle + ry * ry * c;
    result[2][1] = rx * sinAngle + rz * ry * c;
    result[0][2] = ry * sinAngle + rx * rz * c;
    result[1][2] = -rx * sinAngle + ry * rz * c;
    result[2][2] = cosAngle + rz * rz * c;
    return result;
}
but that also didn't work. my general apply function is
    rotMatrx = util->calculateAlignmentRotMat(vecRot[0], m, vecRot[1], m);

    float* interm2 = vector(m+1);
    float* tempm = vector(m+1);

    /* Form projections of row-points on first three prin. components. */
    /* Store in 'realData', overwriting original data. */
    for (i = 0; i < realN; i++) {
        for (j = 0; j < m; j++) {
            interm2[j] = realData[i][j];
        }
        interm2[3] = 1;
        /* data[i][j] will be overwritten */
        for (k = 0; k < 3; k++) {
            for (k2 = 0; k2 < m; k2++) {
                tempm[k2] += interm2[k2] * rotMatrx[k][k2];
            }
        }
        realData[i][0] = tempm[0];
        realData[i][1] = tempm[1];
        realData[i][2] = tempm[2];

    }
I really hope someone can help me out with this, Thanks Phyx

Share this post


Link to post
Share on other sites
I don't think that'll work, mapping all the points to the same constant Z will in effect flatten the pointcloud, losing any and all structural information i had would it not. In the picture i had, the line is rather the direction of the point cloud. the after picture still has the points in the same location relative to this direction vector.

Share this post


Link to post
Share on other sites
Ok so your diagram didn't show what you wanted :D

In that case you have no choice but to do a coordinate transformation as _swx_ suggests. Find the basis vectors and origin point for the plane that the point cloud is based on; this will give you a 4×4 transformation matrix m of the type:

( ....x.... 0 )
( ....y.... 0 )
( ....n.... 0 )
( ....o.... 1 )

... where o is the origin point of the plane, n is the normal and x and y are two perpendicular basis vectors within the plane. (If your plane is only a little deviant from the target space, I recommend you make these vectors x=n×Y and y=X×n respectively, which will align them with the target's X and Y axes as closely as possible.)

Similarly, find the basis vectors for the plane onto which you which to project the point cloud, which make up a matrix M:
( ....X.... 0 )
( ....Y.... 0 )
( ....N.... 0 )
( ....O.... 1 )


It is likely that your target axes X, Y and N will be the world axes [1,0,0], [0,1,0] and [0,0,1], making this a simple transformation matrix, but they do not have to be.

Now, to project a point p out of the coordinate space defined by m, and into the coordinate space defined by M, simply multiply by the inverse of m and then by M:

P = pm-1M

Share this post


Link to post
Share on other sites
Ah, ok, thanks _swx_ and Bob Janova , yeah i do beleive my world axes are [1,0,0], [0,1,0] and [0,0,1]. and i think i already have m, so but i was only applying it to my points, so that might be why it was screwed up. I'll try the one you mentioned. Thanks :)

Share this post


Link to post
Share on other sites

This topic is 3196 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this