·

# Lines+Colors

For this week's Creative Code Challenge by @sableraph: "Swiss Design”, Lines+Colors is coded in Hydra & SonicPi. It uses linear algebra concepts in both the visuals and audio to make the piece. This is inspired and uses Cramer rule as a focal point.

## Colors as Building Blocks

Gabriel Cramer is a swiss mathematician which the rule is named after as it is used in solving systems of linear equations: https://en.wikipedia.org/wiki/Cramer%27s_rule . In addition to this rule, the audiovisual components are controlled by various properties and aspects of matrices (inverse, normal, linear transformations,etc)

This can be seen as the visuals are intersecting color lines and in the audio, colors are grouped into sets to make new colors and connections. Which is then carried on in the composition.

## Poem

``````Colours reflecting
Colours intersecting
Rebuilding with the excerpts
That have joined the intersects
What combinations can be heard?
What information can be unearthed?
What new patterns can be birthed?
Some pleasant and others absurd?
``````

## Code

### Hydra

``````

var y = prompt("choose between number 0 - 39")

//3 x 3 matrix based on the y prompt
pos = [y*2,y-21,y,y+3,Math.abs(y-7),y+5,y/4, y/5+2, y-14]

a = pos[0]
b = pos[1]
c = pos[2]
d = pos[3]
e = pos[4]
f = pos[5]
g = pos[6]
h = pos[7]
i = pos[8]

//recoding into Matrix Coordinates

A11 = a
A12 = b
A13 = c
A21 = d
A22 = e
A23 = f
A31 = g
A32 = h
A33 = i

//determinant formula
det_a = a*(e*i - f*h) - b*(d*i - f*g) + c*(d*h - e*g)
trace = a + e +  i
normal = Math.sqrt(a*a + b*b + c*c + d*d + e*e + f*f + g*g + h*h +  i*i)

Adj_b = -1 * (A12*A33 - A13 * A32)
Adj_c = A12 *A23 - A13*A22
Adj_d = -1 * (A21 * A33 - A23 *A31)
Adj_e = (A11 *A33 - A13 * A31)
Adj_f = -1 * (A11 * A23 - A13 *A21)
Adj_g = (A21 * A32 - A22 *A31)
Adj_h = -1 *(A11 * A32 - A12 *A31)
Adj_i = (A11 *A22 - A12 *A21)

//inverse formula

shape(()=> normal/trace,trace/det_a,1)
.scale(0.5,1).colorama()
.color([0.5,2].smooth(1),[0.15,0.35,0.14,1,1.25].smooth(),[0.25,0.5,0.12,0.05,2,4])
.repeat(()=> det_a,trace)
.modulateScale(osc(3,0.5),-0.6)
.scale([inv_a/inv_b,inv_c/inv_d].smooth())
.out()

speed = inv_d
``````

### SonicPi

``````#Colors pair 1
Aqua = [0,255,255]
Coral = [255,127,80]

#Colors Pair 2
Lavender = [230, 230, 250]
Gold = [255,215,0]

#Colors Pair 3
MidnightBlue = [25,25,112]
DarkOrange = [255,140,0]

#Colors Pair 4
SlateGray = [112, 128, 144]
Crimson = [220,20,60]

def linear_transform(matrixA,vectorA)

#this is the first row of the matrix
row1 = matrixA[0]
#this is the second row of the matrix
row2 = matrixA[1]
#this is the third row of the matrix
row3 = matrixA[2]

#this is the first val of the vector
vec_x = vectorA[0]
#this is the second val of the vector
vec_y = vectorA[1]
#this is the third val of the vector
vec_z = vectorA[2]

#this is the first value of the new vector
vec_x_formed = [row1[0]*vec_x + row1[1]*vec_y + row1[2]*vec_z]
#this is the second value of the new vector
vec_y_formed= [row2[0]*vec_x + row2[1]*vec_y + row2[2]*vec_z]
#this is the third value of the new vector
vec_z_formed = [row3[0]*vec_x + row3[1]*vec_y + row3[2]*vec_z]

