ART絵のための言語

Art を読む

以下の例はすべて実際に動きます。押せばその場で描かれ、 「試す」に持って行けば、書き換えながら試せます。

手引き — 二十五歩

はじめから順に、一歩ずつ。どれもそのまま走る短い作品です。 押すと「試す」へ持って行きます — そこで書き換えながら読んでください。

読み込んでいます…

言語の形

Art は「何が在るか」を書きます。計算機が何をするかは書きません。 draw() も、フレームの数え上げも、状態の更新もありません。

文はどれも、「絵に何かを足す」か「その先の文脈を変える」かのどちらかです。 改行に意味はありません — 一行に詰めても同じ絵が出ます。

形を置く

画布の座標は短いほうの辺が 100です。原点は中心、y は上向き。 だから circle radius: 22 は「短辺の 22%」を意味します。 画布の大きさを変えても、絵の構図は保たれます。

引数
circleradius:
ellipsewidth: height:
rectwidth: height: round:
square大きさをひとつ、名前なしで
linefrom: to:
pathブロックの中に to line curve
textsize: weight: tracking:

置く場所は、引数ではなく囲みで指定します。 at [x y] { circle radius: 6 } と書きます。これは frame { move x: x y: y circle radius: 6 } の短い形です。 circle radius: 6 at [x y] と書くと at次の文になり、 丸は原点に残ります。そのときは、言語がそう知らせます。

入れ子と変形

frame { } は座標系をひとつ作ります。中で move rotate scale をすると、その中だけが動きます。外へは漏れません。

属性はカスケードします。 fill は「その先の文」に効きます。 frame の中で塗り替えても、外の色は変わりません。

繰り返し

repeat n as i { }。中の変形は累積します — 毎回リセットされません。 これが「らせん」や「輪」を一行で書ける理由です。

単位

裸の数がピクセルを意味することはありません。 角度には deg turn rad、 時間には s ms beat bar、 長さには mm in pt px。 単位を書き忘れると、指摘されます。黙って解釈することはありません。

単位は括弧の直後に、空白なしで置きます — (i / 7)turn

% — その場所にとっての全体

裸の数は短いほうの辺の何%です。circle radius: 22 の 22 は 「短辺の 22%」でした。明示的に % と書くこともできます — そして % は、 その場所にとっての自然な全体を指します。

書く場所50% の意味
位置 move x: at line to:そのの広がりの半分
軸のある寸法 width: height:そのの広がりの半分
軸の無い寸法 radius: size: stroke width:短辺の半分
時間 over 50% delay 50%いまの duration の半分
濃さ /50%scalespeed0.5

だから at [50% 50%] { … } は、どんな画布でも右上の角です。 正方形の画布では、裸の数と % は同じ値になります。 違いが出るのは、縦横の違う画布や bounds の中だけです。

mm in pt px実寸です。 印刷やプロッタに出すときは、こちらを書きます — stroke #333 width: 0.22mm は、どんな大きさで出しても 0.22mm です。

#rrggbb のほか、OKLCh が第一の色空間です。 oklch(l: 明るさ, c: 鮮やかさ, h: 色相)/50% を後ろに付ければ薄くなります。

palette p = [ … ] で並びにして、p[0] で引けます。 範囲の外を引いたら塗りません。そして、そう知らせます。

時間は寸法と同じ場所に書く

これが Art のいちばん大きな違いです。 数を書ける場所には、区間 3..9 も、時間に開いた区間 3..9 over 2s も書けます。 フレームを数える必要はありません。だからどの時刻へも飛べます

書き方意味
a..b over 2s2 秒かけて a から b へ
pingpong行って戻る
loop繰り返す
ease inout緩急を付ける
delay 0.5sその先の時をずらす
tempo 2xその先の時を速める

場 — 点ごとに色を決める

field { } の中では、xyその点の場所です。 返した色がそこに置かれます。塗りつぶしの色でも、端から端への流れでもなく、 式が場所ごとに答える。囲んだ図形の形に切り取られます。

step:桝の粗さです。小さくすると細かくなり、そのぶん計算は重くなります (一枚あたりの計算量は「揺らぎを引く回数 × 桝の数」で決まります)。 拡げるときは十六点で混ぜるので、0.7 前後までは角が出ません。

t も読めます。読めば毎フレーム塗り直し、読まなければ一度作って使い回します。 最初のページの絵は、これだけでできています — 図形は地と矩形の二つだけです。

にじみ・粒・型抜き

