Sign in to follow this  

How to get an oblique projection matrix?

This topic is 2814 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 want to project a 3D point x onto a plane (defined by a b c d) along a 3D direction v. I looked at the wikipedia and could not understand, those explanation looks very abstract. Any one can help me to produce a matrix to do it.

Share this post


Link to post
Share on other sites
The following is not the most general approach, but maybe it gives you enough hints...

I allow an aberration of the LOS (line-of-sight) of the virtual camera (getters not shown):

class Camera {

...

public: // projection

/**
sets the mode of projection as specified.
*/

void setModeOfProjection(Projection::mode_t mode);

/**
sets the LOS so that it makes the specified \a angleToHorizon and the also specified \a depthShortening. This routine
just does a setLOSAberration(float, float, bool), where the arguments are computed to:
\code
horinzontal = depthShortening * cos(angleToHorizon)
vertical = depthShortening * sin(angleToHorizon)
\endcode
*/

void setLOS(angle_t angleToHorizon, float depthShortening);

/**
resets the LOS to be co-linear with the principal z-axis of this camera's frame. This routine is just a piggy-back on
setLOSAberration(float, float, bool) for convenience.
*/

inline void resetLOS() {
setLOSAberration(0.0f, 0.0f);
}

/**
sets the LOS aberration. Normally, the LOS is co-linear to the principal z-axis of this camera's frame, but the
camera may also show an aberration here, likely in co-operation with a parallel projection mode, an oblique projection.

\post horizontalLOSAberration() == \a horizontal
\post verticalLOSAberration() == \a vertical
*/

virtual void setLOSAberration(float horizontal, float vertical);

...

};

Using these setters looks e.g. like so:

void
Projection::setToPerspective(Camera& target) {
target.setModeOfProjection(PERSPECTIVE);
target.resetLOS();
}

void
Projection::setToOrthographic(Camera& target) {
target.setModeOfProjection(PARALLEL);
target.resetLOS();
}

void
Projection::setToCavalier45(Camera& target) {
target.setModeOfProjection(PARALLEL);
target.setLOS(Angle::HALF_PI/2.0f, 1.0f);
}

void
Projection::setToCavalier30(Camera& target) {
target.setModeOfProjection(PARALLEL);
target.setLOS(Angle::HALF_PI/3.0f, 1.0f);
}

void
Projection::setToCabinet45(Camera& target) {
target.setModeOfProjection(PARALLEL);
target.setLOS(Angle::HALF_PI/2.0f, 0.5f);
}

void
Projection::setToCabinet30(Camera& target) {
target.setModeOfProjection(PARALLEL);
target.setLOS(Angle::HALF_PI/3.0f, 0.5f);
}

void
Projection::setToDimetricTopView(Camera& target) {
target.setModeOfProjection(PARALLEL);
target.setLOSAberration(0.25f, 0.5f);
}

void
Projection::setToDimetricSideView(Camera& target) {
target.setModeOfProjection(PARALLEL);
target.setLOSAberration(0.5f, 0.25f);
}


Then in OpenGL renderer, where the PROJECTION matrix set-up happens, I first generate the usual projection matrix by e.g. using glOrtho, and then consider LOS aberration as follows:

if(_currentCamera->horizontalLOSAberration() || _currentCamera->verticalLOSAberration()) {
float matrix[16];
for(uint32_t i=0; i<16; ++i) {
matrix[i] = (i%5==0) ? 1.0f : 0.0f;
}
const float viewDistance = _currentCamera->viewDistance();
matrix[8] = _currentCamera->horizontalLOSAberration();
matrix[9] = _currentCamera->verticalLOSAberration();
::glTranslatef(0.0f, 0.0f, viewDistance);
::glMultMatrixf(matrix);
::glTranslatef(0.0f, 0.0f, -viewDistance);
}

As you can see from use of the indices [8] and [9], the aberrations are considered by offsetting x or y, resp., in dependence of the depth. Due to the surrounding glTranslate()s the offsets are enforced to be zero exactly at the distance of the view plane. So any plane parallel to the view plane and at the distance of viewDistance is left where it is.

Share this post


Link to post
Share on other sites
Quote:
Original post by chiyuwang
I want to project a 3D point x onto a plane (defined by a b c d) along a 3D direction v.


It sounds to me like you might be trying to find the intersection of a ray with a plane. If this is the case, you don't want to search for stuff on projection matrices. Projection matrices are applicable to your problem, but it seems like the hard way to approach it.

Instead, consider that you are sliding your point x in the direction of v. Eventually, you will hit the plane, and this is the point you are trying to find.

Use the parameter t to represent the sliding point like this



Now, you want to find the value of t so that the sliding point lies on the plane.

The condition that the sliding coordinates are lying on the plane is given by



inserting the definition of the sliding coordinates with respect to the parameter t gives



Solving for t gives



NOTE: if the denominator of t is zero, then the sliding point will never come into contact with the plane.

Now, insert this value of t back into the equation of the sliding point to get the actual projected point.

Share this post


Link to post
Share on other sites
Thank you for your help. I will try it.

Anyway, if I can get a matrix, it will be very easy for me.

This matrix will concatenate with other transformation matrices and transfered into my pixel shader. In my shader it will be just a matrix multiplication.




Quote:
Original post by Eric_Brown
Quote:
Original post by chiyuwang
I want to project a 3D point x onto a plane (defined by a b c d) along a 3D direction v.


It sounds to me like you might be trying to find the intersection of a ray with a plane. If this is the case, you don't want to search for stuff on projection matrices. Projection matrices are applicable to your problem, but it seems like the hard way to approach it.

Instead, consider that you are sliding your point x in the direction of v. Eventually, you will hit the plane, and this is the point you are trying to find.

Use the parameter t to represent the sliding point like this



Now, you want to find the value of t so that the sliding point lies on the plane.

The condition that the sliding coordinates are lying on the plane is given by



inserting the definition of the sliding coordinates with respect to the parameter t gives



Solving for t gives



NOTE: if the denominator of t is zero, then the sliding point will never come into contact with the plane.

Now, insert this value of t back into the equation of the sliding point to get the actual projected point.



Share this post


Link to post
Share on other sites

This topic is 2814 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