#new vector
vec_change = [vec_x_formed[0],vec_y_formed[0],vec_z_formed[0]]

end

#Cramers Rule with Colors

x1a = row1[0]
x2a = row1[1]
b_a = row1[2]

x1b = row2[0]
x2b = row2[1]
b_b = row2[2]

#determinant of main matrix [x1a,x2a,x1b,x2b]
det_a = ((x1a * x2b) - (x2a * x1b)).to_f

#determinant of main matrix but first column replace by b_a & b_B
det_b = (b_a * x2b) - (x2a * b_b)

#determinant of main matrix but second column replace by b_a & b_B
det_c = (x1a * b_b) - (b_a * x1b)

#the solving of the above equations

det_1 = det_b/det_a
det_2 = det_c/det_a

puts det_1
puts det_2

live_loop loop do
use_random_seed Time.now.to_i
with_fx :ping_pong, mix: rrand(0.4,0.65) do
end

with_fx :echo do
use_synth :piano
play det_2/det_1
end

end
end

def color_det(loop,row1,row2)

#Cramers Rule with Colors

x1a = row1[0]
x2a = row1[1]
b_a = row1[2]

x1b = row2[0]
x2b = row2[1]
b_b = row2[2]

#determinant of main matrix [x1a,x2a,x1b,x2b]
det_a = ((x1a * x2b) - (x2a * x1b)).to_f

#determinant of main matrix but first column replace by b_a & b_B
det_b = (b_a * x2b) - (x2a * b_b)

#determinant of main matrix but second column replace by b_a & b_B
det_c = (x1a * b_b) - (b_a * x1b)

#the solving of the above equations

det_1 = det_b/det_a
det_2 = det_c/det_a

puts det_1
puts det_2

sample

live_loop loop do
use_random_seed Time.now.to_i
with_fx :ping_pong, mix: rrand(0.4,0.65) do

sample [:ambi_choir,:glitch_perc3,:bass_woodsy_c].choose, rate: [det_1,det_2].choose,beat_stretch: [(det_2).abs,(det_1).abs].tick, pitch: [det_1/det_2,det_2/det_1].choose
sleep (det_1+det_2).abs

use_synth :piano
play (det_1/det_2).abs

with_fx :krush do
use_synth :prophet
play (det_2/det_1).abs
end
end
end
end

#this mathematical sections turns the combo of Aqua, Lavender, Gold into Cyber Neon Green
#R,G,B(0,250,40)

color_matrix1 = [Aqua, Lavender, Gold]
first_vector = [1,-1,1]

CyberNeonGreen = linear_transform(color_matrix1,first_vector) #0,250, 40

#this mathematical sections turns the combo of SlateGray, DarkOrange, MidnightBLue into SoftPink
color_matrix2 = [SlateGray, DarkOrange, MidnightBlue]
second_vector = [1,-1,1.75]

SoftPink = linear_transform(color_matrix2,second_vector) #236,115,196

color_matrix3 = [Crimson, SlateGray, Coral]
third_vector = [0.5,1,2]

CucumberIce  = linear_transform(color_matrix3,third_vector) #210,216,160.5 https://icolorpalette.com/color/d2d8a1

#getting the traces
color_mx1_trace = color_matrix1[0][0] + color_matrix1[1][1] + color_matrix2[2][2]
color_mx2_trace = color_matrix2[0][0] + color_matrix2[1][1] + color_matrix2[2][2]
color_mx3_trace = color_matrix3[0][0] + color_matrix3[1][1] + color_matrix3[2][2]

live_loop :ColorBending do
use_random_seed Time.now.to_i / 2

with_fx :whammy, mix: 0.25 do
color_det(:aquaVcoral,Aqua,Coral)
sleep [0.5,1,4].choose
color_det(:LavenderVgold, Lavender, Gold)
sleep [0.5,1,2].choose
color_det(:MidnightvsOrange,MidnightBlue, DarkOrange)
sleep 2
color_det(:GrayvCrimson,SlateGray, Crimson)
sleep [1,2].choose
end

