Processing描画命令使ったGenerative Art例

# はじめに
Processingのリファレンス＋αとして、Generative Artっぽいものを目指したサンプルです。

リファレンス参照
https://processing.org/reference#shape-2d-primitives

リファレンス(abc)順にサンプル載せます。

# 円弧 arc
これらの円弧の長さは、すべて同じ。
```java:Processing
size(800, 800);
background(255);
float r = 390;
noFill();
for (float n=0.5; n<2.01; n+=0.1) {
  arc(400, 400, r/n, r/n, 0, PI*n);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/8b588532-2f63-5e1c-38dc-43662d3b6fb6.png)

```java:Processing
size(800, 800);
background(0);
float r = 400;
fill(255, 255, 0);
arc(400, 400, r, r, PI/4, PI*7/4);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/00bc915e-1594-8499-fd25-e7bbba3f5e34.png)


# 円circle
乱数でたくさん描く。
```java:Processing
void setup(){
  size(800, 800);
}

void draw() {
  float x, y, r;
  x = random(width);
  y = random(height);
  r = random(50, 100);
  fill(random(255));
  circle(x, y, r);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/ca206871-d915-984a-08ca-a0734a2847a7.png)

再帰処理で描く。
```java:Processing
void setup() {
  size(800, 800);
  func(400, 400, 800, 8);
}

void func(float x, float y, float r, int n) {
  if (0<n) {
    fill(n%2*255);
    circle(x, y, r);
    func(x-r/4, y, r/2, n-1);
    func(x+r/4, y, r/2, n-1);
  }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/a48db983-1c2f-a233-4c98-0223fcda4ff2.png)


# 楕円ellipse
乱数でたくさん描く。
```java:Processing
void setup(){
  size(800, 800);
}

void draw() {
  float x, y, w, h;
  x = random(width);
  y = random(height);
  w = random(50, 200);
  h = random(50, 200);
  fill(random(255));
  ellipse(x, y, w, h);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/41b4bda4-bbfb-c657-1b2b-0d87cbe0d17c.png)

回転させながら、縮小する。
```java:Processing
size(800, 800);
translate(400, 400);

for (int n=0; n<50; n++) {
  fill(255-n*4);
  ellipse(0, 0, 800, 400);
  scale(0.9);
  rotate(PI/22);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/892a2642-fe6a-765c-e304-43840047eac4.png)

# 線line
```java:Processing
size(800, 400);

for (int y=0; y<400; y+=10) {
  line(  0, y, 800-y*2,   0);
  line(800, y, 800-y*2, 400);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/7839f63d-0c3b-8804-ab7f-e6b91ce076c7.png)

# 点point
１ピクセルの点描ですが、直径１の円として描かれるため、希望の色になりません。noSmooth()を指定することで、希望の色で点描できます。
※set()やpixels[]使うと速くできます。
```java:Processing
size(800, 400);
noSmooth();

for (int y=0; y<400; y+=2) {
  for (int x=0; x<800; x+=2) {
    stroke(x/4,y/2,0);
    point(x,y);
  }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/08e9336c-bad3-b8a6-7703-0ebe76128c41.png)

# 四角quad
return to squareをオマージュ
```java:Processing
size(800, 800);
noFill();
float a=200, b=600;
for (int n=0; n<150; n+=5) {
  quad(a+n, a+n,
       b+n, a-n,
       b-n, b-n,
       a-n, b+n);
  quad(a-n, a+n,
       b-n, a-n,
       b-n, b+n,
       a+n, b-n);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/b1e7a77b-4e7d-919d-a732-01eb9de321a3.png)

# 長方形、矩形rect
長方形が描けて、角丸にする機能もあります。
参考までに、正円を赤で書きました。
角丸の値は、長方形の短辺の半分より大きくすることはできず、無視されます。以下のサンプルの場合、幅400に対して、角丸の値は200までしか認識されません。

```java:Processing
size(600, 600);
float x=100, y=100, w=400, h=400;
rect(x,y,w,h);
rect(x,y,w,h,50);
rect(x,y,w,h,100);
rect(x,y,w,h,150);
rect(x,y,w,h,200);

stroke(255,0,0);
circle(300,300,400);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/b97d6ac8-746c-4fb0-b4bd-4da3c67d49d0.png)

```java:Processing
size(800, 800);
translate(400, 400);
fill(255,255,255,10);
for (int x=0; x<=400; x+=10) {
  stroke(x, 0, 255);
  int y = 400-x;
  rect(-x, -y, x*2, y*2);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/d1df26c6-5067-8dba-4e2f-da915f5fec5b.png)

# 正方形square
比は1/√2です。
```java:Processing
size(800, 800);
translate(400, 400);

for (int n=0; n<20; n++) {
  square(-400, -400, 800);
  rotate(PI/4);
  scale(1/sqrt(2));
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/85fcd1a9-014e-8dca-0359-43a41f7dd0c1.png)

# 三角形triangle
```java:Processing
void setup() {
  size(800, 800);
  noStroke();
  func(800, 800, 800, 8);
}

void func(float x, float y, float h, int n) {
  if (0<n) {
    fill(0);
    triangle(x, y, x, y-h, x-h, y);
    func(x-h/2, y+h/2, h/2, n-1);
    func(x+h/2, y-h/2, h/2, n-1);
    func(x-h/2, y-h/2, h/2, n-1);
  }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/d9836c3c-cd19-c00f-f1a2-6c72bf2c3188.png)

# 多角形beginShape,endShape,vertex
beginShape
　vertex(頂点1)
　vertex(頂点2)
　...
endShape
のように使う。
このとき、頂点をどのように描画するか、指示ができる。
指定なし：多角形
POINTS 複数の点
LINES 複数の線
TRIANGLES 複数の三角形
TRIANGLE_STRIP 帯状の連続した三角形
TRIANGLE_FAN 扇形の三角形
QUADS 複数の四角形
QUAD_STRIP 帯状の連続した四角形
※それぞれ対応する数字がある。
```java:Processing
println(POINTS);//3
println(LINES);//5
println(TRIANGLES);//9
println(TRIANGLE_STRIP);//10
println(TRIANGLE_FAN);//11
println(QUADS);//17
println(QUAD_STRIP);//18
```
## 多角形
```java:Processing
size(300, 300);
translate(150, 150);

beginShape();
for (float t=0; t<2*PI; t+=PI/6) {
  vertex(100*cos(t), 100*sin(t));
}
endShape();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/d9da7f61-f8c9-febb-192e-908445f99a03.png)

## LINES
```java:Processing
size(300, 300);
translate(150, 150);

beginShape(LINES);
for (float t=0; t<2*PI; t+=PI/6) {
  vertex(100*cos(t), 100*sin(t));
}
endShape();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/ee5752d1-ed4b-bb20-c0d5-057c8b6cdda9.png)

## TRIANGLES
```java:Processing
size(300, 300);
translate(150, 150);

beginShape(TRIANGLES);
for (float t=0; t<2*PI; t+=PI/6) {
  vertex(100*cos(t), 100*sin(t));
}
endShape();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/886fc5f9-9603-d821-b8a0-273531118a16.png)

## TRIANGLE_STRIP
```java:Processing
size(300, 300);
translate(150, 150);

beginShape(TRIANGLE_STRIP);
for (float t=0; t<2*PI; t+=PI/6) {
  vertex(100*cos(t), 100*sin(t));
}
endShape();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/6038882e-b072-17bb-fe48-43ef9ae92f47.png)

## TRIANGLE_FAN
```java:Processing
size(300, 300);
translate(150, 150);

beginShape(TRIANGLE_FAN);
for (float t=0; t<2*PI; t+=PI/6) {
  vertex(100*cos(t), 100*sin(t));
}
endShape();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/68e5e810-f955-b7f2-9d3b-fe21894b918e.png)

## QUADS
```java:Processing
size(300, 300);
translate(150, 150);

beginShape(QUADS);
for (float t=0; t<2*PI; t+=PI/6) {
  vertex(100*cos(t), 100*sin(t));
}
endShape();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/c9a07e33-258f-ac3f-369f-a612d7f510dd.png)

## QUAD_STRIP
```java:Processing
size(300, 300);
translate(150, 150);

beginShape(QUAD_STRIP);
for (float t=0; t<2*PI; t+=PI/6) {
  vertex(100*cos(t), 100*sin(t));
}
endShape();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/bb1fe2ec-6862-3439-3993-08458e791083.png)

# 輪郭beginContour,endContour
多角形を描く際に、中をくりぬく。飛び出た場合は、図のようになる。
```java:Processing
size(400,400);
translate(200, 200);

beginShape();
  // 外側時計回り
  vertex( 0, -170);
  vertex(150, 90);
  vertex(-150, 90);

  // 内側反時計回り
  beginContour();
  vertex(-150, -90);
  vertex(0, 170);
  vertex(150, -90);
  endContour();
endShape(CLOSE);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/cb779539-1d80-d6cb-fbe0-f602e6778133.png)


# 二次ベジェ曲線quadraticVertex
制御点は３つ必要です。最初の制御点は、直前の命令vertexの終点(0,200)になるので、quadraticVertexでは、2点(制御点と終点)の指定をします。サンプルでは、視点を終点を同一にし、制御点をずらして描画しています。
モアレ軽減のため、半透明使ってます。
```java:Processing
size(400, 400);
noFill();
stroke(0,0,0,128);

beginShape();
  vertex(0, 200);
  for(float y=-200; y<600;y+=20){
    quadraticVertex(200, y , 400, 200);
    quadraticVertex(200, y+10, 0, 200);
  }
endShape();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/45e7a0fa-f006-2b8e-3d82-d5df9b7ad458.png)

二次ベジェ曲線はlineで示したサンプルと一致します。
```java:Processing
size(800, 400);
noFill();

for (int y=0; y<400; y+=10) {
  line(  0, y, 800-y*2,   0);
  line(800, y, 800-y*2, 400);
}

stroke(255,0,0);
beginShape();
  vertex(0, 400);
  quadraticVertex(0, 0, 800, 0);
  quadraticVertex(800, 400, 0, 400);
endShape();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/1628dc31-2811-73fb-95ee-5d2c4d10193f.png)

# 三次ベジェ曲線bezier
制御点は４つ必要です。始点と終点を固定し、１つの制御点を、ずらして描いています。
```java:Processing
size(800, 400);
noFill();
stroke(0,0,0,128);
for(int y=-300; y<500; y+=20) {
  bezier(  0, 200,
         300,   y,
         500, 400,
         800, 200);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/1bbd068e-8e11-55f9-3f07-299f0bd72e9e.png)


# bezierVertex
４つの制御点が必要なところを、始点を直前の命令(vertexなど)とすることで、３点を指定すれば良い方法です。イラレのような、連続したベジェ曲線に使えそうです。
ここでは、２本のベジェ曲線でハートを描きました。
```java:Processing
size(800, 600);
translate(400, 150);

beginShape();
  vertex(0, 0);
  bezierVertex(300, -200, 400, 200, 0, 400);
  bezierVertex(-400, 200, -300, -200, 0, 0);
endShape();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/fcf6ee5d-0649-e571-f81c-599641dc8340.png)

# 分割数制御bezierDetail
1~20の範囲で分割数を制御。P3Dのみ対応。出番は低そう。
```java:Processing
size(800, 600, P3D);
translate(400, 150);

bezierDetail(20);
beginShape();
  vertex(0, 0);
  bezierVertex(300, -200, 400, 200, 0, 400);
  bezierVertex(-400, 200, -300, -200, 0, 0);
endShape();

bezierDetail(5);
scale(0.8);
beginShape();
  vertex(0, 0);
  bezierVertex(300, -200, 400, 200, 0, 400);
  bezierVertex(-400, 200, -300, -200, 0, 0);
endShape();

bezierDetail(3);
scale(0.8);
beginShape();
  vertex(0, 0);
  bezierVertex(300, -200, 400, 200, 0, 400);
  bezierVertex(-400, 200, -300, -200, 0, 0);
endShape();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/bde395ff-c9cb-0e7a-d74f-a66fb46aacd8.png)

# bezierPoint
0<t<1で
tを変化させたときに、どうなるか、
ベジェ曲線の理解を深めるのに使えそうです。
```java:Processing
size(800, 600);
translate(400, 150);

int x1=  0, y1=   0;
int x2=300, y2=-200;
int x3=400, y3= 200;
int x4=  0, y4= 400;

bezier(x1, y1,  x2, y2,  x3, y3, x4, y4);
bezier(x4, y4, -x3, y3, -x2, y2, x1, y1);

float x,y;
strokeWeight(20);

for(float t=0; t<=1.001; t+=0.1){
  x = bezierPoint(x1, x2, x3, x4, t);
  y = bezierPoint(y1, y2, y3, y4, t);
  point(x,y);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/7f273ecf-77a0-4dc1-213a-4a9329071a6e.png)

# 接線bezierTangent
tan正接、接線の向きが得られます。
ここでは、正規化(normalize)してから使いました。

また、接線を90度回転して法線が描けます。
(x,y)ベクトルを９０度回すということは,
(y,-x)に変換することです。

```java:Processing
size(800, 600);
translate(400, 150);

