# How to create RGB-colors with equal vector norm?

I am trying to do the following:

1. Interprete RGB color values as a 3-D vektor
2. Transform the RGB color into polar coordinates L, teta and phi
3. Create colors with constant L

The math behind this is the standard transformation into spherical coordinates:

b = L * Sin(teta) * Cos(phi)
r = L * Sin(teta) * Sin(phi)
g = L * Cos(teta)


With L beeing the norm of the RGB vektor I want to create.

L=(r^2+b^2+g^2)^0.5 'between 0 and 441.67 = sqrt(3)*255


So far so good. Onto the first issue: r,g and b need to be between 0 and 255

This means that this holds true (I calculated that myself, it's possible that it has errors in it):

If L>255 Then
arccos(255/L) < teta < pi/2 - arccos(255/L)
arccos(255/L) < phi < pi/2 - arccos(255/L)
End If


Here my calculations: The idea is that teta goes from (pi/4 - delta) to (pi/4 + delta) where Which basically means that teta and phi are restricted in what they can be according to the ratio of 255/L. This restriction gets upto a point were L=441.67 the maximum length. Here phi and teta can only be pi/4.

I think upto this points my conclusions are valid, but there is a problem I cannot figure out.

If phi = teta = pi/4 and L = 441.67 the RGB value should be (255,255,255) and the forumlas above yield: RGB= (221,255,221)

Which is what the forumlas for r,g and b above yield if phi = teta = pi/4 and L = 441.67 are inserted.

So how would one generate RGB vektors with a constant norm that are still valid RGB values? (0 < r,g,b < 255)

• How did you derive $\arccos(255/L) < \theta < \pi/2 - \arccos(255/L)$? Does your formulas yield (221, 255, 221)? – Apass.Jack Feb 27 at 14:16
• @Apass.Jack I added the derivation of the angle description, d in this case specifically is 255. The formulas for x,y and,z in polar coordinates yield (221,255,221) for teta=phi=pi/4 – Lucas Raphael Pianegonda Feb 27 at 14:45
• The start of the question makes it sound like you want to convert a RGB color to polar coordinates. If that's not what you want, perhaps it would help to edit that to be clearer. – D.W. Feb 27 at 15:26
• Why do you say that "If phi = theta = pi/4 and L = 441.67 the RGB value should be (255,255,255)"? If $L = 255\sqrt 3$ and $L \cos\theta = 255$ then $\theta = \cos^{-1} \frac1{\sqrt3}$. – Peter Taylor Feb 28 at 12:01
• @PeterTaylor This was an assumption that I thought should be true, since (255,255,255) is the room diagonal, I thought it should have 45° angles for teta and phi. For phi that is correct but as it turns out teta has a 54,7° angle = cos^-1(1/sqrt(3)). – Lucas Raphael Pianegonda Feb 28 at 12:54

So how would one generate RGB vectors with a constant norm that are still valid RGB values? ($$0 \le r,g,b \le 255$$)

There is a simpler algorithm. Let $$L$$ be the given norm.

• Verify that $$0\le L\le 255\sqrt3$$.
• Let r be a random number between $$\sqrt{L^2-\min(2\cdot255^2, L^2)}$$ and $$\min(255, L)$$.
• Let $$M=\sqrt{L^2-r^2}$$. Let g be a random number between $$\sqrt{M^2-\min(255^2, M^2)}$$ and $$\min(255,M)$$.
• Let $$b =\sqrt{L^2-r^2-g^2}$$.

Some minor adjustment is needed if $$r,g,b$$ should be integers, in which case only approximate solutions can be found in general.

Here is the right computation if we want to find the range of $$\theta$$ and $$\phi$$.

• If $$0\le L\le 255$$, then $$0\le\theta,\phi\le\pi/2$$
• If $$255\lt L\le 255\sqrt3$$, let $$M=\sqrt{\max(0, L^2-2\cdot255^2})$$. we have \begin{align} &\quad\quad\begin{cases}b = L \sin(\theta) \cos(\phi)\\ r = L \sin(\theta) \sin(\phi)\\ g = L \cos(\theta)\\ 0\le b,r,g\le 255\\ 0\le\theta,\phi\le\pi/2 \end{cases}\\ &\Longleftrightarrow \begin{cases}b = L \sin(\theta) \cos(\phi)\\ r = L \sin(\theta) \sin(\phi)\\ g = L \cos(\theta)\\ \sqrt{\max\left(0,(L\sin(\theta))^2-255^2\right)}\le b,r\le \min(255,L\sin(\theta)) \\ M\le g\le 255\\ 0\le\theta,\phi\le\pi/2,\, \theta\not=0 \end{cases}\\ &\Longleftrightarrow \begin{cases} \sqrt{\max\left(0,1-\left(\dfrac{255}{L\sin(\theta}\right)^2\right)}\le \cos(\phi)\le \min\left(1, \dfrac{255}{L\sin(\theta)}\right)\\ \sqrt{\max\left(0,1-\left(\dfrac{255}{L\sin(\theta}\right)^2\right)}\le \sin(\phi)\le \min\left(1, \dfrac{255}{L\sin(\theta)}\right)\\ \dfrac{M}{L}\le \cos(\theta)\le \dfrac{255}L\\ 0\le\theta,\phi\le\pi/2,\, \theta\not=0 \end{cases}\\ &(\text{the inequalities on}\cos\phi\text{ put on the same restrictions on }\phi\\ &\text { as the inequalities on }\sin\phi)\\ &\Longleftrightarrow \begin{cases} \arccos\left(\min\left(1, \dfrac{255}{L\sin(\theta)}\right)\right)\le \phi\\ \phi\le\arccos\left(\sqrt{\max\left(0,1-\left(\dfrac{255}{L\sin(\theta)}\right)^2\right)}\right)\\ \arccos(\dfrac{255}L)\le\theta\le\arccos(\dfrac{M}{L}) \end{cases} \end{align}

The formula above tells a way to generate RGB vectors with a given norm $$L$$. Select $$\theta$$ and $$\phi$$ in the range given by the inequalities. Compute $$r,g,b$$ accordingly.

In particular, if you take $$L=255\sqrt3=441.67$$, then $$\dfrac{255}L=\dfrac{M}L=\dfrac3{\sqrt3}$$. $$\theta=\arccos(255/L)=0.9553$$. Since $$\dfrac{255}{L\sin(\theta)}=0.7071$$, we will get $$\arccos(0.7071)\le \phi\le\arccos(0.7171)$$. So $$\phi=\pi/4$$ and we will arrive at $$b=255$$, $$g=255$$ and $$r=255$$, which is the only possible combination of RGB vector for that value of $$L$$, as expected.

There have been several computational mistakes in the question. There has been a few in the previous versions of this answer as well. The comments below this answer might have become irrelevant.

• 1. Instead of Lsin(teta) I used L assuming that L would be normal to teta. – Lucas Raphael Pianegonda Feb 28 at 7:28
• The "much simpler algorithm" doesn't really work. You have no system that keeps r,g or b below 255. This only works for L<255, there it works fine but for greater L it doesn't yield valid r,g,b tripletts. – Lucas Raphael Pianegonda Feb 28 at 7:58
• Oh, right. I meant something, but wrote something total different. I am correcting it. Just a moment or two. – Apass.Jack Feb 28 at 8:00
• Another potential error: the minimal teta is arccos(255/L) which is between 0 and 0.955 as you already pointed out. But if you'd insert teta =0 which is fine from the teta perspective and insert it into the restrictions for phi, you'll get a divided by 0 because sin(teta) is zero. – Lucas Raphael Pianegonda Feb 28 at 8:30
• It looks like the exercise should be "Find at least two places where this answer made a mistake." ... I will update in a moment. – Apass.Jack Feb 28 at 8:46

Generate a random three-dimensional vector $$v$$ with non-negative components (you can generate each of the three components at random). Then, fix up the norm to be $$L$$ by setting

$$w = L \cdot {v \over \|v\|}.$$

Now $$w$$ will have norm $$L$$. Interpret $$w$$ as a RGB color.

Next, check that all three components of $$w$$ are in the range 0..255. If yes, you've got your RGB color. If not, throw it away and go back to the beginning and generate a new $$v$$, and repeat. (This is called rejection sampling.)