Trying again - I've shortened some lines so hopefully the code will actually run (I wish gmail would let me see ahead of time where lines of code will wrap).
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. 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" NB. use gift wrapping algorithm to find drawable order NB. http://en.wikipedia.org/wiki/Gift_wrapping_algorithm start=: ,:@{. ; }. NB. structure list of corners for iterations keep=: 0 {:: [ NB. part of pair on convex hull try=: 1 {:: [ NB. part of pair not known to be on hull NB. pick next corner based on angle: choose=: try #~ [: (= >./) -@^.@rms@(try -"1 {:@keep) giftwrap=: i. 0 {:: (((keep,]) ; try-.]) choose)^:(#@try)@start CORNERPAIRS=: (#:i.8) {~ ~./:"1~8 8#:I.,1=rms-"1/~#:i.8 CORNERVERTS=: (([ +"1 (85%~i.86) */ -~)/)"2 CORNERPAIRS NB. 256 = 86+85+85 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' -- Raul On Tue, Dec 10, 2013 at 9:17 PM, Raul Miller <rauldmil...@gmail.com> wrote: > 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