Mathematicaで光源を変更して曲面を描画する

## 0. はじめに

最近、Mathematicaで光源の設定を変更する方法を知りました。  
本記事では、Mathematicaで光源の種類を変えて、媒介変数表示の曲面を描画する方法を紹介します。  
具体例として、描画対象の曲面は1つに固定し、光源の種類や位置等を変えた曲面を図示しています。

## 1. 準備

Wolfram IDを作成すれば、Wolfram Cloudにログインして無料でMathematicaを利用できます。  
下記のURLにアクセスしてWolfram IDを作成してください。  

<https://account.wolfram.com/ja/login/create>

Wolfram IDを作成しましたら、下記のURLからWolfram Cloudにログインしてください。

<https://www.wolframcloud.com/>

ログインすると、下図のページが開きます。

`New Notebook`を押下すると、新しいNotebookが開きます。

![01_wolframcloud.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/7bdd0ef2-52ca-1e82-131f-0d0e22193c8b.png)

## 2. 曲面の描画

まずは曲面を描画してみます。
下記をNotebookのセルに入力して実行します。

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"}
]
```

実行すると、媒介変数表示で指定した曲面が描かれます。

![02_parabolic_surface_mathematica.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/e3752319-1de5-d9fb-78fe-499b5aacdd3f.png)

この例では特に光源を指定していないため、デフォルトの光源が設定されています。

以降では、光源を明示的に指定し、曲面の描かれ方を比較してみます。

## 3. 光源の設定

デフォルトの光源から設定を変更してみます。

`ParametricPlot3D`の`Lighting`オプションに光源情報を指定すると、光源の種類や光の色などを変更できます。
MathematicaのLightingオプションでは、下記の4種類の光源を設定できます。

* 点光源
* 平行光源
* スポットライト
* 一様環境光

### 3-1. 点光源

点光源とは、光源が点として表わされる光源のことを指します。
1点の光源を中心として、放射状に光が放たれます。

![03-1_00_point_light_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/c6295684-8a7e-df79-1cb0-bc1159e2ca62.png)

Lighting設定を以下のようにすると、位置が $(0, 0, 1)$ の点光源の曲面を描けます。

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting -> {
    "Point",
    Orange,
    {0, 0, 1}
  }
]
```

![03-1_01_point_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/e377afff-b341-1f4d-39b1-c29e08cd3fee.png)

光源の位置を変えると下図のようになります。

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting -> {
    "Point",
    Orange,
    {-2, -4, 1}
  }
]
```

![03-1_02_point_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/ee433a82-666e-1276-106d-270e133f6b2c.png)

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting -> {
    "Point",
    Orange,
    {5, -4, 0}
  }
]
```

![03-1_03_point_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/5f7286ea-13b0-4c83-91e3-6b2f04244c05.png)

### 3-2. 平行光源

平行光源とは、各光線が平行で同じ向きになっている光源です。
点光源が無限遠方にある場合とも言えます。

![03-2_00_directional_light_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/16218b67-3d8d-6147-9e2f-e7f9b5a10f60.png)

DirectionalLightオプションを使うと、下記のいずれかのように指定することで平行光源の向きを設定できます。

* 1点を指定する
  * 各光線の向きは、指定した1点から描画領域 (=境界ボックス) の中心への向きと一致する  
    (描画領域の中心が必ずしも原点 $(0, 0, 0)$ と一致するとは限らないことに注意する)
* 2点を指定する
  * 各光線の向きは、1点目から2点目への向きと一致する

#### 3-2-1. 1点を指定する場合

下記のように設定すると、$(0, 0, -1)$ 方向の平行光源の曲面を図示できます。

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting -> {
    "Directional",
    Orange,
    {0, 0, 1}
  }
]
```

![03-2-1_01_directional_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/0d33787c-8eca-c0d4-3947-f01e3b9d0db8.png)

ベクトルの長さを変えても、向きが同じなら同じ絵になります。

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting -> {
    "Directional",
    Orange,
    {0, 0, 10}
  }
]
```

