-リアクティブな形状 -  

今回は前回の点群の動きと以前やったひものような動きの仕組みを踏まえて,マウスに反応する形状を作ってみましょう.
それぞれの点を線で滑らかに結ぶことによりある形状がマウスに反応するように見えます.

動きはこのようになります.

そしてソースコードはこうなります.

 


point p[];

[setup, 400, 400]{
p = new point[32];

for(int i = 0; i < p.length; ++i){
double x = 200 + 80*Math.cos(i*Math.PI*2/p.length);
double y = 200 + 80*Math.sin(i*Math.PI*2/p.length);
p[i] = new point(x, y);
}
}

[paint]{
clearAll();
for(int i = 0; i < p.length; ++i){
point pA, pB, pC;

if(i == 0) pA = p[p.length-1];
else pA = p[i-1];
pB = p[i];
if(i == p.length-1) pC = p[0];
else pC = p[i+1];

drawBezierCurve((pA.x+pB.x)/2, (pA.y+pB.y)/2, pB.x, pB.y, pB.x, pB.y, (pB.x+pC.x)/2, (pB.y+pC.y)/2);
}
}

[always]{
for(int i = 0; i < p.length; ++i){
double dist = p[i].distanceTo(mouseX, mouseY);
double f = 0;
if(dist < 100) f = 100-dist;
double dire = point.directionBetween(preMouseX, preMouseY, mouseX, mouseY);
if(preMouseX != mouseX && preMouseY != mouseY){
p[i].push(f*0.8, dire);
}

double x = 200 + 80*Math.cos(i*Math.PI*2/p.length);
double y = 200 + 80*Math.sin(i*Math.PI*2/p.length);

p[i].pushTo(x, y);
}
}

点を動かす大きな仕組みは前回と同じです.
また,複数の点を角ばらずに滑らかに結ぶ方法はひものような動きの回と同じです.

今回は形状を「円」にしたためsetupalwaysで点の並び方を決定するのに

double x = 200 + 80*Math.cos(i*Math.PI*2/p.length);
double y = 200 + 80*Math.sin(i*Math.PI*2/p.length);

というようにして(200, 200)を中心とした半径80の円周上に配置しています.

また,角ばらないようにpaint

point pA, pB, pC;
if(i == 0) pA = p[p.length-1];
else pA = p[i-1];
pB = p[i];
if(i == p.length-1) pC = p[0];
else pC = p[i+1];
drawBezierCurve((pA.x+pB.x)/2, (pA.y+pB.y)/2, pB.x, pB.y, pB.x, pB.y, (pB.x+pC.x)/2, (pB.y+pC.y)/2);

として,pAはp[i]の一つ前の点,pBはp[i]自身,pCはp[i]の一つ後ろの点として,
(pAとpBの中点) - (pB) - (pBとpCの中点)
を結ぶことで角ばらないようにしています.

このようにして,マウスの動きになびくような円を生成しました.