🔘

二次元円上のランダムな座標を取得する方法

2024/07/30に公開

今回は下記のような2次元平面円形内のランダムな座標を取得する方法を紹介します。


https://w3e.kanazawa-it.ac.jp/math/category/kansuu/iroiro-kansu/henkan-tex.cgi?target=/math/category/kansuu/iroiro-kansu/ennohouteisiki.html&pcview=0

手順

前提として、円上の座標を取得するためには極座標を使います。

極座標の基礎知識

極座標は平面上の点の位置を表すのに便利な座標系です。以下に極座標の基本的な使い方を簡単に説明します:

  1. 極座標の構成要素:
    • 原点 (極)
    • 基準となる半直線 (極軸、通常はx軸の正の部分)
    • 距離 (r): 原点から点までの距離
    • 角度 (θ): 極軸から反時計回りに測った角度
  2. 点の表し方:
    • 極座標では点を (r, θ) と表します
    • 例: (3, π/4) は原点から距離3、角度45度の点を表します
  3. 変換:
    • 直交座標 (x, y) から極座標 (r, θ) への変換:
      • r = √(x² + y²)
      • θ = arctan(y/x)
    • 極座標 (r, θ) から直交座標 (x, y) への変換:
      • x = r cos(θ)
      • y = r sin(θ)
  4. 主な利点:
    • 円や螺旋などの曲線を簡単に表現できる
    • 回転対称な図形や現象の記述に適している
  1. ランダムな角度thetaを取得
  2. ランダムな距離rを取得
  3. 直交座標に変換

実装例

この手順に沿って実際に半径5の円上のランダム座標を取得するコードは以下です。

package main

import (
	"fmt"
	"math"
	"math/rand/v2"
)

func getRondomPointOnCircle(radius float64) (float64, float64) {
	theta := 2 * math.Pi * rand.Float64()   // ランダムな角度を取得
	r := radius * math.Sqrt(rand.Float64()) // ランダムな半径を取得
	x := r * math.Cos(theta)
	y := r * math.Sin(theta)
	return x, y
}

func main() {
	// 半径5の円上のランダムな座標を10個取得
	for i := 0; i < 10; i++ {
		x, y := getRondomPointOnCircle(5.0)
		fmt.Printf("(%f, %f)\n", x, y)
	}
}

ここでポイントなのは、rを取得するときに乱数をそのまま使うのではなく、平方根にしているところです。平方根を取らない場合、点は円の中心に近い部分に集中してしまいます。平方根を取ることで、円の全体にわたって均等に点が分布するようになります。

平方根をとる理由

  • 様分布の乱数:
    rand.Float64()は0から1の間の一様分布のfloat64型の乱数を生成します。これは、0から1の間のどの値も同じ確率で選ばれることを意味します。

  • 面積の関係:
    円の面積は半径の2乗に比例します。つまり、半径が大きくなるほど、面積は急速に増加します。

  • 乱数の直接使用:
    半径をそのまま使うと、円の外側の部分の面積が大きいため、外側に点が集中するように見えます。しかし、実際には一様分布の乱数をそのまま使うと、内側の小さな半径の部分に点が集中してしまいます。これは、内側の小さな半径の部分が相対的に小さい面積を持つためです。

まとめ

今回は2次元円形上のランダムな座標を取得する方法をまとめました。

少し数学的な表現が入ったため説明が難しかったですが、参考になれれば幸いです!

Discussion