ショートプログラムを読み解くメモ


「凄すぎてもう訳が分からない作品へのリンク集」に掲載の作品を読み解くためのメモです。
http://koji.jpn.org/processing/amazing/
サイトはこちらです。

```java:Volfegan.pde
float i, m, n, p, s, t;
void setup() {
  size(1080, 720);
  noStroke();
}
void draw() {
  background(0);
  translate(-0.4*1080, -720/4);
  for (i=2e3; i>0; i--) {
    p=i%2==0?0:1;
    m=t/cos(t/i)+p*(t/2+i%t);
    rect(960+m*sin(n=t/9+i*i)*cos((p==0?1:0)*i/t), 540+m*cos(n+p*2), s=3-cos(n)*3, s);
  }
  t+=.05;
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/2cd5cf5a-8c27-ea99-1bcb-dfbe38a9173b.png)

下が一つ元のコード
```java:saturn.pde
//inspired by https://www.dwitter.net/d/10534
//https://twitter.com/VolfeganGeist/status/1273451476556353536
float i, m, n, p, s, t, x, y;
void setup() {
  size(1080, 720);
  noStroke();
}
void draw() {
  background(0);
  t+=.05;
  for (i=2e3; i>0; i--) {
    p=i%2==0 ? 0 : 1;
    m=t/cos(t/i)+p*(t/2+i%t);
    n=t/9+i*i;
    x=560+m*sin(n)*cos((p==0 ? 1 : 0)*i/t);
    y=360+m*cos(n+p*2);
    s=3-cos(n)*3;
    rect(x, y, s, s);
  }  
}
```

おそらく元ネタである下記サイトのjavascript
https://www.dwitter.net/d/10534
```javascript:saturn.html
function u(t) {
x.fillRect(0,0,i=2e3,i)
for(t+=160;p=i&1,m=t/C(t/i)+p*(t/2+i%t),i--;)x.clearRect(
960+m*S(n=t/9+i*i)*C(!p*i/t),
540+m*C(n+p*2),s=3-C(n)*3,s)
```
と、解説文がある。
u(t) is called 60 times per second.
|   |   |
|:-:|:-:|
|t: |elapsed time in seconds.|
|c: |A 1920x1080 canvas.|
|x: |A 2D context for that canvas.|
|S: |Math.sin|
|C: |Math.cos|
|T: |Math.tan|
|R: |Generates rgba-strings, ex.: R(255, 255, 255, 0.5)|


https://twitter.com/VolfeganGeist/status/1273451476556353536
はもう見れない。

①　2e3
2000のこと。

②　p=i%2==0 ? 0 : 1;
iが偶数ならp=0
iが奇数ならp=1

③　m=t/cos(t/i)+p*(t/2+i%t);
式の前半はよくわからない。tとmの関係グラフ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/40fd8dfe-30a0-8d12-a07f-3c3762439955.png)
部分を拡大して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/e0789fb5-8318-7cde-e4fe-982682f37c43.png)
なんだろう？

式の後半はpが0か1によって、以下の表示を制御する。
p=1のときリングのみ表示される。
p=0のとき、球だけが表示される。

④　n=t/9+i*i;
tは0.05ずつ加算され、
iは2000から１ずつ減算される。
t=100のとき、i=1、n=12.11111111となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/1858e005-7178-e41b-cc5c-70d9b9473a24.png)

nは角度に使われており、
n=i*i;でも絵面に変化はなく、n=i;だと、規則的な模様が見えてしまうことから、乱数の代わりに使っているとおもう。乱数生成は重いので、簡易的に計算を済ませている。

解析中



--------
別のもの
processingのpythonモードで動くプログラム

```python:test.py
W=540
N=200
x,y,t=0,0,0

def setup():
  size(W,W)
  noStroke()
  
def draw():
  global t
  clear()
  [F(i,j)for i in range(N)for j in range(N)]
  #for j in range(N):
  #  for i in range(N):
  #    F(i,j)
      
  t+=.02

def F(i,c):
  global x,y
  r=TAU/N
  u=sin(i+y)+sin(r*i+x)
  v=cos(i+y)+cos(r*i+x)
  x=u+t
  y=v
  fill(i,c,99)
  circle(u*N/2+W/2,y*N/2+W/2,2)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/831da1c4-8457-f2e4-fd5d-314594d667de.png)

これをjavaモードで動くように移植したいが、うまく行かない。
pythonのリスト内包表記が肝なのかもしれないが、それにしても、なぜ、円描画のみで、これだけのものが描けるのか。

```java:test.pde
float W=540;
float N=200;
float x, y, t;

void setup() {
  size(540, 540);
  noStroke();
}
void draw() {
  background(0);
  for(int j=0; j<N; j++){
    for(int i=0; i<N; i++){
      F(i, j);
    }
  }
  t += 0.02;
}
void F(float i, float c){
  float r = TWO_PI/N;
  float u = sin(i+y)+sin(r*i+x);
  float v = cos(i+y)+cos(r*i+x);
  x = u+t;
  y = v;
  fill(i,c,99);
  circle(u*N/2+W/2, y*N/2+W/2, 2);
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/de422162-9261-3fbd-80a2-b86713b9660e.png)