Color Coordinated QuadraysConcept by Josef Hasslberger 



Our goal is to come up with a unit radius sphere whereon each
pixel is a of a color determined by its (c,y,m,k) coordinates,
translated to RGB for display purposes, and realizing that in each
quadrant, one of these primary colors will be set to zero. 

The RGB values for the four colors, Cyan, Yellow, Magenta and
Black are given below: We compute the average of two primary colors by noticing which
of the RGB components change going from one vertex to another, and
pick a half way level of 128 for those components. In the chart
below, the middle column shows the color obtained by averaging the
two primary colors on either side: 

The length of a quadray, which may be a vector sum of basis
quadrays, is: 

Furthermore, if this distance is fixed to give a constant spherical sweepout of radius R, then we can express one vector in terms of the other, e.g. b in terms of a (the reason we have two solutions is examined below). Since we have fixed R at the value of root(6)/2, the second pair of solutions at right gives us specific values for (0,b,0,0) once (a,0,0,0) has been selected. 
angles not precise 
Clearly a has a maximum allowable value beyond which no
vector sum with b will be on the arc. This is the same
value, greater than 1, at which the positive solutions for b
converge, and where the 2nd root term for both is zero. 
We are now ready to compute an arc using quadray coordinates. We will generate one set of values by having a range from 1 to root(9/8), giving two values for b, and two points on the arc, for every value of a (or one at the maximum). Then we will let a range from 1 down to 0, taking only the positive solution for b. Repeating this process for all pairs of quadrays will give us our spherical tetrahedron CYMK.  
A subclass inherits all the methods and data holdings of its parent, while providing a new template capable of accepting additional methods (and/or modifications of old ones) plus data  all of which may in turn be passed along to future subclasses of turtle in a kind of family tree. 

procedure calcarcs local a,b1,b2 * ranging from 1 to root(9/8) by 0.0005 * grabbing 2 data points a=1.0 do while a<=(9/8)^.5 b1 = (1/3)*a + (1/3)*(8*a^2 + 9)^.5 b2 = (1/3)*a  (1/3)*(8*a^2 + 9)^.5 this.runturtle(a,b1) if b1<>b2 this.runturtle(a,b2) endif a=a+0.0005 enddo a = (9/8)^.5 b1 = (1/3)*a + (1/3)*(8*a^2 + 9)^.5 this.runturtle(a,b1) * ranging from .999 to 0 by 0.005 * grabbing 1 data point a=0.999 do while a>=0 b1 = (1/3)*a + (1/3)*(8*a^2 + 9)^.5 this.runturtle(a,b1) a=a0.005 enddo endproc Complete source code for cymkTurtle is provided as a separate web page, for those interested in all the nitty gritty details  many of which have to do with the specifics of Visual FoxPro, the computer language used for this implementation (specifics outside the scope of this paper). 
Since Povray gives us control over the RGB color values for each of the tiny spheres, the next step is to consider how to mix the CYMK primary colors into corresponding mixes of red, green and blue. 

Below is an excerpt of the cymkTurtle colorcalibrating method. It stores RGB values in three columns in our datapoints table, wherein each data point constitutes a row. Note the additional wrinkle: Povray expects its RGB values on a 0 to 1 decimal scale, versus the hexadecimal 0 to 255 scale used in our color charts. This actually makes life easier as our quadray coordinates are likewise in the 0 to 1.06 range  "close enough for folk music" as the expression goes. procedure storecolor(edge,c,y,m,k) do case case edge='ab' && cy replace rcolor with 0.0 + y replace gcolor with 1.0 replace bcolor with 1.0  y ... other edges endcase endproc Note that whereas a given CYMK color is purest at its corresponding home vertex, it actually attains a peak value of root(9/8) at three other points, but in mixture with the other colors at the far ends of three respective arcs. This subtle fact is lost in the rounding of RGB color values and produces no visual effect. Two views of the same colorized spherical tetrahedron are provided below.
Over a year after writing the foregoing, I returned to this challenge of generating a colorized CYMK sphere, again using quadray coordinates to control the relative amounts of cyan, magenta, yellow and black. By this time, I had transferred a lot of the features and functionality of my earlier Visual FoxPro routines into a Java application. This new application also had the ability to apply 3way meshes to the triangular faces of an icosahedron, and inflate these into curved regions. The graphics below provide two views of a 20frequency icosaball with the spherical vertices colorized using their quadray coordinates. The procedure is the same as before: the Java utility writes a POV file, which Povray renders as a BMP, which I then resave as a JPEG. The algorithm I used normalizes a generic quadray 4tuple by dividing through by the largest coordinate. Then I average the RGB contributions of color pairs CY, YM, MB e.g. cyan and yellow each contribute to G (green), so I make G = (C+Y)/2. The K coordinate (black) plays a passive role in that a quadray with a high K value and low C,Y,M values will net an RBG value close to <0,0,0>. Readers might be able to come up with another algorithm that works as well or better.
