2
$\begingroup$

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?

$\endgroup$
3
$\begingroup$

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$.

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

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 ;-)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.