円/線描画でカージオイド曲線を描く

# はじめに
カージオイドを描くには
１，極座標形式
２，媒介変数表示
３，ｘｙの直交座標表示
があるが、本稿は別の書き方を記す。

言語はprocessing

# ①内側を描く
赤い円周上を中心とする円で、且つ、その円が同じ点を通過する
```java:cardioid_in_circle.pde
import processing.pdf.*;

size(600,600);

beginRecord(PDF, "fn.pdf");

noFill();

translate(width/2,height/2);

for(float th=0; th<2*PI; th+=PI/10f){
  float x = 100*cos(th);
  float y = 100*sin(th);
  float r = 2*dist(0,0,x,y+100);
  ellipse(x,y,r,r);
}

stroke(255,0,0);
ellipse(0,0,200,200);

endRecord();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/16c28391-96a1-e076-653a-24f8d170a0ba.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/12d375b7-e4f2-f752-f091-dfdfcde59da0.png)

# ②外側を描く
円周上の２点を結ぶ（thラジアンとth*2ラジアンの時の点）
```java:cardioid_out_circle.pde
import processing.pdf.*;

size(600,600);

beginRecord(PDF, "fn1.pdf");
translate(width/2,height/2);

for(float th=0; th<2*PI; th+=PI/90f){
  float r = 200;
  float x1 = r*cos(th);
  float y1 = r*sin(th);
  float x2 = r*cos(th*2);
  float y2 = r*sin(th*2);
  line(x1,y1,x2,y2);
}

endRecord();
```
２倍角
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/43a4496e-fbbe-4f2f-414a-d7b71ae94cab.png)
３倍角
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/e9fec57d-87cc-9b91-3b7e-880df2f73644.png)
４倍角
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/59ca75eb-f4f8-e269-d1af-7b62a8c07de5.png)




交点計算して、中の線を消す。

```java:cardioid_out_circle.pde
import processing.pdf.*;

size(600,600);

beginRecord(PDF, "fn.pdf");
translate(width/2,height/2);

for(float th=0; th<PI; th+=PI/90f){
  float r = 200;
  float x1 = r*cos(th);
  float y1 = r*sin(th);
  float x2 = r*cos(th*2);
  float y2 = r*sin(th*2);
  if(y2<0){
    float R = (y2-y1)/(x2-x1);
    x2 = x1 - y1/R;
    y2 = 0;
  }
  line(x1,y1,x2,y2);
}
for(float th=PI; th<2*PI; th+=PI/90f){
  float r = 200;
  float x1 = r*cos(th);
  float y1 = r*sin(th);
  float x2 = r*cos(th*2);
  float y2 = r*sin(th*2);
  if(y2>0){
    float R = (y2-y1)/(x2-x1);
    x2 = x1 - y1/R;
    y2 = 0;
  }
  line(x1,y1,x2,y2);
}
endRecord();
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510257/2c7a21f7-eb4a-b53d-b726-ceade0a36d20.png)



# 番外：Python版
気になったので、MuのPythonと、ProcessingのPythonに移植した。
numpyがないとforで小数が使えないの不便。

```python:Mu.py
import numpy as np
import math

def draw():
    PI = 3.1415926535
    screen.fill(0xFFFFFFFF)
    for th in np.arange(-PI, PI, PI / 16):
        x = 100 * math.cos(th)
        y = 100 * math.sin(th)
        r = math.sqrt((x + 100) ** 2 + (y) ** 2)
        screen.draw.circle((x + 300, y + 300), r, "black")
```

```python:Mu.py
import numpy as np
import math

def draw():
    PI = 3.1415926535
    screen.fill(0xFFFFFFFF)
    r = 200
    for th in np.arange(-PI, PI, PI / 45):
        # print(th)
        x1 = r * math.cos(th)
        y1 = r * math.sin(th)
        x2 = r * math.cos(th*2)
        y2 = r * math.sin(th*2)
        screen.draw.line((x1+300, y1+300), (x2+300, y2+300), "black")
```

```python:Processing.py
def setup():
    size(600, 600)
    noFill()

def draw():
    background(255)
    translate(300, 300)

    for n in range(-180, 180, 8):
        th = radians(n)
        x = 100 * cos(th)
        y = 100 * sin(th)
        r = 2*dist(0,0,x+100, y)
        ellipse(x, y, r, r)
```


```python:Processing.py
def setup():
    size(512, 512)

def draw():
    background(255)
    translate(256, 256)
    r = 200
    for n in range(-180, 180, 4):
        th = radians(n)
        x1 = r * cos(th)
        y1 = r * sin(th)
        x2 = r * cos(th*2)
        y2 = r * sin(th*2)
        line(x1, y1, x2, y2)
```