Converting an rgb triple to a quaternion

I want to convert an rgb color triplet to a quaternion w + x*i + y*j + z*k. I thought of it as of rotation, and (using axis-angle representation and Euclidian length of a unit quaternion equals 1) I came to following equation system: \begin{align*} w &= \sqrt(1-(x^2+y^2+z^2))\\ w &= \cos(\arcsin(r/x))\\ w &= \cos(\arcsin(g/y))\\ w &= \cos(\arcsin(b/z)). \end{align*}

Here $r, g, b$ are constants and i need to obtain $x, y, z, w$.

I am a bit stumped. On the one hand there are 4 variables and 4 equations. On the other hand... how can I solve this? Could this even be solved?

First of all, $\cos(\arcsin(x)) = \sqrt{1-x^2}$. So you can rewrite your latter three equations as $$w^2 = 1 - r^2/x^2 = 1-g^2/y^2 = 1-b^2/z^2.$$ Moreover from these equations, observe that if $x = \alpha r$ for some proportionality constant $\alpha$, then you also have that $y= \alpha g$ and $z = \alpha b$. Substituting into the first equation gives $$w^2 = 1 - \alpha^2(r^2+g^2+b^2)$$ and from the second equation $$w^2 = 1 - \frac{1}{\alpha^2}$$ so we have that $$\alpha = \frac{1}{(r^2+g^2+b^2)^{1/4}}.$$ Plugging this in to the above equations gives you $x,y,z,w$ in terms of $r,g,b$.

• impressive! brilliant) btw, how do you write math syntax? where can i read about this? – xakepp35 Oct 10 '17 at 9:10
• Use latex syntax. Typing $x \mapsto 0$ gives $x \mapsto 0$ and so on. – Lærne Oct 10 '17 at 9:14

Thank you! I've finally managed got working glsl code, due to your effort. I understand, this is not programmers forum, but for those who eventually will need this i could post (because i wrecked my head before i got correct result):

// converts vec3 color to vec4 quaternion
vec4 c2q( in vec3 c ) {
c = c / sqrt3; // length(c) must be <= 1.0
float rr = c.r*c.r;
float gg = c.g*c.g;
float bb = c.b*c.b;
float ww = 1.0 - sqrt(rr+gg+bb);
float xx = rr/(ww+1.0);
float yy = gg/(ww+1.0);
float zz = bb/(ww+1.0);
return vec4( sqrt( xx ), sqrt( yy ), sqrt( zz ), sqrt( ww ) );
}

// converts vec4 quaternion to vec3 color
vec3 q2c( in vec4 q ) {
float xx = q.x*q.x;
float yy = q.y*q.y;
float zz = q.z*q.z;
float ww = q.w*q.w;
float rr = (1.0-ww)*xx;
float gg = (1.0-ww)*yy;
float bb = (1.0-ww)*zz;
vec3 c = vec3( sqrt( rr ), sqrt( gg ), sqrt( bb ) );
return c * sqrt3; // renormalize
}

You could watch my working demo of rotation video image along white axis. Feel free to edit and experiment if you like ;-)