View Full Version : reflection matrix how to derive
ugluk
12-31-2009, 08:37 PM
Check out the matrix R in this html page:
http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node159.html
It say, the matrix was derived like this:
The reflection transformation can be decomposed for convenience into a translation to the origin, a rotation mapping the mirror into the XY plane, a scale of -1 in Z, the inverse of the rotation previously used, and a translation back to the mirror location.
Now to the the "mapping the mirror into the XY plane" part. I understand the new z axis in the mirror coordinate system is the normal of the mirror. But how about the x and y axes?
ugluk
12-31-2009, 09:22 PM
I got it, no problem at all, basically just orthogonal projection with a twist. Very bad explanation, but hey it's free :)
ugluk
12-31-2009, 11:18 PM
Ugh, is it possible at all to derive the matrix in way described in the article? I did it like this:
Translate(P)(I-2*V*V^T)Translate(-P)
Ilian Dinev
01-01-2010, 04:57 AM
Plane p;
p.FromTriangle(vec3(0,0.5,1),vec3(1,0.7,2),vec3(0, 7,0));
Mat4 r = p.MakeReflectionMatrix();
g_Matrix_MV = g_Matrix_MV*r;
-------------------------------------------------
struct Plane{
public:
vec3 norm;
float d;
Plane() { }
Plane(float a, float b, float c, float d) : norm(a,b,c), d(d) { }
void FromTriangle(const vec3& p0,const vec3& p1,const vec3& p2);
void Normalize();
Mat4 MakeReflectionMatrix();
};
----------------------------------------------------------
void Plane::FromTriangle(const vec3& p0,const vec3& p1,const vec3& p2){
norm = cross(p1-p0,p2-p0);
norm.normalize();
d = -dot(norm,p0);
}
void Plane::Normalize(){
float len = norm.x*norm.x+norm.y*norm.y+norm.z*norm.z;
if(len>0.00001f){
len=1.0f/len;
norm.x*=len; norm.y*=len; norm.z*=len; d*=len;
return;
}
norm.y = 1;
}
#include "ILX.h"
Mat4 Plane::MakeReflectionMatrix(){
//Normalize(); // let's expect it to be already normalized
Mat4 m;
m.a00 = -2 * norm.x * norm.x + 1;
m.a10 = -2 * norm.y * norm.x;
m.a20 = -2 * norm.z * norm.x;
m.a30 = 0;
m.a01 = -2 * norm.x * norm.y;
m.a11 = -2 * norm.y * norm.y + 1;
m.a21 = -2 * norm.z * norm.y;
m.a31 = 0;
m.a02 = -2 * norm.x * norm.z;
m.a12 = -2 * norm.y * norm.z;
m.a22 = -2 * norm.z * norm.z + 1;
m.a32 = 0;
m.a03 = -2 * norm.x * d;
m.a13 = -2 * norm.y * d;
m.a23 = -2 * norm.z * d;
m.a33 = 1;
return m;
}
ugluk
01-01-2010, 08:04 AM
Thanks for the code, but how is it relevant? I've asked about the derivation.
Brolingstanz
01-03-2010, 06:01 PM
One way to go about it...
For some scale s, plane P and plane normal N, a vertex
V' = V + s N
is a point on the opposite side of P with an equal but negative distance,
which implies that
<V + s N | P> = -<V | P>
Solving for s we have
s = -2 <V|P> / <N|P>.
Taking N to be unit length,
s = -2 <V|P>.
So now V' becomes
V' = V - 2 <V | P> N
= V - 2 N <P | V>,
which when we factor the V yields the matrix form
V' = (I - 2 N P^T) V.
So the overly general and slow form of the psuedo code might be
Vector4 plane(reflectorPlane);
Vector4 normal(reflectorPlane, 0);
Matrix4 reflector = Identity() - Tensor(normal * 2, plane);
Say, this looks a bit the the vector form we all know and love...
ugluk
01-03-2010, 06:47 PM
What do the operator | and Tensor() function do?
Brolingstanz
01-03-2010, 07:02 PM
<*|*> is shorthand for dot product and tensor is a somponent-wise vector multiply that results in a matrix (try a google for "vector outerproduct").
Powered by vBulletin® Version 4.2.0 Copyright © 2013 vBulletin Solutions, Inc. All rights reserved.