1

In below example, I use 3 foreach loop to colorize RGB cubic. for example, if red is 0 or 255, blue and green should both be run in range (0,255). currently my code is using 0,10,20,...,255.

Note: current compiling time a little bit long since too many foreach tasks!

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\def\matCC{{0.257, 0.504, 0.098},% 
    {-0.148, -0.291, 0.439},%
    {0.439, -0.368,0.071}}%
\pgfmathdeclarefunction{RGBvec}{3}{%
    \begingroup%
    \pgfmathsetmacro{\myY}{16+{\matCC}[0][0]*#1+{\matCC}[0][1]*#2+{\matCC}[0][2]*#3}%
    \pgfmathsetmacro{\myCb}{128+{\matCC}[1][0]*#1+{\matCC}[1][1]*#2+{\matCC}[1][2]*#3}%
    \pgfmathsetmacro{\myCr}{128+{\matCC}[2][0]*#1+{\matCC}[2][1]*#2+{\matCC}[2][2]*#3}%
    \edef\pgfmathresult{\myCr,\myCb,\myY}%
    \pgfmathsmuggle\pgfmathresult\endgroup%
}%

\begin{document}
    \tdplotsetmaincoords{70}{110}
    \begin{tikzpicture}[bullet/.style={circle,inner
        sep=2pt,fill},line cap=round,line join=round,
    RGB coordinate/.code args={(#1,#2,#3)}{\pgfmathparse{RGBvec(#1,#2,#3)}%
        \tikzset{insert path={(\pgfmathresult)}}},font=\sffamily,thick]
    \begin{scope}[tdplot_main_coords,scale=1/40]
    \draw[-stealth] (0,0,0) coordinate (O) -- (280,0,0) coordinate[label=below:Cr] (Cr);
    \draw[-stealth]  (O) -- (0,280,0) coordinate[label=below:Cb] (Cb);
    \draw[-stealth]  (O) -- (0,0,280) coordinate[label=left:Y] (Y);

    \path 
    foreach \r in {0,10,...,255} {
        foreach \g in {0,10,...,255}{
            foreach \b in {0,255} {
                [RGB coordinate={(\r,\g,\b)}] node[bullet,fill={rgb,255:red,\r; green,\g; blue,\b}] (M){}
            }
        }
    }   
    foreach \r in {0,255} {
        foreach \g in {0,10,...,255}{
            foreach \b in {0,10,...,255} {
                [RGB coordinate={(\r,\g,\b)}] node[bullet,fill={rgb,255:red,\r; green,\g; blue,\b}] (M){}
            }
        }
    }
    foreach \r in {0,10,...,255} {
        foreach \g in {0,255}{
            foreach \b in {0,10,...,255} {
                [RGB coordinate={(\r,\g,\b)}] node[bullet,fill={rgb,255:red,\r; green,\g; blue,\b}] (M){}
            }
        }
    }      
    ;


    \path [RGB coordinate={(255,255,255)}] node[bullet,draw,fill=white] (white){}
    [RGB coordinate={(0,0,0)}] node[bullet] (black){}
    [RGB coordinate={(255,0,0)}] node[bullet,red] (red){}
    [RGB coordinate={(0,255,0)}] node[bullet,green] (green){}
    [RGB coordinate={(0,0,255)}] node[bullet,blue] (blue){}
    [RGB coordinate={(255,0,255)}] node[bullet,magenta] (magenta){}
    [RGB coordinate={(255,255,0)}] node[bullet,yellow] (yellow){}
    [RGB coordinate={(0,255,255)}] node[bullet,cyan] (cyan){};

    \draw (red) -- (black) -- (blue) -- (magenta) -- (red) -- (yellow) 
    -- (green) edge (black) -- (cyan) edge (blue) -- (white)  edge (magenta) -- (yellow); 
    \draw[thin] (255,0,0) node[left]{255} -- (255,255,0) -- (0,255,0) node[above]{255}
    (0,0,255) node[left]{255} -- (255,0,255) edge (255,0,0)
    -- (255,255,255)  edge (255,255,0) -- (0,255,255)  edge (0,255,0)
    -- cycle ;
    \end{scope} 
    \end{tikzpicture}
\end{document}

Output as below:

enter image description here

How can we improve it to get continues color but do not do it with 0,10,...,255 loop?

2
  • What exactly is the question? Dec 21, 2019 at 18:12
  • I wish to replace the foreach loop with more smarter/fine way! now it's jump by 10.
    – lucky1928
    Dec 21, 2019 at 18:18

1 Answer 1

2

One can use the bilinear interpolation here. Unfortunately, it is really made for rectangles on the screen, and transforming it is not so easy. Also the bug in pgf v.3.15 prevents us from using symbolic coordinates but rather than using the patch I use calc here to fix it since since it gets loaded anyway.

\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{shadings}
\def\matCC{{0.257, 0.504, 0.098},% 
        {-0.148, -0.291, 0.439},%
        {0.439, -0.368,0.071}}%
\pgfmathdeclarefunction{RGBvec}{3}{%
\begingroup%
\pgfmathsetmacro{\myY}{16+{\matCC}[0][0]*#1+{\matCC}[0][1]*#2+{\matCC}[0][2]*#3}%
\pgfmathsetmacro{\myCb}{128+{\matCC}[1][0]*#1+{\matCC}[1][1]*#2+{\matCC}[1][2]*#3}%
\pgfmathsetmacro{\myCr}{128+{\matCC}[2][0]*#1+{\matCC}[2][1]*#2+{\matCC}[2][2]*#3}%
\edef\pgfmathresult{\myCr,\myCb,\myY}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\tikzset{RGB coordinate/.code args={(#1,#2,#3)}{\pgfmathparse{RGBvec(#1,#2,#3)}%
    \tikzset{insert path={(\pgfmathresult)}}}}
\begin{document}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[bullet/.style={circle,inner sep=2pt,outer sep=0pt,fill},
    shaded plane/.style args={(#1)--(#2)--(#3)--(#4)}{%
    upper left=#4,upper right=#3,lower left=#1,lower right=#2,
    tdplot_screen_coords,
    insert path={
    let \p1=(#1),\p2=(#2),\p3=(#3),\p4=(#4),\n1={atan2(\y2-\y1,\x2-\x1)} in 
    (\x1,\y1) --(\x2,\y2) --(\x3,\y3)-- (\x4,\y4)}},
    line cap=round,line join=round,font=\sffamily,thick,remember picture]
 %\path[use as bounding box] (-5.5,-2)   rectangle (5.5,8);
 \begin{scope}[tdplot_main_coords,scale=1/40,shift={(-128,-128,0)}]
  \draw[-stealth] (0,0,0) coordinate (O) -- (280,0,0) coordinate[label=below:Cr] (Cr);
  \draw[-stealth]  (O) -- (0,280,0) coordinate[label=below:Cb] (Cb);
  \draw[-stealth]  (O) -- (0,0,280) coordinate[label=left:Y] (Y);
  \path [RGB coordinate={(255,255,255)}] node[bullet,draw,fill=white] (white){}
    [RGB coordinate={(0,0,0)}] node[bullet] (black){}
    [RGB coordinate={(255,0,0)}] node[bullet,red] (red){}
    [RGB coordinate={(0,255,0)}] node[bullet,green] (green){}
    [RGB coordinate={(0,0,255)}] node[bullet,blue] (blue){}
    [RGB coordinate={(255,0,255)}] node[bullet,magenta] (magenta){}
    [RGB coordinate={(255,255,0)}] node[bullet,yellow] (yellow){}
    [RGB coordinate={(0,255,255)}] node[bullet,cyan] (cyan){};
  \shade[shaded plane={(red)--(black)--(green)--(yellow)}];
  \shade[shaded plane={(black)--(blue)--(cyan)--(green)}];
  \shade[shading angle=40,shaded plane={(green)--(cyan)--(white)--(yellow)}];
%   
  \path foreach \X in {red,black,blue,cyan,green,yellow,white}
  {(\X) node[bullet,\X]{}};
   \draw[thin] (255,255,0) -- (255,0,0) node[pos=1.1]{255} 
   (255,255,0) --(0,255,0) node[pos=1.1]{255}
   (0,0,255) node[left]{255} -- (255,0,255) edge (255,0,0)
    -- (255,255,255)  edge (255,255,0) -- (0,255,255)  edge (0,255,0)
   -- cycle ;
 \end{scope}
\end{tikzpicture}
\end{document}

enter image description here

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .