【数学こぼれ話】【Token】トーラス概念

コーシーの積分定理によれば正則関数の積分結果は0になる。ここで問題となるのは上掲図の「三次元における(０→$∞^+$の座標系と０→$∞^-$の座標系の)二重球面状態」。なのでヤコビアンを用いて球の体積を求める時や球表面を経度(±180度)と緯度(±90度)で表す時には「半分」で考える。この様に「任意の偶関数を中心で割って奇関数二つと見做す」操作などが偶奇概念の出発地点の一つとなる。

[Wikipedia「コーシーの積分定理」](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC%E3%82%B7%E3%83%BC%E3%81%AE%E7%A9%8D%E5%88%86%E5%AE%9A%E7%90%86)

```math
\int_0^{1}\int_0^{2π}\int_0^{π}dx=\begin{vmatrix} \frac{∂x}{∂r} & \frac{∂x}{∂θ} & \frac{∂x}{∂φ}\\ \frac{∂y}{∂r} & \frac{∂y}{∂θ} & \frac{∂y}{∂φ}\\ \frac{∂z}{∂r} & \frac{∂z}{∂θ} & \frac{∂z}{∂φ}\end{vmatrix}
```
[半径・直径・円周長・円の面積・球の表面積・球の体積の計算上の往復](https://qiita.com/ochimusha01/items/e180451a210227bb19a5)
![68747470733a2f2f63646e2d616b2e662e73742d686174656e612e636f6d2f696d616765732f666f746f6c6966652f6f2f6f6368696d7573686130312f32303231303731362f32303231303731363034353235382e676966.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597772/7f99a011-a3e5-e800-7054-295ccfc2d690.gif)
[Yahoo知恵袋「３次元の極座標について」](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1141170176)

* 実はここまで徹底して嫌われている二重球面状態、トーラス座標系(Torus Coordinate System)における「大半径0、小半径1」の状態だったりする。その反対の対は「(限りなく大半径1、小半径0の比率に近い)円周$\tilde{∞}$半径1(i)の円弧」となり、その中間として「大半径1、小半径1」の単位トーラス状態が存在する。
![スクリーンショット 2023-10-20 16.00.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597772/a8e881ea-8440-d0ba-438d-9311e13e1593.png)
![68747470733a2f2f63646e2d616b2e662e73742d686174656e612e636f6d2f696d616765732f666f746f6c6966652f6f2f6f6368696d7573686130312f32303231303432332f32303231303432333037353232372e676966.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597772/18c7d66d-8b28-95e5-2cf7-81ae867c004e.gif)
![68747470733a2f2f63646e2d616b2e662e73742d686174656e612e636f6d2f696d616765732f666f746f6c6966652f6f2f6f6368696d7573686130312f32303231303432332f32303231303432333038303232302e676966.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597772/ceda4c82-0501-8a2b-44c5-e0ae47f04d61.gif)
![68747470733a2f2f63646e2d616b2e662e73742d686174656e612e636f6d2f696d616765732f666f746f6c6966652f6f2f6f6368696d7573686130312f32303231303432332f32303231303432333038303330352e676966.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597772/e071763d-78a6-2f7c-0f32-50779ace36b6.gif)

```python
%matplotlib nbagg
import math as m
import cmath as c
import numpy as num
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation

#円柱データ作成
c0=num.linspace(0,m.pi*120,1201,endpoint = True)
s0=[]
for nm in range(len(c0)):
    s0.append(complex(m.cos(c0[nm]),m.sin(c0[nm])))
s1=num.array(s0)
z0=num.linspace(-1,1,1201,endpoint = True)

#「曲率」を計算
cv0=num.linspace(-1,1,1201,endpoint = True)
cv1=num.sqrt(1-cv0**2)

#トーラス計算
s2=s1*(1+cv1)
s3=s1*(1-cv1)

#小半径追加
MiHz0=num.linspace(-1,1,61,endpoint = True)
MiHz=MiHz0[::-1]
MiPx=1+num.sqrt(1-MiHz**2)
MiMx=1-num.sqrt(1-MiHz**2)
MiBx=num.sqrt(1-MiHz**2)
MiHy=num.repeat(0,61)

#小半径アニメーション(元図形)
MiAh1=num.linspace(-1,1,31,endpoint =True)
MiAh2=num.linspace(-1,1,31,endpoint = False)
MiAh3=num.concatenate([MiAh1, MiAh2[::-1]])
MiAh=num.concatenate([MiAh3[14:61], MiAh3[0:13]])
MiAv1=1-num.sqrt(1-MiAh1**2)
MiAv2=1+num.sqrt(1-MiAh2[::-1]**2)
MiAv3=num.concatenate([MiAv2, MiAv1])
MiAv=num.concatenate([MiAv3[14:61], MiAv3[0:13]])

#小半径アニメーション(回転)
MiAvC0=[]
for nm in range(len(MiAv)):
    MiAvC0.append(complex(MiAv[nm],0))
MiAvC=num.array(MiAvC0) 

#単位円データ作成
u0=num.linspace(0,m.pi*2,61,endpoint = True)
u1=[]
for nm in range(len(u0)):
    u1.append(complex(m.cos(u0[nm]),m.sin(u0[nm])))
uc=num.array(u1)
uz0=num.repeat(-1,61)
uz1=num.repeat(-0,61)
uz2=num.repeat(1,61)

#グラフ表示
plt.style.use('default')
fig = plt.figure()
ax = Axes3D(fig)
Tcode=num.linspace(0,m.pi*2,61,endpoint =True)
#描画関数定義
def unit_cylinder(n):
    plt.cla()
    #断面計算
    MiAvD0=[]
    for nm in range(len(MiAvC)):
        MiAvD0.append(c.rect(MiAv[nm],Tcode[n]))
    MiAvD=num.array(MiAvD0) 
    MiBvD0=[]
    for nm in range(len(MiBx)):
        MiBvD0.append(c.rect(MiBx[nm],Tcode[n]))
    MiBvD=num.array(MiBvD0)
    MiCvD0=[]
    for nm in range(len(MiHz)):
        MiCvD0.append(c.rect(2,Tcode[n]))
    MiCvD=num.array(MiCvD0)
    #軌跡計算
    Orb_r=abs(MiAvD[n])
    Orb0=[]
    for nm in range(len(MiCvD)):
        Orb0.append(c.rect(Orb_r,Tcode[nm]))
    Orbv=num.array(Orb0)
    Orbh=num.repeat(MiAh[n],61)
    #断面1計算
    MiAvD10=[]
    for nm in range(len(MiAvC)):
        MiAvD10.append(c.rect(MiAv[nm],Tcode[0]))
    MiAvD1=num.array(MiAvD10) 
    MiBvD10=[]
    for nm in range(len(MiBx)):
        MiBvD10.append(c.rect(MiBx[nm],Tcode[0]))
    MiBvD1=num.array(MiBvD10)
    MiCvD10=[]
    for nm in range(len(MiHz)):
        MiCvD10.append(c.rect(2,Tcode[0]))
    MiCvD1=num.array(MiCvD10)  
    #円柱描画
    ax.plot(s2.real,s2.imag,z0,color="gray",lw=0.5)
    ax.plot(s3.real,s3.imag,z0,color="gray",lw=0.5)
    #単位円描画
    ax.plot(uc.real,uc.imag,uz1,color="blue",lw=1)
    #中心線描画
    ax.plot([0,0],[0,0],[-1,1],color="black",lw=1)
    #分割原点
    ax.plot([0,MiCvD1[0].real],[0,MiCvD1[0].imag],[-1,-1],color="green",lw=1)
    ax.plot([0,uc[0].real],[0,uc[0].imag],[0,0],color="blue",lw=1)
    ax.plot([uc[0].real,MiCvD1[0].real],[uc[0].imag,MiCvD1[0].imag],[0,0],color="green",lw=1)
    ax.plot([uc[0].real,uc[0].real],[uc[0].imag,uc[0].imag],[-1,1],color="green",lw=1)    
    ax.plot([uc[0].real,MiAvD1[0].real],[uc[0].imag,MiAvD1[0].imag],[0,MiAh[0]],color="green",lw=1)
    ax.plot([0,MiCvD1[0].real],[0,MiCvD1[0].imag],[1,1],color="green",lw=1)
    ax.plot([MiCvD1[0].real,MiCvD1[0].real],[MiCvD1[0].imag,MiCvD1[0].imag],[-1,1],color="green",lw=1)
    ax.plot(MiAvD1.real,MiAvD1.imag,MiAh,color="green",lw=1)
    ax.plot(MiBvD1.real,MiBvD1.imag,MiHz,color="blue",lw=1)
    #アニメーション描画
    ax.plot([0,MiCvD[n].real],[0,MiCvD[n].imag],[-1,-1],color="black",lw=1)
    ax.plot([0,uc[n].real],[0,uc[n].imag],[0,0],color="blue",lw=1)
    ax.plot([uc[n].real,MiCvD[n].real],[uc[n].imag,MiCvD[n].imag],[0,0],color="black",lw=1)
    ax.plot([uc[n].real,uc[n].real],[uc[n].imag,uc[n].imag],[-1,1],color="black",lw=1)    
    ax.plot([uc[n].real,MiAvD[n].real],[uc[n].imag,MiAvD[n].imag],[0,MiAh[n]],color="red",lw=1)
    ax.plot([0,MiCvD[n].real],[0,MiCvD[n].imag],[1,1],color="black",lw=1)
    ax.plot([MiCvD[n].real,MiCvD[n].real],[MiCvD[n].imag,MiCvD[n].imag],[-1,1],color="black",lw=1)
    ax.plot(MiAvD.real,MiAvD.imag,MiAh,color="red",lw=1)
    ax.plot(MiBvD.real,MiBvD.imag,MiHz,color="blue",lw=1)
    #軌跡描画
    ax.plot(Orbv.real,Orbv.imag,Orbh,color="red",lw=1)
    #諸元追加
    ax.set_ylim([-2.1,2.1])
    ax.set_xlim([-2.1,2.1])
    ax.set_zlim([-2.1,2.1])
    ax.set_title("Unit Cylinder")
    ax.set_xlabel("Real")
    ax.set_ylabel("Imaginal")
    ax.set_zlabel("Cycle")
    # グラフを回転
    ax.view_init(elev=25, azim=45)

Tcode=num.linspace(0,m.pi*2,61,endpoint =True)
#Time_code0=num.arange(0,360,6) 
#Time_code=Time_code0[::-1] 
#unit_cylinder(15)
#plt.show()

ani = animation.FuncAnimation(fig, unit_cylinder, interval=50,frames=len(Time_code))
ani.save("output620.gif", writer="pillow")
```

「単位トーラス」は意外と身近な形で「実在する」。コンピューターRPGで良く見掛ける「北極側と南極側、東端と南端が連続する世界地図」がそれ。「実在する」とはいえ、現実の物理空間に顕現させるのは難しい？
[RPG世界の形状についての幾何学的考察と可視化](http://nhayashi.main.jp/RPGgeom/indexRPG.html)