with_fx :hpf do
with_fx [:wobble,:ping_pong].choose, mix: rrand(0.2,0.6) do
with_fx [:ping_pong,:vowel].choose,  mix: rrand(0.25,0.75) do
color_det(:aquaVGold,Aqua,Gold)
sleep [2,4,8].choose
color_det(:CrimsonVcoral,Crimson,Coral)
sleep [2,4,8].choose
color_det(:LavenderVOrange,DarkOrange, Lavender)
color_det(:GrayvBlue,SlateGray, MidnightBlue)
end
end
end

sleep [0.5,1,2,4].choose
end

live_loop :colortwisting do
with_fx :echo, mix: 0.65 do
with_fx :ping_pong do
color_det2(:CybervsSoft,CyberNeonGreen,SoftPink,color_mx1_trace,color_mx2_trace)
sleep [2,4,8].choose
color_det2(:IcevsWarmth,SoftPink,CucumberIce,color_mx2_trace,color_mx3_trace)
sleep [2,4,8].choose
color_det2(:IcevsCyber,CucumberIce,CyberNeonGreen,color_mx3_trace,color_mx1_trace)
sleep [3,6,9].choose
end
end
sleep [0.5,1,2].choose
end

#//3 x 3 matrix sound by random numbers between 0  & 30
live_loop :choirflow do
use_random_seed Time.now.to_i

y = rrand(0,30)
puts y

pos = [y*2,y-21,y,y+3,(y-7).abs,y+5,y/4, y/5+2, y-14]

a = pos[0]
b = pos[1]
c = pos[2]
d = pos[3]
e = pos[4]
f = pos[5]
g = pos[6]
h = pos[7]
i = pos[8]

#//recoding into Matrix Coordinates

A11 = a
A12 = b
A13 = c
A21 = d
A22 = e
A23 = f
A31 = g
A32 = h
A33 = i

#//determinant formula
det_a = a*(e*i - f*h) - b*(d*i - f*g) + c*(d*h - e*g)
trace = a + e +  i
normal = Math.sqrt(a*a + b*b + c*c + d*d + e*e + f*f + g*g + h*h +  i*i)

Adj_b = -1 * (A12 * A33 - A13 * A32)
Adj_c = A12 * A23 - A13 * A22
Adj_d = -1 * (A21 * A33 - A23 * A31)
Adj_e = (A11 * A33 - A13 * A31)
Adj_f = -1 * (A11 * A23 - A13 * A21)
Adj_g = (A21 * A32 - A22 * A31)
Adj_h = -1 *(A11 * A32 - A12 * A31)
Adj_i = (A11 * A22 - A12 * A21)

#inverse formula

sample :ambi_choir, decay: Adj_a.abs, rate: inv_a
sample [:ambi_choir,:loop_breakbeat].choose , decay: Adj_b.abs, rate: inv_b
sample :ambi_choir , decay: Adj_c.abs, rate: inv_c
sleep [1,2,4,8].choose
sample [:ambi_choir,:tabla_ghe3].tick , decay: Adj_d.abs, rate: inv_d
sample :ambi_choir , decay: Adj_e.abs, rate: inv_e
sample [:ambi_choir,:loop_weirdo].choose , decay: Adj_f.abs, rate: inv_f
sleep [4,8,16].choose
puts inv_i

sleep [0.5,1,2,4].choose

end
``````
``````live_loop :remix do
use_random_seed Time.now.to_i/3 #making true random as it goes with the actual time
puts Time.now.to_i
with_fx :echo, mix: rrand(0.4,0.8) do
sample "Line+Color.wav", sustain: dice(10)
end
sleep [0.25,0.5,1,2,4].choose
end

live_loop :remix2 do
use_random_seed Time.now.to_i/3 #making true random as it goes with the actual time
puts Time.now.to_i
with_fx [:ping_pong,:whammy,:pitch].choose, mix: rrand(0.1,0.5) do
sample "Line+Color.wav", rate: rrand(-2,2.4) - 0.1
end
sleep [8,16,24].choose
end
``````