Re-reading this, I noticed a mistake. I wrote "CORNERSETS - is a boxed list with 256." but I should have written "CORNERSETS - is a list of 256 boxes." (then going on to say that the end boxes have 1 item while the rest of the boxes have 3 or 6 items - each item representing both the 3d coordinates of a "corner" and the color of that "corner" - and if the corny language isn't making sense then running the code and looking at the display would probably help a lot).
I have also rewritten the code so that the dense parts are hopefully a bit easier to read: coclass 'colourchoice' require 'jzopengl' coinsert 'jzopengl' Note 'wd' p - parent window s - scrollbar -- S will be numeric value 0..255 repesents distance along white/black diagonal c - color display ) NB. object constructor create=:3 :0 ogl=: ''conew'jzopengl' wd 'pc p;' wd 'xywh 0 0 10 256; cc s scrollbarv bottommove; set s 0 127 255 39;' S=: 127 wd 'xywh 10 0 256 256; cc c isigraph opengl rightmove bottommove;' wd 'pas 0 0; pshow;' ) NB. event handlers p_close=: destroy p_c_paint=: 3 :0 rc__ogl'' glClear GL_COLOR_BUFFER_BIT C=: S {:: CORNERSETS select. #C case. 1 do. if. C do. 1 1 1 tri 254 {:: CORNERSETS else. 0 0 0 tri 1 {:: CORNERSETS end. case. 3 do. tri C case. 6 do. tri C end. show__ogl'' ) p_s_button=: 3 :0 S=: 0 ". s wd 'setinvalid c' ) p_c_mbldown=: 3 :0 trac 1 ) p_c_mmove=: 3 :0 trac TRACK ) p_c_mblup=: 3 :0 trac 0 ) NB. implementation destroy=: 3 :0 destroy__ogl'' wd'pclose' codestroy'' ) NB. a transform to plane tangent to white/black axis of colour cube X0=: 1 _1 1 * %: 1 5 1%6 Y0=: _1 0 1 * %: %2 coords=: +/ .*"1&(X0,:Y0)"1 rms=: +/ &.: *:"1 NB. "root mean square" not "richard m stallman" NB. use gift wrapping algorithm to find drawable order for corners NB. http://en.wikipedia.org/wiki/Gift_wrapping_algorithm keep=: 0 {:: [ NB. part of pair on convex hull try=: 1 {:: [ NB. part of pair not known to be on hull start=: ,:@{. ; }. NB. structure list of corners for iterations using try/keep NB. pick next corner based on angle choose=: try #~ [: (= >./) -@^.@rms@(try -"1 {:@keep) giftwrap=: i. 0 {:: (((keep,]) ; try-.]) choose)^:(#@try)@start assert 12 2 3-: $CORNERPAIRS=: (#:i.8) {~ ~./:"1~8 8#:I.,1=rms-"1/~#:i.8 assert 12 86 3-: $CORNERVERTS=: (([ +"1 (85%~i.86) */ -~)/)"2 CORNERPAIRS NB. 256 = 86+85+85 assert (,256)-: $CORNERSETS=: (({~ giftwrap@:coords)^:(6=#))&.> (rms <@~./. ]) ,/CORNERVERTS corner=: 4 :0 glColor3d x glVertex2d y ) tri=: 3 :0"2 y tri y : glBegin GL_POLYGON x corner"1 coords y glEnd'' ) TRACK=: 0 trac=: 3 :0 if. y+.TRACK do. smoutput y,TRACK,2 {. 0".sysdata end. TRACK=: y ) smoutput '' conew 'colourchoice' And remember that this is written for J version 6. Thanks, -- Raul On Fri, Aug 9, 2013 at 12:25 PM, Raul Miller <rauldmil...@gmail.com> wrote: > I should probably document this color-thing somewhat. > > From a top down view, let's pretend that I researched how we perceive > color (and how this can vary from person to person), and how that > relates to various implementations of how computers implement color. > But really, this is something of cubic representation of color, with > the slider representing the white-black range, and the colored part > representing a cross section of that cube perpendicular to the > white/black axis. > > Anyways, this line: > > CORNERSETS=: ((+/&.:*:"1) <@(({~ giftwrap)^:(6=#))@~./. ]) ,/(([ +"1 > (85%~i.86) */ -~)/)"2 ((#~ </"1)8 8 #:I. ,/1=|+/&.: *:"1 -"1/~ #:i.8) > { #:i.8 > > represents that cube. > > This value - CORNERSETS - is a boxed list with 256. The first box > represents black (color: 0 0 0 - red, green, blue) and the last box > represents white (color: 1 1 1). This concept of representing a color > as a sequence of three numbers in the range 0..1 is convenient for use > with opengl. > > The rest of the boxes contain slices of a polygon (either three sided > or six sided) corresponding to a slice across a color cube > perpendicular to the white/black access. Each element of a box can be > thought of as an rgb color value, or as a corner of the face of a > polygon. > > So let's go bottom-up, for a bit, to see how this gets constructed. > > A cube has eight corners, and we can number them: > i. 8 > 0 1 2 3 4 5 6 7 > > The binary representation of these numbers can be thought of as rgb > coordinates for these eight colors. > #:i.8 > 0 0 0 > 0 0 1 > 0 1 0 > 0 1 1 > 1 0 0 > 1 0 1 > 1 1 0 > 1 1 1 > > But that's not enough for the color palette that I wanted. I want not > just the corners, but lines between them. And, for that, I decided to > pair up adjacent corners, so that I could draw lines between them. > That's this: > > ((#~ </"1)8 8 #:I. ,/1=|+/&.:*:"1 -"1/~ #:i.8) { #:i.8 > > The part in parenthesis first finds differences between all corner pairs: > -"1/~ #:i.8 > > and then finds the distance described by that pair > +/&.:*:"1 -"1/~ #:i.8 > > And then I take an absolute value for no good reason - it's a holdover > from an earlier version that's not useful here. (I built this code > "artistically" - thinking of the effect I wanted and using trial and > error, based on appearance and taste, and then posted it before doing > any final cleanup - I felt that give some of you some of the flavor of > my code building process might be useful to you?) > > Anyways, the edges I am interested in have a length of 1, so that's > easy to define: > 1=+/&.:*:"1 -"1/~ #:i.8 > > wait, I'm throwing away all that work! oh no! > > But the interesting bit is in the coordinates of the array, so I > haven't lost anything essential here. All I need to do is ravel it > and use I. and I almost have the coordinates of the interesting edges. > (And I should have just used , instead of ,/ to flatten the cube - at > the time I wrote it, I wasn't thinking clearly there - ,/ gets rid of > just the leading dimension, and I was not looking at my data and had > forgotten that I only had two dimensions here.) But the problem with > I., is that I just get a single number for each 1 bit, and I want a > pair of numbers. But I can recover the information as separate > numbers by using an octal representation: > > 8 8 #:I.,1=+/&.:*:"1 -"1/~ #:i.8 > > That gives me 24 rows of result, and a cube only has 12 edges. I went > a bit over board here, and am representing each edge twice. I can > throw away half of them, but which half? One easy approach discards > edges where the first index is greater than the second index. (#~ > </"1) accomplishes this, but there's another way: > > ~./:"1~8 8 #:I.,1=+/&.:*:"1 -"1/~ #:i.8 > 0 1 > 0 2 > 0 4 > 1 3 > 1 5 > 2 3 > 2 6 > 3 7 > 4 5 > 4 6 > 5 7 > 6 7 > > Now all I need are the corresponding rgb values for each of these cube > indices. I had used (expression) { #:i.8 to get those values, but > there's another way: > > #: ~./:"1~8 8 #:I.,1=+/&.:*:"1 -"1/~ #:i.8 > > Here, I've a rank three array: > > $#:~./:"1~8 8 #:I.,1=+/&.:*:"1 -"1/~ #:i.8 > 12 2 3 > > The 12 is the number of edges of a cube, the 2 is the number of ends > of each edge, and the 3 is the number of dimensions (which I will > think of as red, green, and blue). > > If I could think up a good name, I'd probably stuff this in a variable > to make the rest of it easy. > > Since this is getting long, I'll save the rest of it for another day > (unless someone else wants to take up the banner here?) > > But, briefly, 255=3*85 so I if I make each edge 85 units long (which > becomes 86 values if I include the zero of the axis) I get a total of > 256 values making up my cube diagonal. And, since we have a fair bit > of hardware designed around a 256 division scale for color rendering > that seemed like a nice choice. > > Also, these edges are not arranged in any particular order, so I use a > convex hull algorithm (giftwrap) to arrange them in a form useful for > opengl rendering. > > (And, yes, I am aware that some opengl hardware is... less than ideal? > in terms of color quality. That's not a priority issue for me, at this > stage of the game.) > > So... time for lunch for me. And then I need to do something useful > for the people I work for. I may or may not come back to this bit of > code at a later time. Meanwhile, hopefully I will be able to have > provoked at least a little speculation about what I've written here > and what other mistakes I've made? > > Thanks, > > -- > Raul ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm