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 <[email protected]> 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