Pythonでいろいろやってみる

Pythonを使った画像処理や機械学習などの簡単なプログラムを載せています。

いろいろならせんを描く

5種類のらせんを描画します。Θとrを用いた極座標平面で以下の式で表されます。

(1) アルキメデスのらせん(等間隔)

(2) 放物らせん(外側に行くほど間隔が狭くなる)

(3) 双曲らせん(y=aを漸近線に持つらせん)

(4) リチュース(Θが大きくなるにつれ原点に近づくらせん)

(5) 対数らせん(等角螺旋)

以上の式を用いてΘを変えた際のrを求め、以下式によりΘとrの極座標からx,yの平面座標への変換します。

ただし描画に用いているopencvの座標系は画面の下向きがyが正、画面の上向きがyが負で平面座標のyと符号が逆なため、上記式で求めたyに-1を掛けています。 求めた座標にopencvのcv2.circleで円を描いて図形を描画します。

環境

  • windows10 home
  • Anaconda 3/ jupyter notebook 5.6.0
  • Python 3.7.0
  • opencv 4.0.0
(1) アルキメデスのらせん(等間隔)
コード
import math
import cv2
import numpy as np

width, height = 500, 500
img = np.zeros((height, width, 3), np.uint8)

# アルキメデスらせん
a = 4
for i in range(5000):
    theta = i/100  # Θ
    r = a * theta
    x = int(r * math.cos(theta) + width/2)
    y = int(-r * math.sin(theta) + height/2)
    cv2.circle(img, (x, y), 3, (0, 125, 255), -1)
cv2.imwrite('spiral_a.png', img)
実行結果

f:id:T_A_T:20200713092606p:plain

(2) 放物らせん(外側に行くほど間隔が狭くなる)
コード
import math
import cv2
import numpy as np

width, height = 500, 500
img = np.zeros((height, width, 3), np.uint8)

# 放物らせん
a = 30
for i in range(5000):
    theta = i/100  # Θ
    r = a * math.sqrt(theta)
    x = int(r * math.cos(theta) + width/2)
    y = int(-r * math.sin(theta) + height/2)
    cv2.circle(img, (x, y), 3, (0, 125, 255), -1)
cv2.imwrite('spiral_p1.png', img)
実行結果

f:id:T_A_T:20200713092550p:plain

(3) 双曲らせん(y=aを漸近線に持つらせん)
コード
import math
import cv2
import numpy as np

width, height = 500, 500
img = np.zeros((height, width, 3), np.uint8)

# 双曲らせん
a = 250
for i in range(1, 5000):
    theta = i/100  # Θ
    r = a / theta
    x = int(r * math.cos(theta) + width/2)
    y = int(-r * math.sin(theta) + height/2)
    cv2.circle(img, (x, y), 3, (0, 125, 255), -1)
cv2.imwrite('spiral_p2.png', img)
実行結果

f:id:T_A_T:20200713092532p:plain

(4) リチュース(Θが大きくなるにつれ原点に近づくらせん)
コード
import math
import cv2
import numpy as np

width, height = 500, 500
img = np.zeros((height, width, 3), np.uint8)

# リチュース
a = 100
for i in range(1, 5000):
    theta = i/100  # Θ
    r = a / math.sqrt(theta)
    x = int(r * math.cos(theta) + width/2)
    y = int(-r * math.sin(theta) + height/2)
    cv2.circle(img, (x, y), 3, (0, 125, 255), -1)
cv2.imwrite('spiral_p3.png', img)
実行結果

f:id:T_A_T:20200713092513p:plain

(5) 対数らせん(等角螺旋)
コード
import math
import cv2
import numpy as np

width, height = 500, 500
img = np.zeros((height, width, 3), np.uint8)

# 対数らせん
a = 0.05
b = 0.2
for i in range(5000):
    theta = i/100  # Θ
    r = a * math.exp(b * theta)
    x = int(r * math.cos(theta) + width/2)
    y = int(-r * math.sin(theta) + height/2)
    cv2.circle(img, (x, y), 3, (0, 125, 255), -1)
cv2.imwrite('spiral_e.png', img)
実行結果

f:id:T_A_T:20200713092449p:plain

以下のサイトを参考にさせていただきました

代数螺旋フリー百科事典『ウィキペディア(Wikipedia)』
数C いろいろな曲線の確認
Pythonの文法メモ >> 【OpenCV】円を描画するcircle

ブログランキングに参加しています

にほんブログ村 IT技術ブログへ
にほんブログ村