PitchCircle visual representation of cycle of fifths sets


PitchCircle is intended to provide a visual representation of 12-tone equal temperament C7 segments and subsets, entered as arrays of integers. It is not intended to provide pitch-class operations (other than a simple complementation method). Note that microtonal representations are possible, but do not work with many instance methods. See the example at the end of the file.


 

Creation / Class Methods


*new (steps, tonic, mod, offset, drawints, size, win, num)


steps - number of steps in circle. Default value is 12.

tonic - as an integer, default value is 0 ("C major" collection) if number of steps is 7.

mod - circle generator, either scalic/chromatic (1),  circle of 5ths (7), or thirds (3). Default value is 1

offset - rotates the circle in steps. Default value is 0, where the "tonic" is at the 

top of the circle. Negative offset values are valid.

drawints - boolean as to whether to display note names or pc integers. 

Default value is false. Note that PitchCircle may not provide correct 

diatonic note spellings for complex keys (or natural minor modes).

size - window size in pixels if a window is not passed in. Default value is 300.

win - a window can be passed in, default is a new window. PitchCircle expects win to have a  FlowLayout decorator for positioning.

num - an Integer. Default is 1; use higher nums if you want to nest further 

PitchCircles in the default window.


// example

p = PitchCircle.new(num: 2);

u = PitchCircle.new(win: p.win);

p.drawSet;

u.dotsColFn = { Color.red }; 

u.drawSet(p.complement)

p.close;


Instance variables

set_(aSet) 

set

set or access the primary pc array for display. Its type is an Array, but Sets can be used. Can be bypassed using the drawSet method. Default is the diatonic set [0, 2, 4, 5, 7, 9, 11], transposed to tonic.


// example

p = PitchCircle.new(7, 2);

p.set // default here is [ 2, 4, 6, 7, 9, 11, 1 ]

p.drawSet;

p.set_([2, 4, 6]); 

p.drawSet;

dotsColFn_(aFunction)

dotsColFn

set or access the function that determines the color for the display dots. 

The function is passed in the set as an argument when evaluated upon drawing the set.

The default function is { Color.blue }. 

Takes effect when circle is next drawn.

// example

p = PitchCircle.new;

p.dotsColFn = {|set| if(set.size<4, {Color.red}, {Color.green})};

p.set_([2, 4, 6]); 

p.drawSet;

p.drawSet([2, 4, 6, 7, 8])



drawInts_(boolean)

drawInts

see the corresponding argument in *new.  Takes effect when circle is next drawn.


hlDots_(dots)

hlDots

set or return the current dots Array. A dot will have an extra circle around if if is included in set. Takes effect when circle is next drawn; default is nil.

lines_(boolean)

lines

toggle between drawing lines between pc elements. Default is true.

steps

steps_(integer)

see the corresponding argument in *new.  Takes effect when circle is next drawn.


tonic

tonic_(integer)

see the corresponding argument in *new. Takes effect when circle is next drawn. Note that if steps is 12, changing the tonic has the effect only of altering the offset, and possibly respelling the note names.

mod_(arg1)

mod

see the corresponding argument in *new.  Takes effect when circle is next drawn.

offset_(arg1)

offset

see the corresponding argument in *new.  Takes effect when circle is next drawn.


labelAlign_(aSymbol)

labelAlign


Sets or returns the label text alignment. Default value is \center.


labelSize_(integer)

labelSize


Sets or returns the label font size. Takes effect when circle is next drawn.



labelAlign_(aSymbol)

labelAlign


Returns or sets the label text alignment. Default value is \center.


// Instance variables example

p = PitchCircle.new(7, 3, 3);

p.drawInts_(true);

p.drawSet;

p.drawInts_(false);

p.offset_(5);

p.set_([10, 2, 5, 8]); 

p.drawSet;

p.drawLabel("Bb Major 7th chord")

Instance methods


drawSet (aSet, aLabel, aDotsCol)

aSet - an Array or Set. Default value is the set instance variable.

aLabel - a String. Default value is aSet.

aDotsCol -  Default value is the dotsColFn instance variable

// example

p = PitchCircle.new;

p.set_(Set[ 0, 2, 4, 6, 8, 10 ]);

p.drawSet(aLabel: format("A wholetone scale %", p.set.asArray)) 



drawLabel (aString, align)

aString - a String. Default value is aSet.

align -  Default value is the dotsColFn instance variable

setAll (mod, tonic, offset, steps)


// example

p = PitchCircle.new;

p.set_([6, 8, 10, 1, 3]);

p.drawSet;

p.setAll(1, 1, 0, 7); // mod, tonic, offset, steps

p.set // => [ 1, 3, 6, 8, 10 ]

p.drawSet;


drawSets (aSets, aLabel, colsArr)

draws an array or arrays (sets) in different colors.

aSets - an array of Arrays or Sets.

aLabel - default is aSets.

colsArr - an optional Array of colours. 


// example

p = PitchCircle.new;

a = [0, 1, 5];

p.drawSets([a, a+3, a+6]);



addSet (aSet, aLabel, aDotsCol)

an alternative to drawSets. Superimposes a second set over the set instance variable.

aSet - an Array or Set.

aDotsCol - default value is Color.green.

// example

p = PitchCircle.new;

p.set_([0, 2, 7]);

p.drawSet(p.set)

p.addSet([4, 5, 6]);



addSpacing (num, aDotsCol)

This is designed to be used to demonstrate maximal evenness (see the writings of John Clough). 

Like addSet, the result is superimposed over the set instance variable.

num - number of divisions of the circle. Default value is 7.

aDotsCol -  default value is Color.green.

// example

p = PitchCircle.new;

p.set_([10, 0, 2, 5, 7])

p.addSpacing(5);


complement (aSet)

returns the complement of an Array or Set.

aSet - Explanation of aSet. Default value is the set instance variable.

// example

p = PitchCircle.new;

p.set_([10, 0, 2, 5, 7])

// See post window

p.complement; // => [ 1, 3, 4, 6, 8, 9, 11 ]

p.complement([0, 2, 4, 6, 8, 10])


drawCompl (aDotsCol, aLabel)

A shorthand method for drawing  set and its complement.

// example

p = PitchCircle.new;

p.set_([10, 0, 2, 5, 7]);

p.drawCompl;


front

brings the PitchCircle window to the front.

p.front;


close

close the PitchCircle window.

p.close;



// Examples

(

var newSet;

p = PitchCircle.new;

Routine {

p.labelAlign_(\left);

24.do({ |i|

if(i.even, {

{

newSet = p.complement.scramble.keep(rrand(4, 6)).sort;

p.hlDots_(newSet.sect([11, 0, 1]).choose);

p.drawSet(newSet);

}.defer;

}, {

{ p.complement(p.set);

  p.drawCompl(

  aLabel: format("%  compl.: %", 

  p.set, p.complement(p.set))

  );

}.defer;

});

0.5.wait;

});

1.wait;

p.close;

}.play;

)

// 19-ET microtonal example

(

p = PitchCircle.new(19);

i = (0..18);

n = ["C", "C#", "Db", "D", "D#", "Eb", "E", "E#", "F", "Gb", "F#", "Gb", "G", "G#", "Ab", "A", "A#", "B", "B#"];

p.notes = n;

p.integers = i;

p.hlDots_(2);

p.drawInts_(true);

p.drawSet([0, 2, 4, 6, 8, 10]);

)

(

// the offset variable cannot be used directly

var rotn=5.neg;

p.notes = n.rotate(rotn);

p.integers = i.rotate(rotn);

p.drawInts_(false);

p.hlDots_((2 + rotn)%19);

p.drawSet;

)