いろいろならせんを描く
5種類のらせんを描画します。Θとrを用いた極座標平面で以下の式で表されます。
(1) アルキメデスのらせん(等間隔)
(2) 放物らせん(外側に行くほど間隔が狭くなる)
(3) 双曲らせん(y=aを漸近線に持つらせん)
(4) リチュース(Θが大きくなるにつれ原点に近づくらせん)
(5) 対数らせん(等角螺旋)
以上の式を用いてΘを変えた際のrを求め、以下式によりΘとrの極座標からx,yの平面座標への変換します。
ただし描画に用いているopencvの座標系は画面の下向きがyが正、画面の上向きがyが負で平面座標のyと符号が逆なため、上記式で求めたyに-1を掛けています。 求めた座標にopencvのcv2.circleで円を描いて図形を描画します。
環境
(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)
実行結果
(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)
実行結果
(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)
実行結果
(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)
実行結果
(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)
実行結果
以下のサイトを参考にさせていただきました
代数螺旋フリー百科事典『ウィキペディア(Wikipedia)』
数C いろいろな曲線の確認
Pythonの文法メモ >> 【OpenCV】円を描画するcircle