(ほぼprocessing初心者でも読み通せる水準の記事です! 今回processingでスケッチを作り、一応完成はしたもののコードにその場しのぎな書き方をした箇所が残ってしまいました。まずは今後の改善と反省のために一旦公表します、という主旨の記事です)
概要
processingは環境構築も楽で、立ち上げ→コード作成→実行結果としての画像の表示までのステップを手早く済ませられるので「アート製作にプログラミングを採りいれたい」と思った実作者の方が手を出しやすい言語です。
ただし、なまじ手早く始められるだけにつまづきの石に行き当たるのものも早くなりがちで・・・・私自身がまさにそんなルートを通ってきました。
今回はその一例として私が現代詩の世界の一分野である「コンクリートポエトリ」をprocessingで作ろうとして、つまづいたという一幕について。
出発点
当初の構想としてまず「正方形が規則的にたくさん並んでいて、その中に匣(はこ)という字が書いてある」という作品を作ろうと目論んでいました(コードが単純な割にはなんとなく様になりそうだし)。そこで、出発点として
①まず正方形とその中心に任意の文字を入れて描画するというコードを組んでみることに。そして②それを色んなサイズでも実現できるようにすればおおよそ完成、というわけです。
テキストのベースライン問題
ではまず①の工程をコードに。文字を指定した座標の中心に持ってくる方法としてtext-alignとtextAscent があります。詳しくは以下の記事が参考になります。(https://qiita.com/akspect/items/14962dbe0b7d45627b4e)
PFont f;
void setup(){
f=loadFont("YuMincho-Light-48.vlw");
size(300,300);
background(0);
}
void draw() {
float x=width/2;
float y=height/2;
float size=48;
//外枠の正方形を描画
fill(255);
rectMode(CENTER);
rect(x,y,size,size);
//内側の文字を表示
fill(0);
textFont(f,size);
textAlign(CENTER,CENTER);
/*ベースラインのX軸の値を上から数えた数値と下から数えた値を足し合わせる。 要はsizeの半分。*/
float ascent = textAscent();
float descent = textDescent();
float textHeight = ascent + descent;
int textPosY = int(y+textHeight)/2;
text("a",x,textPosY);
}
が、しかし。。実行してみると中心からやや上にずれてしまいました。あれま。
改めて上述の記事を読みこむとフォントごとに上の幅と下の幅には差があるようで、、
printlnでためしにprintln(ascent); println(descent);と調べてみるに、どうやらフォントサイズ48の游明朝 lightでは上から38.0(つまり下から10.0)の位置にベースラインがあるとわかりました。このベースラインから上に沿って文字が並ぶと。
妥協案
ここで綺麗なコードで解決!という展開をお見せできれば最高なんですが、、
コードの完成度を差し置いてまずは完成品を見ておきたい私はここへきて「マジックナンバー」でお茶を濁すという暴挙に打って出ました・・・!
//問題のコードがこちら。
int textPosY = int(y-textHeight/6);
そう、なんか良い感じの見た目に収まるまで変数をいじるという悪魔じみた所業に訴えたという次第!!なんとも拍子抜けが過ぎる打開策。ただ実際、以下のランダムな生成のためのコードを足して実行したところ見た目は完成品として及第点に。
void draw() {
x=random(50,250);
y=random(50,250);
float d=dist(x, y, width/2, height/2);
float size=d/4;
rectMode(CENTER);
fill(255);
rect(x,y,size,size);
fill(0);
textFont(f,size);
textAlign(CENTER,CENTER);
float ascent = textAscent();
float descent = textDescent();
float textHeight = ascent + descent;
int textPosY = int(y-textHeight/6);
text("a",x,textPosY);
}
そしてこのアドホックな解決策は当然汎用性も低いので「匣」という別の字に切り替えると、またその都度調整が必要になるという。。(ほぼ仕組みもわからぬままブラックボックスをいじっているだけの猿と変わらないぜ!)。
いびつなコードを書いた対価はのちのち自分の手間として帰ってくる!それが最速で証明された形ですね。皆さんもお気をつけて!
なにはともあれ出来た!
int textPosY = int(y-textHeight/60);
text("匣",x,textPosY);
その後試行錯誤して色々調整してはみたのですが・・・フォントや文字の種類ごとにちまちま設定し直すしかないのか??という至極当然の疑問は残ります。また設定し直すにしても、文字の位置を変化させる際に用いる比率などの仕組みについてもう少し一般化できるはずだろうという反省点は残りました。
かつてCSSでテキストの並びを目視で調整しながらページをデザインしていた時も感じましたが、こういうフォントのデザインに関していちいち状況ごとに対応するのでなく、もっと短縮できるようちゃんとコードを考えなければならない。そう痛感しました。今後の課題となりそうです(聖エクスペダイトに祈るしかないか)。。
ともあれここまで読んでいただきありがとうございました!
GOODNIGHT WORLD!