2020年11月

数日前から右側の二の腕や右足の脛のかゆみがひどく、軟膏でやっと抑えている。この日も念のために薬を病院へ持って行き、脛のかゆみが気になってならず、本来なら触ってはいけないことになっているはずの預けた自分の荷物から薬を取り出してリハ中に塗るありさまだった。右足脛ならまだいいが、右の二の腕が痒いと、不自由な左手で軟膏を塗るしかないのが辛い。かゆみが生じるのはほとんど右半身であるのも後遺症なのか。損傷しているのは右の脳である。

リハ後、カメラのキタムラとコメダへ。
草刈り業者から送ってもらった実家の写真を納める安いA4クリアファイルを買ってこようとしたが売ってなく、また来年の年賀状用のフォルダを買ってくる。
 DSCN3184DSCN3186

20年前に書いた本や教材に挿入したまだHDに残っている数式ファイルを見るたびに、今では数式を書くどころか、理解することにも苦労する為に、ふとか細い気分になる。「Mathtype」というソフトで作った画像ファイルだった。1990年頃、横浜の亘香通商(株)というショップまで買いに行った日のことは今でも覚えている。この会社はまだ残存しており、おぼろな記憶では山の中にあるような小さなショップだったが、調べると今では、随分立派なビルの中に入っている。

亘香通商(株)(せんこう)
神奈川県横浜市西区北幸2丁目9−30

どこでMathtypeのことを知ったのだろうか(今ではinDesignなどで数式などは簡単に作れるようでもあるが)。まだネットが普及するずっと以前のことだ。Windows3.0が世にでるのは1990年であり、数式を作っていたのはマック上(QuarkXpress)でである。現に今HDに残っている数式画像ファイルは、その全部が拡張子がpctのpictフォーマット。

岡崎の冨田病院もそうであるが、記憶の中に残っていて消えようとしている店や病院は、いずれも山の中にあある小さい建物や施設であることが多い気がする。

つい二三日前のことなのに、亘香通商株式会社のことをどうやって思い出したのかも思い出せない。2003年頃に作った手作りの手帖には会社名は載っていない。過去のカレンダー日記を読んでいて目に留めたのか、だとしたら購入日も分かって別のところにメモするはずなのに、その痕跡もない。

次は本来はFLASHやAnimateカテゴリーで括るべき内容の記事だが、波紋の異常態を描画する上で欠かせないアルゴリズムでもあるので「芸術ノート」に入れておく。ただし、昨日の記事の補足でもある。再度その手続きを書くと、画内の任意位置をマウスダウンする。その場所から画面中心位置までの距離を計測してlengに入れる。画面の左上から右下にかけて画素単位にドットを打ちながら、絶えずその現在位置と画面中心までの距離を計測し、その値をleng2の方に読み、

○leng2<lengの時=ドットを打つ色を(やや赤に近い)マゼンタ
○leng2>leng=ドットを打つ色を(やや赤に近い)黄色

という風に色を変えるてやるという手続きが昨日書いたプログラムであり、おそらく20年前の波紋描画プログラムもこのアルゴリズムに基づいて作られていたはずだった。これを次のよう変更する。完全に二つの色を分けてしまうのではなく、leng2>lengの時は赤の色を leng/leng2として徐々に変化するようにする。

col.r = 1.0; 
col.g = 0.0; 
col.b = 0.5;

if(leng2>leng){
col.r = leng/leng2;
col.b = 0.5;
}

F1121-1のように、円の境界がはっきりせずにボケることになる。

●円の境界をぼかして二色の領域を表示
var shape:Shape = new Shape();
this.addChild(shape);

var px,py, cx,cy, leng;
var stageW = stage.stageWidth;
var stageH = stage.stageHeight;
cx = stageW / 2;
cy = stageH / 2;

function getrgb(){
    return {r:0,g:0,b:0};
}

function getxyz(){
    return {x:0,y:0,z:0};
}

function paint()
{
var xx:int, yy:int;
var sx,sy;
var col = getrgb();
var cc = getrgb();
var leng2;

for(yy = 0; yy < stageH; yy++){
for(xx = 0; xx < stageW; xx++){
//偏在画素の位置(xx,yy)から画面中心(cx,vy)までの距離をleng2に。
sx = (xx - cx);
sy = (yy - cy);
leng2 = Math.sqrt(sx * sx + sy * sy);
col.r = 1.0; 
col.g = 0.0; 
col.b = 0.5;
// trace("leng2="+leng2);
if(leng2>leng){
col.r = leng/leng2;
col.b = 0.5;
}
cc.r = col.r * 255;
cc.g = col.g * 255;
cc.b = col.b * 255;
// trace("r= "+col.r+" : g= "+col.g+" : g= "+col.b);
var a = henkan(cc);
shape.graphics.beginFill(a);
shape.graphics.drawRect(xx, yy, 1, 1);
}
}
}

stage.addEventListener(MouseEvent.MOUSE_DOWN,function(){
px = stage.mouseX;
py = stage.mouseY;
var sx, sy, r;
//マウスダウンの位置(px,py)から画面中心(cx,vy)までの距離をlengに。
sx = px - cx;
sy = py - cy;
leng = Math.sqrt(sx * sx + sy * sy);
trace("leng1="+leng);
paint();
});

function henkan(c){
var a;
var rr:String;
var gg:String;
var bb:String;
var cc:String;
rr = c.r.toString(16);
gg = c.g.toString(16);
bb = c.b.toString(16);
if(rr.length == 1) rr = "0"+rr;
if(gg.length == 1) gg = "0"+gg;
if(bb.length == 1) bb = "0"+bb;
cc = "0x"+rr+gg+bb;
a = Number(cc);
return a;
}
F1121-1
ただ、ずっと考えていたのが、三角形を始めとした多角形の形状を持つ波紋(F1121-2)の生成である。多角形は正円の角数が減ったものであるに過ぎないのに、ざっと想像しただけでもこれを描くのはよほどアクロバティックな手法を使わない限り不可能である。また楕円の破門などがあり得るのだろうか。一度正円として生成した波紋を縦横のどちらかに延長すれば可能かもしれないが。
F1121-2

次も波紋描画のためには必須のアルゴリズム。画面内を左上から右下まで画素単位にドットを打ち、ペイントする。描画開始はマウスダウンをきっかけとする。その時ダウン位置と画面中心までの距離をlengに記憶し、ドットを打ち続ける画素と画面中心との距離leng2とを比較して、(leng2>leng)の場合とそうでない場合の色を変えてdrawRectメソッドを実行する。これは「画面中心からマウスダウンした位置までの距離」を半径とする円の描画である。

var shape:Shape = new Shape();
this.addChild(shape);

var px,py, cx,cy, leng;
var stageW = stage.stageWidth;
var stageH = stage.stageHeight;
cx = stageW / 2;
cy = stageH / 2;

function getrgb(){
    return {r:0,g:0,b:0};
}

function getxyz(){
    return {x:0,y:0,z:0};
}

function paint()
{
var xx:int, yy:int;
var sx,sy;
var col = getrgb();
var cc = getrgb();
var leng2;
for(yy = 0; yy < stageH; yy++){
for(xx = 0; xx < stageW; xx++){
//偏在画素の位置(xx,yy)から
//画面中心(cx,vy)までの距離をleng2に。
sx = (xx - cx);
sy = (yy - cy);
// trace("sx= "+sx+" : sy= "+sy);
leng2 = Math.sqrt(sx * sx + sy * sy);
//
col.r = 1.0; 
col.g = 0.0; 
col.b = 0.5;
// trace("leng2="+leng2);
if(leng2>leng){
col.g = 1.0; 
col.b = 0.5;
}
cc.r = col.r * 255;
cc.g = col.g * 255;
cc.b = col.b * 255;
// trace("r= "+col.r+" : g= "+col.g+" : g= "+col.b);
var a = henkan(cc);
shape.graphics.beginFill(a);
shape.graphics.drawRect(xx, yy, 1, 1);
}
}
}
stage.addEventListener(MouseEvent.MOUSE_DOWN,function(){
px = stage.mouseX;
py = stage.mouseY;
var sx, sy, r;
//マウスダウンの位置(px,py)から画面中心(cx,vy)までの距離をlengに。
sx = px - cx;
sy = py - cy;
leng = Math.sqrt(sx * sx + sy * sy);
trace("leng1="+leng);
paint();
});