int x1=  0, y1=   0;
int x2=300, y2=-200;
int x3=400, y3= 200;
int x4=  0, y4= 400;

bezier(x1, y1,  x2, y2,  x3, y3, x4, y4);
bezier(x4, y4, -x3, y3, -x2, y2, x1, y1);

float x,y,tanx,tany;
for(float t=0; t<=1.001; t+=0.1){
  x = bezierPoint(x1, x2, x3, x4, t);
  y = bezierPoint(y1, y2, y3, y4, t);
  tanx = bezierTangent(x1, x2, x3, x4, t);
  tany = bezierTangent(y1, y2, y3, y4, t);
  PVector v = new PVector(tanx,tany);
  v.normalize();
  stroke(255,0,0);
  line(x-v.x*50,
       y-v.y*50,
       x+v.x*50,
       y+v.y*50);
  stroke(0,0,255);
  line(x,
       y,
       x+v.y*50,
       y-v.x*50);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/52292d02-b8e2-149c-1f3d-c36a706d66f0.png)

# Catmull-Romスプラインcurve
スプライン曲線とは指定した点の上を通る曲線のことです。
曲線の引き方にも種類があり、ProcessingではCatmull-Romをcurve命令で実装されています。
以下では、５点を指定し、これら５点を通る曲線を描いています。
通常1-2-3-4と点を指定した場合、2-3の間しか曲線が引けませんが、1-1-2-3と指定したり、3-4-5-5と重ねて指定することで、始点と終点を通す曲線が描けます。
```java:Processing
size(600, 400);
noFill();

int x1=100, y1=100;
int x2=100, y2=300;
int x3=300, y3=300;
int x4=300, y4=100;
int x5=500, y5=100;

line(x1, y1, x2, y2);
line(x2, y2, x3, y3);
line(x3, y3, x4, y4);
line(x4, y4, x5, y5);

stroke(255, 0, 0);
curve(x1, y1, x1, y1, x2, y2, x3, y3);
stroke(0);
curve(x1, y1, x2, y2, x3, y3, x4, y4);
stroke(0, 0, 255);
curve(x2, y2, x3, y3, x4, y4, x5, y5);
stroke(0, 255, 0);
curve(x3, y3, x4, y4, x5, y5, x5, y5);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/91e4a9a0-f73b-232b-b67b-71a61bcc7387.png)

下はbezierのサンプル座標と同じ座標でcurveを使って、描いたものです。
bezierとcurveの指定点を通る通らないの特徴がでています。
```java:Processing
size(800, 500);
noFill();

for(int y=-300; y<500; y+=20) {
  stroke(0,0,0,128);
  curve(   0, 200,
           0, 200,
         300,   y,
         500, 400);
  stroke(255,0,0,128);
  curve(   0, 200,
         300,   y,
         500, 400,
         800, 200);
  stroke(0,0,255,128);
  curve( 300,   y,
         500, 400,
         800, 200,
         800, 200);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/d478dd70-7268-53c1-786b-28d0aac32691.png)


# curveVertex
長いスプライン曲線を描くなら、こっちの書き方がシンプルでしょう。
```java:Processing
size(600, 400);
noFill();

int x1=100, y1=100;
int x2=100, y2=300;
int x3=300, y3=300;
int x4=300, y4=100;
int x5=500, y5=100;

line(x1, y1, x2, y2);
line(x2, y2, x3, y3);
line(x3, y3, x4, y4);
line(x4, y4, x5, y5);

stroke(255, 0, 0);

beginShape();
  curveVertex(x1, y1);
  curveVertex(x1, y1);
  curveVertex(x2, y2);
  curveVertex(x3, y3);
  curveVertex(x4, y4);
  curveVertex(x5, y5);
  curveVertex(x5, y5);
endShape();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/25bbb70d-9a09-fe1c-de00-0401993a9e81.png)


# curveTightness
スプライン曲線を変えることができる。仕組みは未調査。引数はいくつでも良いが、リファレンスでは-5~5を使っていた。使う場面が思いつかないが、-1~1あたりなら丸みの制御で使えそう。
-1は大きく膨らむ
０は無指定と同じ
1は直線と同じ
2は曲線がねじれる
```java:Processing
int x1=100, y1=100;
int x2=100, y2=300;
int x3=300, y3=300;
int x4=300, y4=100;
int x5=500, y5=100;

void setup(){
  size(600, 500);
  noFill();
  
  for(int t=-5; t<=5; t++){
    stroke(128+20*t, 0, 0);
    func(t);
  }
  
  stroke(255,255,255);
  line(x1, y1, x2, y2);
  line(x2, y2, x3, y3);
  line(x3, y3, x4, y4);
  line(x4, y4, x5, y5);
}

