ちょっと面白いものを見つけた。
cf. LEDドームのLEDの並びを決めるのに使用した計算式 – jakaladaのブログ
球面上に任意個の点を一様分布させる、座標を求めるもの。一般化螺旋集合(generalized spiral set)というものを使っている。元の資料(論文)はここ。
cf. 多数の点を球面上に一様分布させるソフトウェアGSS Generator
上のリンク先のブログでは Python を使っているので、Ruby でやってみた。
#!/usr/bin/env ruby
# encoding: utf-8
require 'gss'
require 'optparse'
require 'csv'
options = {}
opts = OptionParser.new
opts.banner = "Generate points with uniform distribution on the sphere."
opts.on("-c", "--cartesian", "Cartesian coordinate."){|v|
options[:cartesian] = true
}
opts.on_tail("-h", "--help", "Show this message."){|v|
print opts.help
exit
}
opts.on_tail("-v", "--version", "Show version."){|v|
puts "v#{GSS::VERSION}"
exit
}
opts.parse!
r = ARGV.shift.to_f
n = ARGV.shift.to_i
gss = GSS::GSS.new
points = gss.generate(r, n)
points.each do |p|
if options[:cartesian]
coord = p.to_cartesian
print coord.to_csv
else
print [p.r, p.theta, p.phi].to_csv
end
end
# encoding: utf-8
require "gss/polar_point"
module GSS
class GSS
def generate(r, n)
theta_1 = Math::PI
phi_1 = 0.0
points = []
points << PolarPoint.new(r, theta_1, phi_1)
2.upto(n) do |k|
h_k = -1.0 + 2.0 * (k - 1) / (n - 1)
theta_k = Math.acos(h_k)
phi_k = points.last.phi + 3.6 / Math.sqrt(n) * 1 / Math.sqrt(1 - h_k ** 2)
phi_k = phi_k.infinite? ? 0.0 : phi_k % (Math::PI * 2.0)
points << PolarPoint.new(r, theta_k, phi_k)
end
points
end
end # of class GSS
end # of module GSS
# encoding: utf-8
module GSS
class PolarPoint
attr_reader :r, :theta, :phi
def initialize(r, theta, phi)
@r = r
@theta = theta
@phi = phi
end
def to_cartesian
x = @r * Math.sin(@theta) * Math.cos(@phi)
y = @r * Math.sin(@theta) * Math.sin(@phi)
z = @r * Math.cos(@theta)
[x, y, z]
end
end # of class PolarPoint
end # of module GSS
最初のがコマンドで、あとの2つがライブラリ。引数に球の半径と配置したい点の個数を指定すると、各点の極座標を CSV 形式で出力する。
^o^ > ruby -Ilib exe/gss_gen 1.0 600
極座標じゃなく、デカルト座標(XYZ座標)がほしい時には --cartesian オプション。
^o^ > ruby -Ilib exe/gss_gen --cartesian 1.0 600
下の図は、発生させた600個の点のうち下半分の300個を XY 平面上に投影した図。
各点を順に線でつないでみると、螺旋になっているのがよくわかる。
……なんか螺旋が逆になってるな。元論文じゃ球面を下から見たと書いてあるからそのせいか?
ともあれ、それらしいのはできた。ただし、最初と最後の点の座標を調整するのはやってない。時間があったらやってみよう。


「多数の点を球面上に一様分布させる」への1件のフィードバック