![03-2-1_02_directional_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/f5347bac-0011-adda-a0fc-6f6afdd82cc6.png)

平行光源の角度を変えると下図のようになります。

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting -> {
    "Directional",
    Orange,
    {2,-2,-1}
  }
]
```

![03-2-1_03_directional_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/efc3531d-c299-bebc-18d0-329cf665e4d0.png)

#### 3-2-2. 2点を指定する場合

例えば、平行光源の向きを $(0, 2, -1)$ のベクトルとする場合、下記のように指定します。

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting -> {
    "Directional",
    Orange,
    {
      {0, 0, 1},
      {0, 2, 0}
    }
  }
]
```

![03-2-2_01_directional_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/43e8cd49-7e03-bafd-95b3-0ef89eb7f378.png)

2点目に境界ボックスの中心と同じ点を指定した場合には、1点だけ指定した場合と同じ絵が描画されます。

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting -> {
    "Directional",
    Orange,
    {
      {0, 0, 1},
      {0, 0, 0}
    }
  }
]
```

![03-2-2_02_directional_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/37d0f422-d862-e431-9f75-9313050523cd.png)

### 3-3. スポットライト

スポットライトとは、円錐状に光を放つ光源のことを言います。
1点の光源を円錐の頂点として、円錐状に光が放たれます。

![03-3_00_spot_light_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/4545e711-1382-09e2-7d0f-144582937c29.png)

下記のようにLightingを指定すると、円錐の頂点座標が$(0, 0, 1)$、半角 (円錐の広がる角度) が $\pi/3$ の曲面を描画できます。

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting ->{
    "Spot",
    Orange,
    {0, 0, 1},
    Pi/3
  }
]
```

![03-3_01_spot_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/3b64be0b-b46f-db9a-3f54-a8ce30313607.png)

半角の大きさを変えると、光の当たる範囲が変わります。

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting -> {
    "Spot",
    Orange,
    {0, 0, 1},
    Pi/6
  }
]
```

![03-3_02_spot_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/b1003117-18cf-3a4b-5c2f-068ee2768680.png)

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting -> {
    "Spot",
    Orange,
    {0, 0, 1},
    Pi/9
  }
]
```

![03-3_03_spot_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/cae90dc6-bba7-b5f8-6b09-c32d1119da1a.png)

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting -> {
    "Spot",
    Orange,
    {0, 0, 1},
    Pi/2
  }
]
```

![03-3_04_spot_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/c38989e0-32e9-a9c2-d7f1-efecbdc6ead8.png)

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting ->{
    "Spot",
    Orange,
    {0, 0, 1},
    Pi
  }
]
```

![03-3_05_spot_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/563adac9-b263-3a35-80c2-d8894102029e.png)

### 3-4. 環境一様光

環境一様光とは、光源から直接届く光ではなく、壁や周囲の物による反射で環境全体に広がる光を指します。

![03-4_00_ambient_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/b3b738d2-b7b5-7335-73a4-b7c50f8544be.png)

Lightingに`AmbientLight`を指定すると、環境一様光で曲面を描画できます。

```mathematica
ParametricPlot3D[
  {u, v, u^2/2+v^3/6},
  {u, -2, 2},
  {v, -2, 2},
  AxesLabel -> {"x", "y", "z"},
  Lighting -> AmbientLight[Orange]
]
```

![03-4_01_ambient_light.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3337954/281980a5-a1b7-cf55-0b9c-53354a5b5f36.png)

## 4. まとめ

Mathematicaを使えば、比較的手軽に光源を設定して曲面を図示できます。

実験的に曲面の輝度や陰影を観察したい場合におすすめかと思います。

今後、曲面の反射率や材質を変更する方法も調査して試したいと思います。

## 5. 参考文献

* <https://reference.wolfram.com/language/tutorial/TheStructureOfGraphicsAndSound.html.ja?source=footer>
* <https://reference.wolfram.com/language/ref/Lighting.html.ja?source=footer>