blur は以降の兄弟要素をぼかします(blur 0 で戻します)。 grain は画面ぜんぶに粒を置きます — 種から決まるので、同じ作品なら同じ粒です。

mask { 型 } { 中身 } は、型の形で中身を切り抜きます。

にじみ・粒・型抜きは画素の上で起きます。SVG で書き出すと、 そのぶんは出せません — 言語はそれを黙らずに知らせます(§18.3)。

偶然は再現する

random 1..5 の値は「種 × 構造的同一性」から決まります。 呼ばれた順ではありません。だから兄弟を増やしても、自分の乱数は動きません。 時刻を戻せば同じ絵が出ます。

つまみ — 作品は絵の族である

param は言語の一部です。範囲と見出しを添えると、 道具がつまみを出します。一つの原文が、絵の族になります。

回しても絵が変わらないつまみは警告されます。 黙って無視することはありません。

自分の語彙

define 名前(引数: 既定) { }。既定値は必須です。書き忘れると指摘されます。 本体は呼ばれた場所の変形と色を継ぎますが、 let で結んだ名前はファイルの最上位と自分の引数だけを見ます。

isolated を付けると、呼ばれた場所の変形と色を継ぎません。

測ることは言語の一部

as 名前 で、置いたものの測られた広がりを受け取れます。 自分で座標を計算する必要がありません。

外の物を読む

data("../data/sales.csv") は表を読みます。行の並びが返るので、 repeat でそのまま回せます。 picture("../data/test.png") は絵を読みます。 .width .height のほか、.at([x y])その画素の色を訊けます(座標は画素で数えます。外を訊いたら端の色が返ります)。

let 写 = picture("../data/test.png")
repeat 16 as i { frame {
  move x: (-38 + i * 5)
  fill 写.at([i, 8])
  rect width: 4 height: 40 } }

パスは作品ファイルからの相対です。読めなければ、そう知らせて先へ進みます(P7)— 黙って白い絵にはしませんpicture読む絵で、図形にはなりません。置きたいときは image です。

入力 — 触れる作品

mouse key audio camera midi繋がっていなければ 0 を返します — 落ちませんし、 何も繋がっていない場所でも「静かな既定の絵」が出ます。

入力読めるもの
mouse.x .y .down .speed — 画布の単位で
key.any .space .arrow.x .arrow.y ほか
audio.level .bass .mid .high .beat
camera.motion.frame — 絵としてそのまま置けます
midi.cc[n] .held[n] .note .velocity

sound { }時間の関数です。絵と同じ t を使います。 純粋な関数なので、飛べる・巻き戻せる・書き出せる

「試す」へ持って行くと、実際に鳴らせます♪ 音 を押してください。 WAV で持ち帰ることもできます。コマンドラインからは、 export wav seconds: 2 と書いて node proto/export.js を実行します。

奥行き

space { } の中では move z:rotate x: y: z: が効きます。 核が持つのはそれと facing、つまりその面がどれだけ手前を向いているかだけで、 陰影も箱も球も、Art 自身で書かれていますstd/solid.art です。

import "../std/solid.art"
space {
  rotate x: 0.12turn
  rotate y: (0.05 + sin((t / 8)turn) * 0.04)turn
  box(size: 18, base: #6688cc, light: 0.6) }

書き出す

一つの原文から十七の形へ。すべて自前で書いています — 外部ライブラリはありません。

種類形式
ベクタsvg pdf dxf plot ペンプロッタ
画素png jpg tga tiff
動きgif mp4 frames
wav
json csv tsv txt
ページweb — 処理系ごと入った一枚の HTML

書き出したものは自分の作り方を持ち歩きます — 原文・種・つまみの上書き、 そして署名が中に入ります。原文は消せますが、姿は消せません

文字だけは、形式によって幅が変わります。 Art は書体を同梱しません(§15)— 文字の輪郭は表示する機械の書体から借ります。 だから svg は見る人の書体で組まれ、png は書き出した機械の書体で組まれます。 同じ原文でも、文字の幅と位置は少しずれます(測ると、文字のある帯で画素の一割ほど)。 形をそろえたいときは png で書き出すか、文字を path で描いてください。

署名

Art は同じ入力から必ず同じ絵を出します。だから逆に辿れます。 作品の刻みは三段です。

刻み落とすもの捕まえるもの
何も落とさない同じファイル
空白・註釈・宣言の順書き直しただけの複製
姿数・色・見出し・あなたの名前つまみを回した複製

絵の側は、8×8 の区画ごとにを刻みます。回転と鏡像は八通り試し、 向きまで言い当てますその場で確かめられます →