function henkan(c){
var a;
var rr:String;
var gg:String;
var bb:String;
var cc:String;
rr = c.r.toString(16);
gg = c.g.toString(16);
bb = c.b.toString(16);
if(rr.length == 1) rr = "0"+rr;
if(gg.length == 1) gg = "0"+gg;
if(bb.length == 1) bb = "0"+bb;
cc = "0x"+rr+gg+bb;
a = Number(cc);
return a;
}
F1119-5

病気になってからのこと、多分今から7年前の2013年の時、学校で学生に見せたグラデーションの矩形を描くactionscript3.0によるプログラムを探していてようやく発見したのでそれを手直ししたものと合わせてここに載せる。これは近日中に書く予定の白黒のグレースケールによる波紋画像を描くプログラムの準備として追想するものである。当時のプログラムを尊重して、記述をできる限り簡素にしてある。RGBデータは0.1〜1.0の実数値を一度、0〜255の整数値に置き換え、さらにそれを16進数の文字列に変換し、もし文字数が1個しかない時は、例えば”3”ならもう一つ「0」を続けて”03”として二個の文字列にし、最後に”0x”を先頭に付けて、”0XFF0033”などとして、それをNumber関数の引数として実行して得た値を、beginFillメンバ関数の引数にして実行することでdrawRectで描くピクセルの色を決めるという面倒な手順で指定している。他に、もっと簡単な方法があるかもしれない。

①実数値のRGBデータを得る。
②RGBデータを0〜255の整数値に置き換える。
③RGBデータを16進数の文字列に変換する。
④もしRGBのどれかの値の文字数が1個しかない時は”03”などとする。
⑤”0x”を先頭に付けて、”0XFF0033”などとする。
⑥それをNumber関数の引数として実行して戻り値を得る。
⑦beginFillメンバ関数の引数にして実行し、描画色を決定。

次は7年前の255*255の画面をグラデーションで塗るスクリプト。当時は255*255でもさして小さいとは感じなかった。HDが当たり前になった現在までの時の流れの速さを痛切に感ずる。今から7年後にはどうなっているのか。4Kですら小さいと思う時が来るのか。

左から右への横の変化における青の色を(255-xx)として255から0まで減っていくようにし、赤を横変化の0→255とし緑を縦変化の0→255としている。

for(var yy = 0; yy < 255; yy++){
for(var xx = 0; xx < 255; xx++){
r = xx;(赤を横変化の0→255)
g = yy;(緑を縦変化の0→255)
b = 255-xx;(青は横変化の255→0)

実は、7年前には多分作成に10分もかからなかったはずのこのプログラムを理解するのにも、結構の時間を要しているのだ。加齢と言うよりは、一昨年の全身麻酔で一週間昏睡だったという発作が影響しているような気がしてならない。

●255*255の画面をグラデーションで塗りつぶすスクリプト。
var myShape:Shape = new Shape();
var a:int;
var r:int = 100;
var g:int = 150;
var b:int = 255;
var rr:String;
var gg:String;
var bb:String;
var c:String;

for(var yy = 0; yy < 255; yy++){
for(var xx = 0; xx < 255; xx++){
r = xx;
g = yy;
b = 255-xx;
rr = r.toString(16);
gg = g.toString(16);
bb = b.toString(16);
if(rr.length == 1) rr = "0"+rr;
if(gg.length == 1) gg = "0"+gg;
if(bb.length == 1) bb = "0"+bb;
c = "0x"+rr+gg+bb;

a = Number(c);
myShape.graphics.beginFill(a);
myShape.graphics.drawRect(xx, yy, 1, 1);
this.addChild(myShape);
}
}
s1

●次は600*600の画面をグラデーションで塗りつぶすスクリプト。
var myShape:Shape = new Shape();

var a:int;
var r:int = 100;
var g:int = 150;
var b:int = 255;
var rr:String;
var gg:String;
var bb:String;
var c:String;
var ratiox,ratioy;

for(var yy = 0; yy < 600; yy++){
for(var xx = 0; xx < 600; xx++){
ratiox = xx / 600;
ratioy = yy / 600;

r = ratiox*255;
g = ratioy*255;
b = (1-ratiox)*255;
rr = r.toString(16);
gg = g.toString(16);
bb = b.toString(16);
if(rr.length == 1) rr = "0"+rr;
if(gg.length == 1) gg = "0"+gg;
if(bb.length == 1) bb = "0"+bb;
c = "0x"+rr+gg+bb;

a = Number(c);
myShape.graphics.beginFill(a);
myShape.graphics.drawRect(xx, yy, 1, 1);
this.addChild(myShape);
}
}
s2 


先日引用した「楕円方程式を使った楕円円周上から出る法線を描くスクリプト」記事の後半に、「回転体S原形頂点上の法線ベクトル」を描くスクリプトが書かれていた。この部分を再掲する。内容は先日「芸術ノート」に加えてしまった曲線の前の座標と後の座標を結ぶ直線の法線ベクトル(曲線に接する接線の法線ベクトル)を得る方法と同じ方法を使っている。すなわちx成分とy成分を入れ替えてy成分にマイナス1を乗ずる方法である。5年前にどうやってこの方法を得たのか全く覚えてない。

//■回転体S原形頂点上の法線ベクトル。rathe_straight.fla

var shape:Shape = new Shape(); 
this.addChild(shape);
var g = shape.graphics;
var stageW = stage.stageWidth;
var stageH = stage.stageHeight;
var th:Number = 45;
var h:Number = 500;
var pi:Number = Math.PI/180;
var eyez:Number = 500;

var kaku = 12;
var sp =360 / kaku;

function getrgb(){
    return {r:0,g:0,b:0};
}

function getxyz(){
    return {x:0,y:0,z:0};
}

function getstart_end_step(){
    return {start:0,end:0,step:0};
}

var m_light = getrgb();
var nv = getxyz();
var xz = getstart_end_step();

var rad = getxyz();
rad.x = 150;
rad.y = 250;

xz.start = 0;
xz.end = 360;
xz.step = 30;

var p = new Array();
// 円弧頂点座標を記憶
for(var i = 0; i <= 360; i++){
p[i] = {x:0,y:0,z:0};
}

var x1, y1, x2, y2, x3, y3; 
var nleng = 1;

p[0].x = 250; p[0].y = 50; 
p[1].x = 365; p[1].y = 200;
p[2].x = 220; p[2].y = 300;
p[3].x = 220; p[3].y = 450;
p[4].x = 320; p[4].y = 520;

rathe_straight();
 
function rathe_straight(){

var po = 4;
var rxz, rxy, xzno, leng;
var nv = getxyz();
for(var i = 0; i < po ; i ++){
x1 = p[i].x;
y1 = p[i].y;
x2 = p[i+1].x;
y2 = p[i+1].y;
// trace("i= "+i+" : x= "+x1+" : y= "+y1);
g.lineStyle(2, 0x0002ff, 1);
g.moveTo(x1, y1);
g.lineTo(x2, y2);
}

trace("---");
for(i = 0; i < po ; i ++){
//xとyを入れ替える。yにマイナス1をかける。
nv.x = p[i+1].y - p[i].y;
nv.y = p[i+1].x - p[i].x;
nv.y *= -1;
nv = normal_vector(nv);

//(p[i]とp[i+1]の中央
x1 = (p[i].x + p[i+1].x) / 2;
y1 = (p[i].y + p[i+1].y) / 2
g.lineStyle(2, 0xff0000, 1);
g.beginFill (0xFFFFFF, 2);
g.drawCircle(x1, y1, 5);
x2 = x1 + nv.x *100;
y2 = y1 + nv.y *100;
g.moveTo(x1, y1);
g.lineTo(x2, y2);
trace("i= "+i+" : x= "+nv.x+" : y= "+nv.y);
}
rxz  = (xz.end - xz.start) / xz.step;
rxy = 0;

for(i = 0; i < po - 1; i++){
leng = Math.sqrt(Math.pow((p[i+1].x - p[i].x), 2) + 
Math.pow((p[i+1].y - p[i].y), 2));
rxy += leng;
}

p[po].x = p[po-1].x + (p[po-1].x - p[po-2].x);
p[po].y = p[po-1].y + (p[po-1].y - p[po-2].y);
p[po].z = 0;

xzno = 0;

}

function normal_vector(nv){
var leng;
leng = Math.sqrt(nv.x * nv.x + nv.y * nv.y + nv.z * nv.z);

nv.x /= leng;
nv.y /= leng;
nv.z /= leng;
return nv;
}
s1

————————————————————————

次は円の円周上から出る法線を描くスクリプト。

var shape:Shape = new Shape(); 
this.addChild(shape);
var g = shape.graphics;
var cx = stage.stageWidth/2;
var cy = stage.stageHeight/2;


var th:Number = 45;
var h:Number = 500;
var pi:Number = Math.PI/180;

var kaku = 8;
var sp =360 / kaku;
var po; 


function getxyz(){
    return {x:0,y:0,z:0};
}


var nv = getxyz();
var rad = getxyz();
rad.x = 200;
rad.y = 200;

var p = new Array();
// 円弧頂点座標を記憶
for(var i = 0; i <= 360; i++){
p[i] = {x:0,y:0,z:0};
}

var x1, y1, x2, y2, x3, y3; 

p[0].x = 250; p[0].y = 50; 
p[1].x = 365; p[1].y = 200;
p[2].x = 220; p[2].y = 300;
p[3].x = 220; p[3].y = 450;
p[4].x = 320; p[4].y = 520;

elldata1();


function elldata1(){
var x1, y1, x2, y2; 
var j=0;
for(var i = 0; i <= 360; i += sp){
x1 = rad.x * Math.cos(i * pi);
y1 = rad.y * Math.sin(i * pi);
j =i/sp;
p[j].x = x1;
p[j].y = y1;

}
po = j;
elldata2();
}

function elldata2(){
var x1, y1, x2, y2; 
var j=0;
for(var i = 0; i < po; i++){
x1 = p[i].x;
y1 = p[i].y;
x2 = p[i+1].x;
y2 = p[i+1].y;
trace("i= "+po+" : x= "+x1+" : y= "+y1);
g.lineStyle(2, 0x0002ff, 1);
g.moveTo(x1+cx, y1+cy);
g.lineTo(x2+cx, y2+cy);
j++;
}
for(i = 0; i < po ; i ++){
//xとyを入れ替える。yにマイナス1をかける。
nv.x = p[i+1].y - p[i].y;
nv.y = p[i+1].x - p[i].x;
nv.y *= -1;
nv = normal_vector(nv);
x1 = (p[i].x + p[i+1].x) / 2;
y1 = (p[i].y + p[i+1].y) / 2;
g.lineStyle(2, 0xff0000, 1);
g.beginFill (0xFFFFFF, 2);
g.drawCircle(x1+cx, y1+cy, 5);
x2 = x1 + nv.x *100;
y2 = y1 + nv.y *100;
g.moveTo(x1+cx, y1+cy);
g.lineTo(x2+cx, y2+cy);
}

}

function normal_vector(nv){
var leng;
leng = Math.sqrt(nv.x * nv.x + nv.y * nv.y + nv.z * nv.z);

nv.x /= leng;
nv.y /= leng;
nv.z /= leng;
return nv;
}
s2
 


ローソン買い物ついでに、横のGSで灯油を3缶頼む。去年の少し残っていた灯油をタンクに入れて芯に油が染み込むまで時間を空けたら点火できた。去年は短3電池を収納するケースの蓋がすぐに開いてしまったのが、今のところ大丈夫の様子である。ストーブのタンクはほぼ1日で使い切るので給油が面倒である。また20リットルは一週間でなくなるので、灯油代に月6千円を要す。

20年前に試した波紋は、上方から波紋を起こす要因となる石コロか何かを落とし入れ、同時にカメラの位置も水面に垂直になる角度で上方に置いている。光源の位置は任意だったはずだが、視線が水面に入射して屈折して衝突する底面も水面と平行となる形で置かれており、カメラが水面に対して斜めに入射することまでには想像が及ばなかった。あるいはその必要がなかった。

ではいつもの「黒部屋」(適用な名称が思い当たるまではしばらくこの名称を使用)の壁に対して、人が斜めの角度で正面の壁にボールをぶつけた場合、どのような形でグラデーション円や波紋は生じるのか。またどのように円の形は目に見えるのか。さらにボールをぶつける壁は正面だけではなく左右側面の壁の場合もあるだろう。

一つには、人が壁に対していかなる角度を持って向かい合っていたとしても、また斜めの軌道を描くボールを投げたとしても,真正面から見た時にだけ、ぶつかった場所を中心とする正円に見えるグラデーション円や波紋が生じるとする考えがある。この時に例えばF1120-1の位置に居た人aが図のようにボールを投げたとしても、正円としてそれを見るのは、扉を開いて正面の壁に向かい合う人bだけである。
F1120-1
aにとっては波紋は正円ではなく楕円として見える。多重円のラインを波紋に見立てて、aが見える形をF1120-2aに、bが見える形をF1120-2b描く。
F1120-2a
F1120-2b

ただの円柱や円錐などが歪んで見えるのは当たり前のことであるが、波紋がそのように見えるのは妙ではないか。これは石ころを池に放り投げて生じる波紋ではなく、部屋の入り口辺りから奥の壁に垂直に落ちる石によって生じた波紋だからである。

しばらく忘れていたので、メモ。

「<」は「&lt;」、「>」は「&gt;」としなければならない。

for (i<360)は、for (i &lt;)と書く必要がある。

ここに解説があるので引用。 

<pre><code>
this.stop();
var shape:Shape = new Shape(); 

this.addChild(shape);
var g = shape.graphics;
var cx = stage.stageWidth/2;
var cy = stage.stageHeight/2;

var th:Number = 45;
var h:Number = 500;
var pi:Number = Math.PI/180;
var eyez:Number = 500;


var kaku = 36;
var sp =360 / kaku;

function getrgb(){
    return {r:0,g:0,b:0};
}

function getxyz(){
    return {x:0,y:0,z:0};
}

var nv = getxyz();
var rad = getxyz();
rad.x = 150;
rad.y = 150;

var x1, y1, x2, y2; 

function elldata(){

for(var i = 0; i  &lt; 360*2; i += sp){
x1 = rad.x * Math.cos(i * pi);
y1 = rad.y * Math.sin(i * pi);
//次を実行すると円弧を右に拡張
//x1+=i;
//次を実行するとサインカーブを描く
x1=i;
// g.lineStyle(2, 0x0002ff, 1);
g.beginFill(0x0000FF);
g.drawCircle(x1+cy, y1+cy, 2);
}

}

elldata();
</code></pre>

20年近く前の波紋生成のアルゴリズムがどうも思い出せない。あの時は全くの我流で一定の間隔で広がる複数の波紋から発する法線ベクトルを取得していた。さらに水面は透明体になるので底面に格子状の重層色面を置き、カメラが水面に入って屈折する状況をリフレクションマッピングとして計測し、最後にぶつかる底面の色を得て、それを水面に見える色としていた。底面の矩形の色は乱数によって時間経過にしたがって変化するという手の込んだことも行っていた。

波紋が広がる10秒の動画であれば、300枚のイメージ画像を作成し、最後にそれをDirectorで繋げて動画にしていたはずであるが、よく分からないのは一枚の画像を生成する際に、リアルタイムに水面上の法線を取得していたのか、それとも一旦画面(当時標準のSDサイズ)における全画素の白黒画像を求め、それを元にして法線データを得ていたのかという点である。つまり、

①2次元のサインカーブを元にして、全画素におけるグレースケールのデータを求める。
②それを元にして全画素における法線データを求める。
③法線データに基づいて、スペキュラー光を求める。
④ディフューズ光はリフレクションマッピングで得る底面の色。

①で求めたグレースケールデータを配列に収納し、それを使って②で法線データを求めたのかという点が分からないのだ。少し前に20年前のソースコードは見つかった。ところが自分で作ったプログラムであるにもかかわらず、内容をほとんど理解できない。

芸術ノートのカテゴリに入れるかどうか悩ましいところだが、このノートは脳回復のリハビリとしても書いているのであえて掲載。次の図は、右に拡張する円弧と、ようやく思い出すことのできたサインカーブのプログラムである。ほとんど中学数学の内容である。三角関数で円を描く時に0から360*2までに変化する角度iを円弧の円周座標(x1,y1)に対して、x1+=i;とすると、右に円弧は拡張し、
F1119-1a

x1=i;
とするとサインカーブを描く。
F1119-1b
this.stop();
var shape:Shape = new Shape(); 

this.addChild(shape);
var g = shape.graphics;
var cx = stage.stageWidth/2;
var cy = stage.stageHeight/2;

var th:Number = 45;
var h:Number = 500;
var pi:Number = Math.PI/180;
var eyez:Number = 500;
var kaku = 36;
var sp =360 / kaku;

function getxyz(){
    return {x:0,y:0,z:0};
}

var nv = getxyz();
var rad = getxyz();
rad.x = 150;
rad.y = 150;

var x1, y1, x2, y2; 

function elldata(){

for(var i = 0; i <= 360*2; i += sp){
x1 = rad.x * Math.cos(i * pi);
y1 = rad.y * Math.sin(i * pi);
//次を実行すると円弧を右に拡張
//x1+=i;
//次を実行するとサインカーブを描く
x1=i;
// g.lineStyle(2, 0x0002ff, 1);
g.beginFill(0x0000FF);
g.drawCircle(x1+cy, y1+cy, 2);
}

}
elldata();

次に問題になるのが、サインカーブから出る法線ベクトルの求め方である。円の方程式から求める法線ベクトルではなく、法線を発する座標の前の座標と次の座標へ向かう法線データから、その線から垂直に出る法線を求めるという独自の方法を使う。

例えばF1119-2aの、4頂点①、②、③、④で構成される図形をサインカーブとした時、頂点と頂点の中間位置、あるいは頂点上から出る法線ベクトルは次のようになる。分かりにくいので、前の頂点から次の頂点に向かう法線データとその線分から垂直に出る法線のデータを両方記載いた図と別々にした図を分けて掲載する。次は両方載せた図(F1119-2a)。
F1119-2a

●前の頂点座標から次の頂点座標へ向かう法線成分データ(F1119-2b)
①(2, -2)
②(1, 3) 
③(2, -4)
④(2, 2) 
F1119-2b
●法線ベクトル成分データF1119-2c)
① (-2, -2)
② (3, -1)
③ (-4, -2)
④ (2, -2)
F1119-2c
円弧カーブの前座標から次座標へのベクトルに直交する現在座標から出るベクトルは次のように求められるはずである。

①x成分とy成分を入れ替える。
②y成分にマイナスをかける。

つまり、前の座標が(4, 2)で次の座標が(5, 5) だとしたら、前の座標から次の座標に向かう法線は、(1,3)となる。その前後の座標の中間位置から垂直に出る法線の成分は、(3, -1)のはずだ。(1,3)の1と3を入れ替えて、(3,1)とし、次にy成分の1にマイナスをかけて-1とする。したがって前の座標から次の座標に向かう法線が(a, b)ならその線から垂直に出る法線データは(b,-a)となる。

次は5年前に書いた楕円上の座標から発する法線ベクトルを描くプログラム。楕円方程式を用いている。

this.stop();
var shape:Shape = new Shape(); 

this.addChild(shape);
var g = shape.graphics;
var stageW = stage.stageWidth;
var stageH = stage.stageHeight;

var th:Number = 45;
var h:Number = 500;
var pi:Number = Math.PI/180;
var eyez:Number = 500;


var kaku = 12;
var sp =360 / kaku;

function getrgb(){
    return {r:0,g:0,b:0};
}

function getxyz(){
    return {x:0,y:0,z:0};
}

var m_light = getrgb();
var nv = getxyz();
var rad = getxyz();
rad.x = 150;
rad.y = 200;

var p = new Array();
// 円弧頂点座標を記憶
for(var i = 0; i <= 360; i++){
p[i] = {x:0,y:0};
}

var x1, y1, x2, y2, x3, y3; 
var nleng = 1;

//円の円周上座標データを配列pに記憶。
function elldata(){

for(var i = 0; i <= 360; i += sp){
x1 = rad.x * Math.cos(i * pi);
y1 = rad.y * Math.sin(i * pi);
p[i / sp].x = x1;
p[i / sp].y = y1;
}
}

//円と円周上座標から出る法線ベクトルを描画
function rathe_curve(){

for(var i = 0; i < kaku; i ++){
x1 = p[i].x;
y1 = p[i].y;
x2 = p[i+1].x;
y2 = p[i+1].y;
nv.x = x1 / (rad.x * rad.x);
nv.y = y1 / (rad.y * rad.y);
nv.z = 0;
nv = normal_vector(nv);
g.lineStyle(2, 0x0002ff, 1);
g.moveTo(x1+stageW/2, y1+stageH/2);
g.lineTo(x2+stageW/2, y2+stageH/2);
x3 = x1 + nv.x*100;
y3 = y1 + nv.y*100;
trace("x= "+nv.x+" : y= "+nv.y);
g.lineStyle(2, 0xff0000, 1);
g.moveTo(x1+stageW/2, y1+stageH/2);
g.lineTo(x3+stageW/2, y3+stageH/2);
}
}

//単位ベクトルを取得。
function normal_vector(nv){
var leng;
leng = Math.sqrt(nv.x * nv.x + nv.y * nv.y + nv.z * nv.z);

nv.x /= leng;
nv.y /= leng;
nv.z /= leng;
return nv;
}

elldata();
rathe_curve();
ss


研修だったのか、どこかの小学校に見学に来ていた。やや小太りの一人の小学生と仲良くなり、教室の外の廊下のソファに座ってアルバムを見ながらそのアルバムに載っている教員についての噂話しをする。美術の教員なのに、算数や国語など他の教科も担当しているという。教員は何らかの問題を起こして学校を解雇されたらしい。女性職員がやって来て、こんな所でサボっていてはいけないと少年を連れて行く。別の女性教員がやって来て、美術教員についての同じ話しを続ける。解雇された原因が何だったのかとか色々と。この当たりで夢は終わっている。もしくはその後に続いたストーリーは忘れている。

5年前に書いたasによるスクリプトが、Adiobe Animateで復活できる希望が出てきたので、、ここで思い出して復習する。ついでに波紋生成には必須のサインカーブを描く方法も20年ぶりに思い出す。ソースコードが消滅しているため、どこまでできるか分からないが、ここで行うのは20年前に書いた波紋プログラムの復活である。もちろんこれはボールがぶつかった箇所から広がる波紋の形状を作るのが目的である。ただ、asスクリプトは、まだ5年前に書いたばかりなのに、今やすっかり忘れてしまっていることに驚く。

次は、単に三角関数による円弧を描くだけのプログラム。円弧を線だけで描く場合と内部を塗り潰す場合の二つのケースを用意。内部を塗りつぶすされた任意の形状を持つ図形は、Shapeオブジェクトのメンバ関数graphicsを実行して得たオブジェクトのメンバ関数beginFillを実行してから、線で閉じた図形を描けば良い。
actionscriptによるグラフィックはややこしいので、手順を箇条書きにする。

①Shape オブジェクト取得
var shape:Shape = new Shape(); 
②Shapeオブジェクトを引数にaddChild実行
this.addChild(shape);
③Shapeオブジェクトの関数graphicsを実行してgraphicsオブジェクトを得る。
var g = shape.graphics;

このgraphicsオブジェクトgに対して各種グラフィックス関数を実行する。


ここでは、次の円の描画を二行程で行うものとする。
①配列に円弧の円周上座標データを記憶(elldata)。
②配列データを取り出して円弧を描画する(drawEll)。
プログラムの最後で二つのメソッドを続けて実行。

var shape:Shape = new Shape(); 
this.addChild(shape);
var g = shape.graphics;

//ステージの中心座標
var cx = stage.stageWidth / 2;
var cy = stage.stageHeight / 2;

var pi:Number = Math.PI/180;
var rad = 150;
var kaku = 6;

var sp = 360 / kaku;
var p = new Array();

//配列の初期化
for(var i = 0; i <= 360; i++){
p[i] = {x:0,y:0};

}

// 円弧頂点座標を記憶
function elldata(){

for(i = 0; i <= 360; i += sp){
var x1 = rad * Math.cos(i * pi);
var y1 = rad * Math.sin(i * pi);
p[i / sp].x = x1;
p[i / sp].y = y1;
}
}

//円弧を描画
function drawEll(q):void{

// g.beginFill(0xFF00FF);
g.lineStyle(2, 0x0002ff, 1);
for(i = 0; i <= kaku; i++){

if(i == 0)
g.moveTo(q[i].x + cx, q[i].y + cy);
else
g.lineTo(q[i].x + cx, q[i].y + cy);
}
}

elldata();
drawEll(p);

線で円弧を描く時は次を実行し、
g.lineStyle(2, 0x0002ff, 1);
 s1
内部を塗り潰す時は次を実行。
g.beginFill(0xFF00FF);
s2

ガス配管工事の影響か、携帯の充電器か携帯そのものが故障したらしく、充電器に携帯を置いても赤ランプが点かない。急いで駅前のドコモショップに問い合わせると、在庫があると言うので12時の予約を入れ、バスで店まで行く。結果、やはり充電器の故障だった。ポイントを引いて約2000円の充電器を買って帰宅。駅ではいつものハンバーガーとアイスコーヒーの昼食(胃腸を直撃するのでいつもすぐに後悔する)。

疑心暗鬼となっているので、実際に買った充電器で充電できるか心配だったが、今は赤ランプとともに携帯は充電中である。しかし、もしかすると5個以上のコンセントが付いているタックの故障とも考えられるので、別室のコンセントに繋げて充電している。

サインカーブを利用した波紋生成の必要性から過去の記事を調べるうちに、Flashのことに思いが及んだのでついでに付記。

どうも基本的なことの知識が決定的に欠けているか、理解できていないようである。2020年の10月にAdobe Flashのサポートが終了し、その歴史に幕を閉じることはネット情報で聞いていた。このことの意味もよく分かっていない。
SWF形式のインタラクティブなムービーを見るためのFlash PlayerがAdobe社から提供されなくなるということか。そうなると、まだFlash Playerをローカルにダウンロードしていない人は「偲ぶ会」HPのSWFを埋め込んでいるページは見られなくなることになる。

これまで作ってきたSWFのほとんどはタイムライン上で作成したムービーではなく、action script3.0によるスクリプトで動くインタラクティブなムービーである。FLASHが消滅するとなると、一応は5.5の古いヴァージョンをインストールしてはいるが、これを実行する環境もなくなることになってしまう。ネットに公開する予定はなくても、スクリプトの実行は古いFLASHで行うしかないのかと思っていた。

ところが、さっき試しに以前(と言っても5年前)作ったasスクリプトをAdobe Animateを起動してそのアクションパネルにコピペして実行(デバッグ)してみたら、そのまま実行できたのである。次はいつもの三角関数で円を描くプログラム。

var shape:Shape = new Shape(); 

this.addChild(shape);
var g = shape.graphics;
var stageW = stage.stageWidth;
var stageH = stage.stageHeight;

var th:Number = 45;
var h:Number = 500;
var pi:Number = Math.PI/180;
var eyez:Number = 500;

var kaku = 36;
var sp =360 / kaku;

function getrgb(){
    return {r:0,g:0,b:0};
}

function getxyz(){
    return {x:0,y:0,z:0};
}

var m_light = getrgb();
var nv = getxyz();
var rad = getxyz();
rad.x = 150;
rad.y = 150;

var x1, y1, x2, y2; 

function elldata(){

for(var i = 0; i <= 360; i += sp){
x1 = rad.x * Math.cos(i * pi);
y1 = rad.y * Math.sin(i * pi);
var i2 = i + sp;
x2 = rad.x * Math.cos(i2 * pi);
y2 = rad.y * Math.sin(i2 * pi);
g.lineStyle(2, 0x0002ff, 1);
g.moveTo(x1+stageW/2, y1+stageH/2);
g.lineTo(x2+stageW/2, y2+stageH/2);
}
}

elldata();
s0

早速、Adobe FlashとAnimateの違いがどこにあるのかを検索したがよく分からない。これはAdobeのサイトである。これまでのFlashに新機能を追加し、内部的に脆弱性解消他の改良がなされただけだったら、なぜ名称を変えて新しいソフトとして再出発する必要があったのか、機能強化して改良されたFlashの新バージョンで良いのではないのか。Animateをパブリッシュすると、Flashと同様、SWFファイルが生成される。このSWFとFlashによるSWFとでは何かが違うのか。

○Flashのパブリッシュで生成されるSWF
○Animateのパブリッシュで生成されるSWF

これの違いがないとしたら、FlashとAnimateの違いもないことになってしまう。
今、同じ上のスクリプトをFlashとAnimateでパブリッシュしてみた。すると、FlashのSWFの方がややファイルサイズが大きいことに気づいた。スクリプト内容は全く一緒である。FlashのSWFは1,703バイトで、AnimateのSWFは1,205バイトであるここまでファイルサイズが違うと、目には見えない内部が相当違っているのかもしれない。

s1
s2






三嶋リハ。本日は人数少なし。
アオキへ。天候は良く寒くも暑くもない気候なのに、風が強くて歩きにくい。

昨日はトイレの電気が突然切れたと思ったらすぐに点いた。またパソコンも電源をOFFにしたわけでもないのに落ちていた。と思ったら、隣室のテレビのNHK中継が入らないという怪現象が続けて起こる。 

ほとんど遊びの気分でアイデア次第で内容が決まってしまうことになるが、投げられたボールが衝突した壁の一箇所から放射状に壁表面の変質が起こるという事態を作品の骨子とするなら、次のようなヴァリエーションが思いつく。

●ボール表面の二次元テクスチャを壁表面の三次元的バンプ・マッピングへと変移する。
すぐに思い当たるのが水面上に広がる波紋である。これは重いボールを池などに放り込んだ時に生じる波紋を模すものにすぎず、地平に平行である水面が地平に対して垂直になるだけの現象であり、さして面白いとは言えない。またバンプマッピングに使用する白黒画像を今は用意することができない。昔は波紋生成のための白黒画像はVCによるプログラミングで作っていた。これについては今年の5月29日に「[20200520] 物理シミュレーションを手作業で行う意義」という記事があり、これはさらに「制作ノート」として書かれた以前のレポートからの引用を元に書かれたものである(その時読み返して見て、よく理解できなかったのを覚えている)。


波紋の生成は擬似生成であった方がいい。そうでなければ円形の波紋ばかりではなく、三角形を始めとした多角形の波紋や星型の波紋などの異常波紋を作ることはできない。

キーワード「波紋」で画像検索すると、次のような少し斜めから見た波紋の写真しか出てこない。
F11118-0a
多分「波紋」を写真に撮るのは相当難しいのだろう。その次は上の記事に添付したプログラミングで得た白黒画像を元にした生成した波紋の画像である。HD画像が一般化する以前の画像なので、サイズは640×480。その下はついでにミルククラウンの写真。これも真上から撮ることはできまい。
F11118-0b
F11118-0c
バンプマッピングのおさらいを兼ねて次の円形グラデーションをバンプ用画像としてキューブに適用したレンダリング図を掲載。思ったような結果にならない。F1118-1aが中心が黒、周縁が白のグラデーションの左画像をキューブ前面にマッピングした図であある。
F11118-2a
F1118-1bが中心が白、周縁が黒のグラデーションの左画像をキューブ前面にマッピングした図である。明度が低い所が凹みとなり高い所が相対的に高くなる。あまりバンプのノーマル値を上げると(1.0で最大)不自然になる。
F11118-2b
F1118-1cは大理石模様、F1118-1dはボケたアウトラインを持つブラシで描いた黒い線を元にバンプマッピングを行った図。
F11118-2c
F11118-2d
しかしここまで不自然な結果しか得られず、物理シミュレーションに頼るわけに行かないとしたら、10年前には当たり前のように行っていた自らのプログラミングによる波紋生成を本格的に復活させるしかないのではないかという気もしてくる。Windowsマシンは処分してしまったのでソースプログラムは手元にないが。

[20201116]に書いた①の映像表現についての補足。この映像にも色々なパターンがある。ボールを壁に投げてボールのストラップ模様を壁に定着させるシークエンスであれば、登場人物を客観的に捉えてその人物が壁に向かって投げるカットや、壁の一箇所から飛沫が放射状に拡散するカットを交互に切り替えたりしながら、黒部屋に入り込んだ人の困惑をショートムービー風に表現する映像があれば、最初から最後までその人の主観ショットで表す映像もある。否、主観ショットや客観ショットを交互に切り替えながら見せるのが普通のショートムービーだろう。

この場合、空中に放り投げられたボールだけを捉えたシーンも入ってくるだろうか。人物の顔だけをアップにしたカットはあってもいいだろうが、ファインダ内にボールのみが入ってくるカットなどがあり得るだろうか。しかも放り投げられて動いているボールである。

このように、ごくありふれたボールを拾って投げるというシーンの具体的な映像表現が中々想像できないのだ。第一、部屋にはどのような動作で入っていくのか。部屋の壁には扉があってそれを開いて入っていくのだろうか。遊園地などにはほとんど行った経験もないし、このような部屋だけのアトラクションというものも現実にあるものなのか。

アトラクションと言えば大抵は乗り物である。次はWikipediaの「アトラクション」の説明であるが、どうも定義が一定ではないのが分かる。随分カッコ「()」で囲む箇所があって読みにくい文章でもある。

【アトラクション】
アトラクション (attraction) とは、引き付けるもの、引き付けること。
催し物(イベント)、見せ物、呼び物。
アトラクション (遊園地) - 遊園地(テーマパーク)の遊具施設。娯楽乗り物 (en:Amusement ride)。観客が乗り物に乗ったり、移動して楽しむ物を指す。観客が移動せずにステージなどを観る物はショーと呼ばれる。

「見世物」という抽象概念でもあれば、「遊具施設」という具体的な物を指す用語でもある。ディズニーランドで言えば、「It's a Small World」は建物全体のことを指すのか中に入っている人形のことを指すのかずっと動いている乗り物(カナルボート型のライドとある)のことを指すのかが判然としない。

ともあれ、黒部屋で言うところのアトラクションは物理的には部屋である。しかも正立方体の形状を持つ部屋、あるいは建物である(部屋と建物の違いを言うのも難しい)。部屋の形式を持つアトラクションにどのようにして入っていくのかの想像は難しいが、まず壁には扉がありそれを自分で開いて入っていくところから想像する。

あまり複雑にしないでカットを単純明快にするなら、部屋の壁と部屋の中に入る人の背中を部屋外部のカメラが捉えたカットが最初にあり、次には部屋の中に置いたカメラが入ってきた人の前姿を捉えるカットが続く。そして部屋内部の様子を見る人の表情、部屋内観に軽く驚く表情が続くとする。その人が見る壁を見せる。そして床に転がっているボールを映す。次に床のボールを見る人の顔を映す…………など、基本的には主観ショットと客観ショットの交互切り替えになる。客観ショットの方も、登場人物全体のモーションを捉えたカットとその人の表情を捉えるカットとに大きく分類されるだろう。


●部屋に入る。
①部屋外のカメラが捉えた人の後ろ姿(F1117-1a)。
②部屋中のカメラが捉えた人の前姿(F1117-1b)。
③部屋内壁を見る人の表情(F1117-1c)。
④部屋の内壁(F1117-1d)。
⑤床のボール(F1117-1e)。
⑥ボールを見る表情(F1117-1f)。
●ボールを拾う
①ボールを拾う人のモーション(F1117-2a)。
②拾われるボール+指先(F1117-2b)。
●ボールを投げる
①ボールを投げる人のモーション(F1117-2c)。
②投げられたボールそのもの(F1117-2d)。
③前から捉えた投げられたボールとその背後の人(F1117-2e)。

●壁にボールがぶつかってグラデーションの輪が広がる。
①ボールが壁にぶつかる(F1117-3a)。
②衝突地点から輪が広がり始める(F1117-3b)。
③ボールがバウンドして床に転がる(F1117-3c)。
④壁の輪がさらに広がる(F1117-3d)。
⑤輪の境界(F1117-3e)
⑥壁全体(F1117-3f)
⑦輪の広がった壁+それを見る人の後ろ姿(F1117-3g)。

————————————————————————————————————
●部屋に入る。
①部屋外のカメラが捉えた人の後ろ姿。
②部屋中のカメラが捉えた人の前姿。
 F1117-1a
③部屋内壁を見る人の表情。
④部屋の内壁。
F1117-1c
⑤床のボール。
⑥ボールを見る表情。

F1117-1e

●ボールを拾う
①ボールを拾う人のモーション。
②拾われるボール+指先。
 F1117-2a
●ボールを投げる
①ボールを投げる人のモーション。
②投げられたボールそのもの。
③前から捉えた投げられたボールとその背後の人。
F1117-2c

●壁にボールがぶつかってグラデーションの輪が広がる。
①ボールが壁にぶつかる。
②衝突地点から輪が広がり始める。
F1117-3a

③ボールがバウンドして床に転がる。
④壁の輪がさらに広がる。
F1117-3c

⑤輪の境界
⑥壁全体
⑦輪の広がった壁+それを見る人の後ろ姿。
F1117-3e

以前も繰り返し書いているはずだが、このノートが結実する「作品」のスタイルは、大まかに分類すれば次の三種類しかない。

①映像作品
②スマートグラス+スマホ
③「不思議館」改め「黒部屋」

●モニター内の映像
①については特に言及するまでもない。文字通りテレビモニターかPCモニターに映し出される映像としての作品である。ただフィックスカメラが捉えた映像ではなく、絶えずカメラが動いており、光源も一箇所に止まってはおらず絶えず動いているのが特徴である。「映像」が現代美術のスタイルのひとつに取り入れられてから大分時が経過しているが、十数年前に見た映像作品は、プロジェクターによって美術館の壁に貼られた巨大なスクリーンに投影されていた。いかにも中途半端な感じしか受けず、普通の28インチモニター上の映像を、あえて巨大なスクリーンに拡大するパフォーマンスにアートの意義を見出そうとしていたようにも思われた。

●スマートグラス内のVR
②はソファにでもくつろぎながらスマートグラスを顔面にかけ、その中に展開される風景や状況を体験する作品である。そのため、美術館や画廊などのスペースは一切必要としない。スマホグラスの中の風景への参画はコントローラで行うものかと思っていたが、スマートグラスとは、Wi-Fiで繋がったスマホとともに作動するものらしいので、スマホが必要となる。簡単に言えばテレビのリモコンがそれに相当する。

テレビなど見なくなって10年近くなる。リモコンの赤ボタンや緑のボタンを押すことで視聴者が番組の情報を送ることができるようになったのはいつ頃からだろうか。番組のアナウンサーがテレビを見ている視聴者に向けてリモコンのボタンを押すことでアンケートを募っているのを聴くことがあった。テレビの向こう側にはスタジオがあり、こちら側には番組を見る視聴者がいる。二つの世界はリモコンで繋がっており、何らかの情報をボタンの押し下げでリモコンを介してこちらから向こうに発信ができるのである。

ごく常識的発想だろうが、この関係は「スマートグラス+スマホ」を介して向こうの世界と繋がるこちらの世界との関係と同じではないのか。つまりスマートグラスがテレビであり、スマホがテレビリモコンである(F1116-1)。

スマートグラス=テレビ
スマホ=テレビリモコン
F1116-1
テレビなどの旧遺跡は消滅し、それに替わってスマートグラスが普及し、テレビリモコンの替わりをスマホが行う時代がいずれ来るだろう。

なお、これも以前書いているはずだが、スマートグラスに登場する世界は基本的には三次元の世界であり、スマホを操作することで行うのはその現実と見紛う世界内を歩行したり飛翔したりする肉体の動作であり関与である。


●黒部屋
③「黒部屋」には幾つかのパターンがある。一つは生身の肉体がそのまま部屋に入って床に転がっているボールを壁にぶつけたりする動作を行う関与であり、もう一つはスマホを持たないで、スマートグラスだけをかけて部屋に入っていくパターンである。一つめは人のモーションは壁の隅に仕込まれたカメラと繋がるコンピュータでキャプチャはするものの、生成するのは壁モニター上のCG映像になる。

○黒部屋+肉体
これにも幾通りかのパターンがあるかもしれない。ボールのテクスチャが壁に反映する場合のものと、壁を鏡面に模す場合のものだ。

◇ボールのテクスチャなどを壁に反映させる(F1116-2a)。
◇壁を鏡面に模す(F1116-2b)。
F1116-2
テクスチャの反映はすでに何通りかのアイデアを書いている。それに対して、後者は壁全体をCGによって鏡とするものだ。もし、壁にぶつかったボールが衝突場所から出る法線に対して同じ角度分だけ反対側に対称移動して跳ね返ってくる様をシミュレートするとしても、跳ね返る架空のボールはヴァーチャルとしてフォログラフィ的に空間内に作る3次元のボールではなく、そのボールが存在するとした時に想定される壁の鏡に映る映像をCG表現するというものだ。

床に転がっている現実のボールがある。それを拾って壁にぶつける。ボールは跳ね返って床にバウンドしてまたこちらに転がってくる。ところがこの正常な様子が壁の鏡に映っているところまでをも、モニター上に移すCG映像で表現する必要があるのである。つまり正常にバウンドして跳ね返ってくるボールと異常なモーションを呈すボールの両方を、鏡に映るものとしてCG表現するということである。

これは②と変わらないようにも見えるが、スマホ操作の代わりに歩行やボール投球などの肉体の大きな動作を行うために、自宅のソファで座って行うバーチャル世界への関与とは違っている。


○黒部屋+スマートグラス+肉体
すべてをスマートグラス内VRで生成してしまうと、物理的な大きさを持つ部屋に入っていく意味がない。しかし、現実の部屋でバウンドする現実のボールと異常なモーションを持つVRを合成表示すれば意味はあるだろう。スマートグラスを通して見える現実の正常ボール(F1116-3a)とスマートグラス内で生成されるVRとしての異常ボール(F1116-3b)との合成である。
F1116-3

どちらかを透過処理で半透明にしてもいいかもしれない。

blenderに限らず、すべてのCGツールのパラメータに指定するデータはキーフレームになり得るだろう。次はblender初学と言ってもいいスクリューモデファイアにおけるパラメータに指定するキーフレームで生成するアニメション例。「角度」パラメータに指定するデータを0秒目に0、1秒目に360とする1秒間のアニメーションを次に掲載する。

○「角度」0
F1115-1a
F1115-2a
○「角度」175
F1115-1b
F1115-2b
○「角度」360
F1115-1c
F1115-2c

ボールがバウンドする正常なシミュレーションではなく、そこに少しでも異常なシミュレーションを付加するとしたらどのようなものが考えられるか。[20201110]に描いた図はもちろん正しい物理的現象をシミュレートしてはおらず、ボールは楕円アウトラインの半分の軌跡を辿ってバウンドしたりはしない。半径(500, 1000)や(400, 900)の楕円はちょうど100ずつ減っていくという区切りのいい数値で描いてみた楕円に過ぎないのだ。

ただあえてこのデータを持つ楕円右半分のアウトラインを軌跡とするボールのバウンドを正しいシミュレートと見做すなら、異常なバウンドの例を思いつく限り列挙する。

①途中の楕円軌跡から進路を90度変更(F1114-1)
正面から見て右に向かって転がっていったボールが同じバウンドデータを携えて途中から進路を変えて前方に転がってくる。
F1114-1
②途中から正円の軌跡を描く。(F1114-2)
バウンドする楕円の横半径の大きさは徐々に減っていくはずであるが、途中から正円の半径になってそれが連続する。あるいは最初から不自然な正円の軌跡を辿るバウンドを行う。
F1114-2
③半径サイズが小さい円弧から大きい円弧になっていくバウンド(F1114-3)
これはボールがバウンドする状態を逆回しに再生することと同じである。映像の逆回しは誰でも思いつく映像エフェクトであり、映像編集ツールでも簡単に実現できるが、映画はもちろんのこと、PVやCMでも実際には目にすることはほとんどない。
F1114-3

昔スパイク・ジョーンズが某ミュージシャン(名を失念)のPVを最初から最後まで逆再生で作っていた。次はそのワンカット。
(F1114-0
初見では逆再生だということには気づかないが何度か見るとそれに気づく。ただこれは完全な逆回しであり、正常映像の中に逆再生映像を挿入して編集した映像ではない。ここで想像するのは、床に落としたボールが最初は直線を軌道にして転がってゆく所から徐々に小さなバウンドを始め、そのバウンドも大きくなっていくという異常性である。

④螺旋的に上下左右に旋回移動するボール(F1114-4)
上は不自然であってもすべて床にバウンドするボールのシミュレートであり、一定の間隔を空けてボールが床に接するのは条件となっている。しかし、円弧の軌道が常に空中に浮いていて床には接する機会がないとしたらボールはどのような状態を呈すか。螺旋状に渦巻きながら上下移動するボールがあり得るだろうか。
F1114-4

⑤楕円の軌跡が楕球となる。(F1114-5)
楕円の軌跡を描いた線の形状は立体的な楕球のフォルムを喚起した。バウンドする実際のボールが透過処理で消失すると同時に、楕球が二次元の線から立体化する。
F1114-5

三嶋リハビリ。珍しく買い物せず。

実家の堤防から玄関までの草刈りと防草シート敷きの見積書届く。約10万。早速電話して依頼する。残った分は100万からその10万を引いた金額でいいと聞く。こちらは来年になる。叔父に電話したところ、来年1月の5日に松阪フレックスに泊まるそうなので、その時に合流する予定。

先の三つのオブジェクトの間を縫うカメラモーションを訂正する(F1113-1)。

①球の円弧右半分は球の中心を向く。
②-a球の円弧左上1/4半分は球の中心を向く。
②-b円錐の円弧右下1/4半分は、球中心から円錐中心に変移する。
③-a円錐の円弧左下1/4半分は、円錐中心から円柱中心に変移する。
③-b円柱の円弧右上1/4半分は、円錐中心から円柱中心に変移する。
④の円柱左半分は円柱の中心を向く。
F1113-1
ごくテクニカルなテーマでもっと簡単な方法があるはずだが、次のようにカメラの旋回基点とターゲットの変移を決める。まず、上記シナリオの①で1秒(30フレーム)、②で1秒、③で1秒、④で1秒の計4秒の120フレームを要してカメラが旋回するとする。なお以前確認しているように、カメラの旋回基点とターゲットは共有できる。

やや半端な値となるが、図のカメラ旋回軌跡の円弧は1/4で15フレーム、1回転で45フレームを要する。45秒は1秒と15フレームである。分かりにくいので、カメラ旋回の図とターゲット変移の図を別々に掲載。

●カメラ旋回の基点の変移(F1113-2)
○[00frame]〜[045frame]
円弧右半分と円弧左上1/4半分までは、球の中心を基点にカメラが回転する。
○[045frame]〜[090frame]
1フレーム先から2秒目まで、円錐の中心を基点にカメラが回転する。
○[090frame]〜[135frame]
1フレーム先から3秒目まで、円錐の中心を基点にカメラが回転する。
F1113-2

●カメラターゲットの変移(F1113-3)
○[00frame]〜[030frame]
円弧右半分までは、球の中心をターゲット。
○[030frame]〜[060frame]
ターゲットは球から円錐中心に変移。
○[060frame]〜[090frame]
ターゲットは円錐から円柱中心に変移。
○[090frame]〜[120frame]
ターゲットは円柱中心。
F1113-3
 

予約時間の9時半前に年金事務所へ。だが結局この日はほとんど無駄骨に終わり、来年の書類提出日に回しても良かった。代筆してもらおうと思っていた記入項目がほとんどない上に、記入が必要な所は提出日に代筆してもらっても良かったからである。唯一、来年の提出日(予約してくる。1月12日の10時)を忘れないよう注意が行き渡るだけの効用はあっただろうが。今日行っておかないと、高次脳機能障害によって来年の締め切りをうっかり逃してしまう怖れは大きい。

事務所までは徒歩で。中天馬の交差点まで30分、市役所まで40分、年金事務所までは50分ほどもかかったようで、いつもより10分遅い。東岡崎駅まで歩き、プラージュで三ヶ月ぶりの散髪(前回は8月24日)。

年金事務所の様子と1号線。撮影対象となりそうな一劃は車の流れに遮られて通ることができず。
DSCN3175
DSCN3183
 

[20200717]に三種類の光源オブジェクトのタイプを互換するテストを行っている。しかしこの記事が今年の7月、まだ4か月前であることがどうしても信じられない。記事を検索する前までは、二年ほど前としか思っていなかったのだ。ということは、これから書こうとするテストも、もしかすると少し前に中途半端なレポートとして書いていることをすっかり忘れてしまっている可能性が大である。しかしいずれにせよ中途半端なところで思考中断して放り投げているのは間違いないし、再考を怖れても仕方がない。

再度掲載する光源タイプにもう一つ追加して次に書く。

①透明体+点光源
②放射体(発光体)
③スペキュラーが大きい通常オブジェクト
④スポットライトに照射された球

これらはいずれも通常時の正常なオブジェクト(球)ではない。点光源は実体を持たず、透明体もそれ自体は実体を思わせるマテリアルではない。二つが一体となることで光源自体が実体をまとい始める時間を示唆しながら、通常のマテリアルが消失しようとするのが①である。②は通常のマテリアルを持ちながらそれが光を放つ光源でもあるという特殊なオブジェクトである。③はオブジェクトの表面全体の大きさまでにスペキュラー光が広がると、それは光源にも見えてくる。

④が新しく追加するマテリアルである。このテストは以前も行っている。球の円形形状の輪郭線とスポットライトの輪の輪郭線の境界を曖昧にすることで、どちらがオブジェクトでどちらが光源なのかを分らなくさせるテストである。

まず単純に三つの球を横に並べ、正面に置いたカメラから見たレンダリング図をF1112-1に描く。
F1112-1
四(三)種類の光源間のメタモルフォーゼの前に、もっと簡単な三つのオブジェクト間を縫って走行するカメラのモーションを決める。これは後にテストする予定の上下への移動を行うカメラモーションはまだ省いている。オブジェクトは右からいつものプリミティブ、球(a)、円錐(b)、円柱(c)の三つである。右端の球の一回り大きい円弧の軌跡をカメラは辿る。ただし右半分は球の中心をターゲットにして旋回するが、左半分の円弧は真ん中の円錐の中心をターゲットにして旋回するカメラの動きへ徐々に変移するものとする。そうすると最後は円錐中心をターゲットとするカメラアングルで終わる。同じように、円錐の左半分は円柱中心をいターゲットとするカメラの動きに変移する。最後の円柱左半分の円弧は円柱中心だけを見るカメラアングルで終了するとしたらどうだろうか。
以下、「球より一回り大きい円弧」は「球の円弧」と略して表記。

①球の円弧右半分は球の中心を向く(F1112-2)。
②球の円弧左半分は球の中心を向くアングルから、円錐の円弧右半分が円錐中心を向くアングルに変移(F1112-3a)。
③円錐の円弧左半分は円錐の中心を向くアングルから、円柱の円弧右半分が円柱中心を向くアングルに変移(F1112-3b)。
④円柱の円弧左右半分は円柱の中心を向く(F1112-4)。

しかし、これだと、結局オブジェクトの変移はカットトランジションで一挙に変移させるか、ディゾルブで徐々に変移させるかでしかない。このような面倒な図解を待つまでもなく、上面から見れば逆時計回りに回って三つのオブジェクトを見るカットを三つ連続させてカットトランジションかディゾルブで見るスピンショットカメラワークとそのモーションでしかない。否、②と③でカメラが徐々に推移していくとしているのはディゾルブを想定しているということだろう。何ら変哲もないモーションでしかない。②と③の間で、回転方向を逆にすれば多少異常性は生じるだろうか。それとも三つのオブジェクトはすべて同一のオブジェクトであるべきだったろうか。

①球の円弧右半分は球の中心を向く。
 F1112-2
②球の円弧左半分は球の中心を向くアングルから、円錐の円弧右半分が円錐中心を向くアングルに変移。
 F1112-3a
③円錐の円弧左半分は円錐の中心を向くアングルから、円柱の円弧右半分が円柱中心を向くアングルに変移。
 F1112-3b
④円柱の円弧左右半分は円柱の中心を向く。
F1112-4
 

↑このページのトップヘ