void func(float t){
  curveTightness(t);
  beginShape();
    curveVertex(x1, y1);
    curveVertex(x1, y1);
    curveVertex(x2, y2);
    curveVertex(x3, y3);
    curveVertex(x4, y4);
    curveVertex(x5, y5);
    curveVertex(x5, y5);
  endShape();
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/03c391ed-34e9-2660-1912-b61239fb2ede.png)

```java:範囲を変えた場合
  for(float t=-1; t<=1; t+=0.4){
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/9592b702-c655-7197-43ff-0a8fd5508a17.png)

# curveDetail
1~20の範囲で分割数を制御。P2Dのみ対応。出番は低そう。

```java:Processing
int x1=100, y1=100;
int x2=100, y2=300;
int x3=300, y3=300;
int x4=300, y4=100;
int x5=500, y5=100;

void setup(){
  size(600, 500, P2D);
  noFill();
  
  stroke(0, 0, 0);
  func(1);
  stroke(255, 0, 0);
  func(2);
  stroke(0, 0, 255);
  func(4);
}

void func(int d){
  curveDetail(d);
  beginShape();
    curveVertex(x1, y1);
    curveVertex(x1, y1);
    curveVertex(x2, y2);
    curveVertex(x3, y3);
    curveVertex(x4, y4);
    curveVertex(x5, y5);
    curveVertex(x5, y5);
  endShape();
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/07701e77-d234-7f8f-f3f6-6849d62611d6.png)

# curvePoint
bezierと同じなので割愛

# curveTangent
bezierと同じなので割愛

# 直方体box
```java:Processing
void setup() {
  size(400, 400, P3D);//OPENGLでも動く
}

void draw() {
  background(255);
  translate(200, 200, 0);
  rotateY(frameCount*0.01);
  noFill();
  box(150);
  box(200,100,200);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/b86076e5-a5cf-428d-5e90-77a54f615682.png)

# 球sphere
sphereDetailのデフォルトは30
sphereDetail(水平分割数,垂直分割数)でも使える。
```java:Processing
void setup() {
  size(800, 800, P3D);
}

void draw() {
  background(255);
  translate(400, 400, 0);
  rotateY(frameCount*0.01);
  noFill();
  sphereDetail(16);
  sphere(300);
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/4403e0c6-3482-8c5a-7ed4-5ec562250d98.png)

# 3D
```java:Processing
void setup() {
  size(800, 800, P3D);
  noStroke();
}

void draw() {
  background(255);
  camera(0, -100, 200,
         0, 0, 0,
         0, 1, 0);
  lights();

  for (float z=-100; z<101; z+=50) {
    for (float x=-100; x<101; x+=50) {
      fill(random(255),random(255),random(255));
      pushMatrix();
        translate(x, 0, z);
        sphere(20);
      popMatrix();
    }
  }
}

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/83839ecf-0c28-076f-321b-c0fed04107e9.png)

# ノイズnoise
randomとは異なり、滑らかに変化する乱数(0~1)が得られる。
実装はPerlin関数。
引数の数で１次元,２次元,３次元が選べる。
```java:Processing
float th;

void setup() {
  size(800, 800);
}

void draw() {
  background(255);
  for (int y=0; y<800; y+=10) {
    for (int x=0; x<800; x+=10) {
      th = noise(x*0.01, y*0.01, frameCount*0.02);
      th *= 4*PI;
      line(x, y, x+20*cos(th), y+20*sin(th));
    }
  }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/be6cc435-310b-663c-a327-fb3d6d0f4f75.png)


# その他
rect命令の角丸機能は、もしかして、iPhoneの角かも！と思いましたが、違いました。
rect(100,100,400,400,169);
の時一番近くなりますが、一致はしません。

# Processingの入出力について
|   | 書き出し | 読み込み | 備考 |
|:-:|:-:|:-:|:--|
|JPG| o | o | save("a.jpg")<br>loadImage()  |
|PNG| o | o | save("a.png")<br>loadImage()  |
|SVG| o | o | import processing.svg.*;<br>loadShape()  |
|OBJ| △ | o | import nervoussystem.obj.*<br>loadShape()|
|PDF| o | x | import processing.pdf.*;  |


Sprine系の曲線をSVGやPDFで保存した場合でも、内部でベジェに変換されて保存されます。円もしかりです。