[Go to “teaching” in Morimoto Lab]

Game by ball 7

①ボールに力を加える・投げる
②見えないボールでアトラクターを作る


1. ボールに力を加える

classの練習、Attractorのための助走としてボールに力を加えるプログラムを作る。

力を加える=速さにあるベクトルを加える。
まず、ボールが重力ではねているプログラムを作ろう。
このとき、classを使おう。できたら、
マウスを押したら適当なベクトルが速度に足されるコードを作ろう。
以下はヒントです。

[Sample Code A]
Ball ball;
void setup(){
size(500,500);
ball = new Ball();
}
void draw(){
background(255);
ball.update();
if(mousePressed) {
ball.addForce();
}
}
class Ball{
PVector pos;
float size = 100;
float radi = size/2.0;
PVector vel;
float gravity;
float air_drag = 0.99f;
Ball()
{
pos = new PVector(width/2, height/2);
vel = new PVector(10, -10);
gravity = 0.98f;
}
void update()
{
//update velosity:ここは第1,2回にしたので省略
//update position:ここは第1,2回にしたので省略
//bound:壁とのバウンドは今回なくてもよいです
display();
}
void display(){
stroke(0);
noFill();
ellipse(pos.x, pos.y, size, size);
}
void addForce(){
PVector vec = new PVector(10,-10);
vel.add(vec);
}
}

Ex A:上記のクラスを完成させて、マウスを押したらボールに力が加わるようにする

//update velosity
//vel.y = ;//重力。なくてもよい。
vel.x *=air_drag;//空気抵抗
vel.y *=air_drag;
//update position
/*位置の更新をしてください(以前の回でもしています)*/

注意:
Ballクラスの中では、メンバ変数であるposやvelはそのまま使ってください(pos.xなど)。
Ballクラスの中で、ball.pos.xなどとしないようにしましょう。
記述が冗長ですし、配列でBallが増えるとよくわからないことになってしまいますし、使い方としておかしいです。

Alt text


Ex B: 次に、マウスとボールが近づいたときに、力が加わるようにする

<実装の一例>

  1. addForce内で

  2. ボールがマウスからどれくらいの距離に入ったら、力を与えるか、決める

  3. マウスとボールの距離を計算

  4. 2で決めた距離内にマウスがあるかどうか判定

  5. もし距離内にマウスがあったら、マウスからボールへの単位ベクトルを計算し、適当な倍数にして調整して、ボールの速度にベクトルを足す


ヒント:近いほど強くなるような力の計算方法
例えば、以下のように計算した値を力の大きさとするとよさそうですが、工夫してみてもよいと思います
①(1/距離)
②(影響範囲-距離)※1
③(ガウス関数などの釣鐘型の関数に距離を変数として計算)※2

※1 値が0以下になるときはifで場合分けの処理をすること。
※2 指数関数はexp(), べき乗はpow()で計算できる。

Alt text
↑点を並べてマウスを押して周囲に力を与えた場合
※課題はまずボール一つでやってみてください。
※課題では重力や壁とのバウンドはあってもなくてもよいです。


(おまけ。余裕のある人へ)ボールをマウスドラッグでつかんで、マウスを離したときに投げるようにする

※この課題は横道にそれるのでとばしてもいいですが、ポケモンGOみたいにボールを投げるコンテンツ興味のある人はやってみてください。


2. Attractorを作ろう

Attractorは数値的値の集合が動的に発展をするもの、らしい。

Attractorの画像検索結果

Alt text

数学的Attractor:
Attractorについてのサイトをいくつか紹介。

今回実装するのはAttractorのような雰囲気のビジュアルのものである。
ここでの実装では、アトラクターは見えないボールとボールの間を線でつなぎ、
そのボールをマウスにひきつけたり、逆に離したりすることで、
不思議な模様が描きます。

以下はGenerative Designという本の例。
http://www.bnn.co.jp/support/generativedesign/code/M_4_3_01_TOOL.html

enter image description here

以下のようにコードをダウンロードして、
デスクトップ上でこのプログラムを実行してみよう。

  1. このページの右のボタン”code”から、”download zip”などでdownloadする

  2. 解凍したフォルダからCode-Package-Processing-3.x/02_M/M_4_3_01_TOOL/を開く

  3. pdeファイルをProcessingで開く。

  4. Generative Designのライブラリをimportする必要があります。
    メニュー>スケッチ>ライブラリをインポート>ライブラリを追加 より”GenerativeDesign”をインストールする

  5. 実行できるはず

クリックして、挙動を見てみましょう。
左上のボタンを押すと、UIが現れ、影響範囲や点の動かし方を変更できます。

しかしコードを見てみると、つらく感じる人もいるだろう。
プロのプログラムを読むのはつらい作業だ。
むしろ、これまで培ったGame by ballの知識で一から実装してみよう。
そっちの方が簡単だと思う。

※高みを目指す人には人のプログラムは色々見てもらいたい。
とても勉強になる。


Ex C: Attractorを実装しなさい(横方向一列のみ)

①まず横一列を作る

  1. 最初のBallクラスを使って横一列にボールを並べる

    • 重力や壁とのバウンドはいらない

  2. ボールをマウスから遠ざけるように力を加える

    • 距離に反比例するように力の大きさを加える

  3. ボールとボールの間に線を描く(横方向だけ)

  4. ボールはy方向にしか動かないようにする

Ex D: Attractorを実装しなさい(全体)

②縦に増やす

  1. 横一列できたら、それをクラス化(BallLineクラス)する ※後述

  2. y方向にBallLineをたくさん並べる

  3. ボールを消す

  4. 色や点の間隔や動き方を調整する

    • 線にきれいな色(グラデーションなど)を指定する
      (HSB色空間や透明色などを使う)

Alt text

※BallLineクラスの一例
以下は、横一列のボールとその間に線を描画するBallLineクラスの実装例です。

BallLine ballLine;
int xnum=10;//横方向のボールの数
void setup() {
size(500, 500);
ballLine = new BallLine(100);
}
void draw() {
background(255);
ballLine.update();
}
class BallLine {
Ball[] balls;
BallLine(int ofssetY) {
balls = new Ball[xnum];
for (int i=0; i<balls.length; i++) {
balls[i] = new Ball(i*50, 100+ofssetY);
}
}
void update() {
for (int i=0; i<balls.length; i++) {
balls[i].update();
if (mousePressed) {
balls[i].addForce();
}
//draw line
if (i+1<balls.length) {
PVector a =balls[i].pos;
PVector b =balls[i+1].pos;
line(a.x, a.y, b.x, b.y);
}
}
}
}
//Ballクラスの記述は省略

!Ballクラスは初期位置(x,y)を指定できる引数を持つコンストラクタが必要です


(余裕がある人へ) 自分なりの工夫をして美しいor面白いAttractorを作ろう。

例えば

もっとAttractorの例を見て、実装の参考にしよう。
ちなみにこのページのM.4アトラクターに7つもコードと動画付きの例がある。

ここにも別の例(ビジュアルのみ)。
https://www.dezeen.com/2012/11/20/competition-five-copies-of-generative-design-to-be-won/


☕コーヒーブレイク:ボールじゃなくてノード
アトラクターで使ったようなボールのことをノード(Node)と呼ぶ。
「結び目」のことで、線と線のつなぎ目などのことを呼ぶことが多い。
グラフ理論の分野で頂点あるいは節点と言われるもの。
点の集合とそれを連結する情報があれば広義で使ってよさそうです。

今回のようなプログラムでノードを増やすと、滑らかな形状が得られる反面、処理動作が多少遅くなることを確認してもらいたい。