Huippukivaa taidetta 2000-luvun alun REBOL-kielellä?
Päästäänkö tällä videolla Nykytaiteen museoon?! 🤣☺️❗
Minulle on kertynyt vuosien varrella melko paljon algoritmisen taiteen kuvia: https://petke.info/uus/art.html
Toteutin nyt 3D gallerian REBOL-kielellä. Tein 20 minuuttisen videon: https://youtu.be/4-LphIISStY
Sinne mahtui 84 kuvaa, jotka valitsin 171:stä.
Videon nimi on "Risa 3D". Teos olisi tylsä, jos siinä olisi teknisesti täydellinen 3D grafiikka. Nyt se rumasti sanottuna välillä kusee.
Teoksen hakemus Suomen Taiteilijat ry:n vuosinäyttelyyn:
Hei,
haen Suomen Taiteilijat ry:n vuosinäyttelyyn videoinstallaatiollani "Risa 3D".
Teos on 20 minuutin mittainen, non-stop -loopissa esitettävä video. Se on suunniteltu esitettäväksi yksinkertaisella ja luotettavaksi testatulla laitteistolla (mediatoistin ja 24” näyttö/televisio).
Videossa liikutaan pienessä 3D-virtuaaligalleriassa, jossa on esillä 84 valitsemaani algoritmisen taiteen kuvaani. Kamera liikkuu tilassa edestakaisin samalla pyörien, minkä ansiosta näkymä ei toistu teoksen aikana. Lisäksi galleriassa tapahtuu satunnaisia muutoksia: keskimäärin noin 1000 freimin välein kaikkien teosten kuvat vaihtuvat uudelleen. Näihin hetkiin liittyy lyhyt ääniefekti, muuten teos on äänetön.
Teoksen nimi viittaa sen tarkoitukselliseen epätäydellisyyteen. Se on toteutettu 2000-luvun alun REBOL-ohjelmointikielellä, minkä seurauksena 3D-tilassa esiintyy visuaalisia poikkeamia ja “kauneusvirheitä”. Nämä eivät ole pelkkiä teknisiä rajoitteita, vaan olennainen osa teoksen estetiikkaa: tila ei ole vakaa eikä täysin hallittavissa.
Linkki videoon: https://youtu.be/4-LphIISStY
Ystävällisin terveisin,
Petri Keckman
Sitten itse Ohjelmointiputkan asiaan, eli koodeihin. Selittelemättä ehkä paras? Lopputulos ratkaisee?
rebol[]
print "odota"
maxx: 1920
maxy: 1080
alfay1: -70
origx: -6000
origy: 0
origz: -20000
dx: 100
x0: maxx / 2
y0: maxy / 2
polys: copy []
pituusx: 4000
pituusy: 12000
pituusz: 2000
bkuvat: copy[]
kind: 1
for i 1 85 1 [
kuva: load to-file rejoin ["u" i ".png"]
append bkuvat kuva
]
;LAitetaan taulut *****************************************************************************************
lisaaTaulu: func [p1 p2 p3 p4 pic][
; --- skaalatut pisteet ---
xt: reduce [
(pituusx * p1/1)
(pituusx * p2/1)
(pituusx * p3/1)
(pituusx * p4/1)
]
yt: reduce [
(pituusy * p1/2)
(pituusy * p2/2)
(pituusy * p3/2)
(pituusy * p4/2)
]
zt: reduce [
(pituusz * p1/3)
(pituusz * p2/3)
(pituusz * p3/3)
(pituusz * p4/3)
]
; --- laske normaali ---
ax: xt/2 - xt/1
ay: yt/2 - yt/1
az: zt/2 - zt/1
bx: xt/3 - xt/1
by: yt/3 - yt/1
bz: zt/3 - zt/1
nx: (ay * bz) - (az * by)
ny: (az * bx) - (ax * bz)
nz: (ax * by) - (ay * bx)
; --- jos normaali väärin päin ? flip ---
if nz < 0 [
xt: reverse xt
yt: reverse yt
zt: reverse zt
]
; --- lisää poly ---
append polys make object! [
xtb: xt
ytb: yt
ztb: zt
depth: 0
kuva: pic
]
]
; =========================
; SEINÄ NUMERO 1 (Z vakio)
; =========================
minx1: 9999999
alkux: 3
alkuy: -0.65
välix: 0.6
väliy: 0.3
kokox: 1.2
kokoy: 0.55
z: -7
for i 1 8 1 [
xL: alkux - (i * kokox) - ((i - 1) * välix)
xR: alkux - ((i + 1) * kokox) - ((i - 1) * välix)
for j 1 2 1 [
yT: alkuy + (j * kokoy) + ((j - 1) * väliy)
yB: alkuy + ((j - 1) * kokoy) + ((j - 1) * väliy)
lisaaTaulu
reduce [xL yT z] ; ylä-vasen
reduce [xR yT z] ; ylä-oikea
reduce [xR yB z] ; ala-oikea
reduce [xL yB z] ; ala-vasen
bkuvat/(kind)
kind: kind + 1
if xL < minx1 [minx1: xL]
]
]
; =========================
; SEINÄ NUMERO 2 KAKSI TAULUA (X vakio)
; =========================
lisaaTaulu
reduce [4 0.5 0.7] ; ylä-vasen
reduce [4 0.5 -2.7] ; ylä-oikea
reduce [4 -0.6 -2.7] ; ala-oikea
reduce [4 -0.6 0.7] ; ala-vasen
bkuvat/(kind)
kind: kind + 1
lisaaTaulu
reduce [4 0.5 -3.2] ; ylä-vasen
reduce [4 0.5 -6.6] ; ylä-oikea
reduce [4 -0.6 -6.6] ; ala-oikea
reduce [4 -0.6 -3.2] ; ala-vasen
bkuvat/(kind)
kind: kind + 1
; =========================
; SEINÄ NUMERO 3 (Z vakio)
; =========================
sivux: 1.3
sivuy: 0.54
alkuy: -0.65
alkux: 4.4
välix: 0.2
väliy: 0.2
for i 1 6 1 [
xL: alkux + ((i - 1) * sivux) + ((i - 1) * välix)
xR: alkux + (i * sivux) + ((i - 1) * välix)
for j 1 2 1 [
yT: alkuy + (j * sivuy) + ((j - 1) * väliy)
yB: alkuy + ((j - 1) * sivuy) + ((j - 1) * väliy)
z: 1.2
lisaaTaulu
reduce [xR yT z] ; ylä-vasen
reduce [xL yT z] ; ylä-oikea
reduce [xL yB z] ; ala-oikea
reduce [xR yB z] ; ala-vasen
bkuvat/(kind)
kind: kind + 1
]
]
; =========================
; SEINÄ NRO 4 (X vakio)
; =========================
sivux: 3
sivuy: 0.54
alkuy: -0.7
alkux: 6.5
välix: 0.4
väliy: 0.2
alkuz: 1.4
for i 1 4 1 [
zL: alkuz + ((i - 1) * sivux) + ((i - 1) * välix)
zR: alkuz + (i * sivux) + ((i - 1) * välix)
for j 1 2 1 [
yT: alkuy + (j * sivuy) + ((j - 1) * väliy)
yB: alkuy + ((j - 1) * sivuy) + ((j - 1) * väliy)
lisaaTaulu
reduce [14 yT zR] ; ylä-vasen
reduce [14 yT zL] ; ylä-oikea
reduce [14 yB zL] ; ala-oikea
reduce [14 yB zR] ; ala-vasen
bkuvat/(kind)
kind: kind + 1
]
]
; =========================
; PITKÄ SEINÄ NUMERO 5 (Z vakio)
; =========================
alkux: 14
alkuy: -0.65
välix: 0.7
väliy: 0.3
kokox: 0.9
kokoy: 0.55
z: 15
minx6: 99999
maxx6: -999999
for i 1 11 1 [
xL: alkux - (i * kokox) - ((i - 1) * välix)
xR: alkux - ((i + 1) * kokox) - ((i - 1) * välix)
for j 1 2 1 [
yT: alkuy + (j * kokoy) + ((j - 1) * väliy)
yB: alkuy + ((j - 1) * kokoy) + ((j - 1) * väliy)
lisaaTaulu
reduce [xR yT z] ; ylä-vasen
reduce [xL yT z] ; ylä-oikea
reduce [xL yB z] ; ala-oikea
reduce [xR yB z] ; ala-vasen
bkuvat/(kind)
kind: kind + 1
]
if xL < minx6 [minx6: xL]
if xL > maxx6 [maxx6: xL]
]
; =========================
; VIKASEINÄ NRO 6 (X vakio)
; =========================
sivux: 4
sivuy: 1
alkuy: -1
välix: 0.8
väliy: 0.2
alkuz: -1
x: -14
minx7: 99999
maxx7: -999999
for i 1 10 1 [
zL: alkuz + ((i - 1) * sivux) + ((i - 1) * välix)
zR: alkuz + (i * sivux) + ((i - 1) * välix)
for j 1 2 1 [
yT: alkuy + (j * sivuy) + ((j - 1) * väliy)
yB: alkuy + ((j - 1) * sivuy) + ((j - 1) * väliy)
lisaaTaulu
reduce [x yT zL] ; ylä-vasen
reduce [x yT zR] ; ylä-oikea
reduce [x yB zR] ; ala-oikea
reduce [x yB zL] ; ala-vasen
bkuvat/(kind)
kind: kind + 1
if xL < minx7 [minx7: xL]
if xL > maxx7 [maxx7: xL]
]
]
dz: -10000
foreach poly polys [
poly/ztb/1: poly/ztb/1 + dz
poly/ztb/2: poly/ztb/2 + dz
poly/ztb/3: poly/ztb/3 + dz
poly/ztb/4: poly/ztb/4 + dz
]
print kind
print minx1
print minx6
print maxx6
print minx7
print maxx7
freimit: copy[]
for kuvaind 1 (20 * 60 * 30) 1 [
plot: copy[]
foreach poly polys [
ztb: poly/ztb
; keskimääräinen z
depth: (
(ztb/1 + ztb/2 + ztb/3 + ztb/4) / 4
)
poly/depth: depth
]
sort/compare polys func [a b][
a/depth > b/depth
]
foreach poly polys [
xtb: poly/xtb
ytb: poly/ytb
ztb: poly/ztb
kuva: poly/kuva
xp: copy []
yp: copy []
kelpaa: true
valid: true
xrlist: copy []
zrlist: copy []
; --- KIERRÄ + PROJEKTIO ---
repeat i 4 [
apu: xtb/:i
xr: ((cosine alfay1) * xtb/:i) + ((- sine alfay1) * ztb/:i)
zr: ((sine alfay1) * apu) + ((cosine alfay1) * ztb/:i)
append xrlist xr
append zrlist zr
; ?? TÄRKEIN: jos yksikin piste kameran edessä ? hylkää koko poly
if (zr + origz) >= 0 [
valid: false
]
jakaja: (maxx - (zr + origz))
if jakaja = 0 [jakaja: 0.00000000001]
temp: maxx / jakaja
append xp (x0 + ((xr + origx) * temp))
append yp (y0 - ((ytb/:i + origy) * temp))
]
; --- PIIRTO ---
if all [
kelpaa
valid
(length? xp) >= 4
][
append plot compose [
image (as-pair xp/1 yp/1)
(as-pair xp/2 yp/2)
(as-pair xp/3 yp/3)
(as-pair xp/4 yp/4)
(kuva)
]
]
]
main: layout [
box (as-pair (maxx) (maxy)) white effect reduce ['draw plot]
]
kuva1: copy/part skip to-image main (as-pair 20 20) (as-pair maxx maxy)
save/png to-file rejoin ["yritys" kuvaind ".png"] kuva1
print kuvaind
alfay1: alfay1 - 0.1
maxxpoly: -9999999
minpoly: 9999999
foreach poly polys [
poly/xtb/1: poly/xtb/1 + dx
poly/xtb/2: poly/xtb/2 + dx
poly/xtb/3: poly/xtb/3 + dx
poly/xtb/4: poly/xtb/4 + dx
if poly/xtb/4 > maxxpoly [maxxpoly: poly/xtb/4]
if poly/xtb/4 < minpoly [minpoly: poly/xtb/4]
]
if (maxxpoly > 70000) or (minpoly < -108000) [dx: - dx]
;print [minpoly maxxpoly]
if ((random 1000) = 1) and (kuvaind > 500) [
repeat i length? polys [
ran: random length? polys
apu: polys/:i/kuva
polys/:i/kuva: polys/:ran/kuva
polys/:ran/kuva: apu
]
append freimit kuvaind
]
]
probe freimit
halt
; ffmpeg -framerate 30 -i yritys%d.png -c:v libx264 -r 30 video.mp4No, selitetään vähän tätä toista koodia, jolla laitoin ääniefektin niihin kohtiin, joissa taulujen kuvat sekoitettiin. Freimeja tehdessä oli ehto:
if ((random 1000) = 1) and (kuvaind > 500)
..niin silloin sekoitetaan kaikki gallerian taulut. eli noin joka tuhannes freimi. Otin kuvaind muuttujan arvot talteen ja ohjelman lopuksi tulostin ne liitin tähän ohjemaan:
rebol []
lmrk: to-char 34 ; "
filters: copy ""
inputs: copy ""
; --- SYÖTE ---
freimit: [987 1750 1935 3234 3665 3848 4346 5012 6309 8638 8975 11192 12400 13517 14178 15000 15080 15266 16495
18326 19471 19596 20429 20799 21425 22089 22266 22563 22927 23195 23526 23937 24499 24747 25838 26760
27813 28183 31328 31443 31638 33452 33613 33938 34258 34334 34627 34758 35495 35718 35922] ; <-- sinun data tähän
print ["PAM määrä:" length? freimit]
; --- VÄLIT ---
välit: copy []
repeat i (length? freimit) - 1 [
append välit (freimit/(i + 1) - freimit/(i))
]
; --- PERUSARVOT ---
sum: 0
minv: 999999999
maxv: 0
foreach v välit [
sum: sum + v
if v < minv [minv: v]
if v > maxv [maxv: v]
]
keski: sum / length? välit
print "---- PERUS ----"
print ["keski väli:" keski]
print ["min väli:" minv]
print ["max väli:" maxv]
; --- VARIANSSI ---
var: 0
foreach v välit [
var: var + ((v - keski) * (v - keski))
]
var: var / length? välit
print ["varianssi:" var]
; --- KLUSTERIT ---
cluster-raja: 200
print "---- KLUSTERIT ----"
cluster-count: 0
repeat i (length? freimit) - 1 [
väli: freimit/(i + 1) - freimit/(i)
if väli < cluster-raja [
print ["CLUSTER!" freimit/(i) "->" freimit/(i + 1) "väli:" väli]
cluster-count: cluster-count + 1
]
]
print ["clusterien määrä:" cluster-count]
; --- HISTOGRAMMI ---
pieni: 0
normaali: 0
iso: 0
foreach v välit [
either v < 500 [
pieni: pieni + 1
][
either v < 1500 [
normaali: normaali + 1
][
iso: iso + 1
]
]
]
print "---- JAKAUMA ----"
print ["pieni (<500):" pieni]
print ["normaali (500-1500):" normaali]
print ["iso (>1500):" iso]
; --- BONUS: ENSIMMÄISET VÄLIT ---
print "---- EKAT 10 VÄLIÄ ----"
repeat i min 10 length? välit [
print välit/:i
]
fps: 30
repeat i length? freimit [
freimi: freimit/:i
suunta: 0
if random 100 > 80 [suunta: 1 + random 2]
if random 100 < 10 [suunta: -1 - random 2]
frame2: freimi + suunta
aika-ms: to-integer (frame2 * 1000 / fps)
idx: random 11
tied: rejoin [idx ".wav"]
append inputs rejoin [" -i " tied]
; ?? EI VÄLEJÄ | ympärille!
append filters rejoin [
"[" i ":a]adelay=" aika-ms "|" aika-ms "[a" i "];"
]
]
; --- amix ---
mix: copy ""
repeat i length? freimit [
append mix rejoin ["[a" i "]"]
]
append filters rejoin [
mix "amix=inputs=" length? freimit
]
; --- KOMENTO ---
cmd: rejoin [
"ffmpeg -i video.mp4"
inputs
" -filter_complex "
lmrk filters lmrk
" -c:v copy -c:a aac output.mp4"
]
write %render.cmd cmd
print "render.cmd tehty"
haltSe teki .cmd skriptin, jossa ffmpeg:n käskyllä lisätään arvottu ääniefekti 1.wav, 2.wav,...,11.wav siihen kohtaan, missä kaikki gallerian taulut sekoitetaan. ffmpeg:n ohjelman syntaksista en paljoa tajunnut, eikä tarvinnutkaan, sillä tuon skriptin antoi ChatGPT. Huvikseni pistin sen tulostamaan (ChatGPT:n avustuksella) kaikenlaista dataa noista kohdista, joissa videossa taulut sekoitetaan ja tulee ääniefekti:
PAM määrä: 51 ---- PERUS ---- keski väli: 698.7 min väli: 76 max väli: 3145 varianssi: 422605.49 ---- KLUSTERIT ---- CLUSTER! 1750 -> 1935 väli: 185 CLUSTER! 3665 -> 3848 väli: 183 CLUSTER! 15000 -> 15080 väli: 80 CLUSTER! 15080 -> 15266 väli: 186 CLUSTER! 19471 -> 19596 väli: 125 CLUSTER! 22089 -> 22266 väli: 177 CLUSTER! 31328 -> 31443 väli: 115 CLUSTER! 31443 -> 31638 väli: 195 CLUSTER! 33452 -> 33613 väli: 161 CLUSTER! 34258 -> 34334 väli: 76 CLUSTER! 34627 -> 34758 väli: 131 clusterien määrä: 11 ---- JAKAUMA ---- pieni (<500): 27 normaali (500-1500): 18 iso (>1500): 5 ---- EKAT 10 VÄLIÄ ---- 763 185 1299 431 183 498 666 1297 2329 337 render.cmd tehty
20 minuutin videoon tulee 36 000 framea, eli kohtien odotusarvo oli 36, mutta niitä tulikin 51 kpl.
En oikein jaksa selitellä! Taide puhukoon puolestaan. Jos on jotain kysyttävää, niin vastaan mielelläni.