幾何学幾何学
空間上の円; 3D Circle

概要
空間上の円は中心ベクトル\(\boldsymbol{v_c}\)と法線ベクトル\(\boldsymbol{v_n}\)と半径\(r\)で表現される。

円の面積\(S\)は以下で与えられる。
\(\quad \displaystyle S = \pi r^2 \)

内接円
3つのベクトル\(\boldsymbol{v_0}, \boldsymbol{v_1}, \boldsymbol{v_2} \)に内接する円の中心ベクトル\(\boldsymbol{v_c}\)と法線ベクトル\(\boldsymbol{v_n}\)と半径\(r\)は以下で与えられる。
ここで\(s\)は三角形\(\boldsymbol{v_0}, \boldsymbol{v_1}, \boldsymbol{v_2} \)の面積である。

\( \quad \displaystyle \boldsymbol{v_c} = \frac{|\boldsymbol{a}| \boldsymbol{v_2} + |\boldsymbol{b}| \boldsymbol{v_0} + |\boldsymbol{c}| \boldsymbol{v_1} }{ |\boldsymbol{a}| + |\boldsymbol{b}| + |\boldsymbol{c}| } \\ \quad \displaystyle \boldsymbol{v_n} = - \boldsymbol{a} \times \boldsymbol{c} \\ \quad \displaystyle r = \frac{2 s}{|\boldsymbol{a}| + |\boldsymbol{b}| + |\boldsymbol{c}|} \\ \quad \boldsymbol{a} = \boldsymbol{v_0} - \boldsymbol{v_1}, \quad \boldsymbol{b} = \boldsymbol{v_1} - \boldsymbol{v_2}, \quad \boldsymbol{c} = \boldsymbol{v_2} - \boldsymbol{v_0} \\ \)

外接円
3つのベクトル\(\boldsymbol{v_0}, \boldsymbol{v_1}, \boldsymbol{v_2} \)を通る円の中心ベクトル\(\boldsymbol{v_c}\)と法線ベクトル\(\boldsymbol{v_n}\)と半径\(r\)は以下で与えられる。

\( \quad \displaystyle \boldsymbol{v_c} = \frac{r_a \boldsymbol{v_2} + r_b \boldsymbol{v_0} + r_c \boldsymbol{v_1} }{ r_a + r_b + r_c } \\ \quad \displaystyle \boldsymbol{v_n} = - \boldsymbol{a} \times \boldsymbol{c} \\ \quad \displaystyle r = \frac{|\boldsymbol{a}| |\boldsymbol{b}| |\boldsymbol{c}|}{\sqrt{(|\boldsymbol{a}| + |\boldsymbol{b}| + |\boldsymbol{c}|)(-|\boldsymbol{a}| + |\boldsymbol{b}| + |\boldsymbol{c}|)(|\boldsymbol{a}| - |\boldsymbol{b}| + |\boldsymbol{c}|)(|\boldsymbol{a}| + |\boldsymbol{b}| - |\boldsymbol{c}|)}} \\ \quad \boldsymbol{a} = \boldsymbol{v_0} - \boldsymbol{v_1}, \quad \boldsymbol{b} = \boldsymbol{v_1} - \boldsymbol{v_2}, \quad \boldsymbol{c} = \boldsymbol{v_2} - \boldsymbol{v_0} \\ \quad r_a = |\boldsymbol{a}|^2 (|\boldsymbol{b}|^2+|\boldsymbol{c}|^2-|\boldsymbol{a}|^2), \quad r_b = |\boldsymbol{b}|^2 (|\boldsymbol{c}|^2+|\boldsymbol{a}|^2-|\boldsymbol{b}|^2), \quad r_a = |\boldsymbol{c}|^2 (|\boldsymbol{a}|^2+|\boldsymbol{b}|^2-|\boldsymbol{c}|^2) \)

ソースコード

namespace Geometry.Geometry3D {

    /// <summary>円</summary>
    public class Circle3D {
        Vector3D normal;

        /// <summary>コンストラクタ</summary>
        public Circle3D(Vector3D center, Vector3D normal, double radius) {
            this.Center = center;
            this.Normal = normal;
            this.Radius = radius;
        }

        /// <summary>コンストラクタ</summary>
        public Circle3D(Triangle3D triangle) {
            throw new InvalidProgramException();
        }

        /// <summary>中心</summary>
        public Vector3D Center { get; set; }

        /// <summary>法線</summary>
        public Vector3D Normal {
            get {
                return normal;
            }
            set {
                normal = value.Normal;
            }
        }

        /// <summary>半径</summary>
        public double Radius { get; set; }

        /// <summary>面積</summary>
        public double Area => Radius * Radius * Math.PI;

        /// <summary>外接円</summary>
        public static Circle3D Circum(Triangle3D triangle) {
            Vector3D a = triangle.V0 - triangle.V1, b = triangle.V1 - triangle.V2, c = triangle.V2 - triangle.V0;

            double a_sqnorm = a.SquareNorm, b_sqnorm = b.SquareNorm, c_sqnorm = c.SquareNorm;
            double a_norm = Math.Sqrt(a_sqnorm), b_norm = Math.Sqrt(b_sqnorm), c_norm = Math.Sqrt(c_sqnorm);

            double ra = a_sqnorm * (b_sqnorm + c_sqnorm - a_sqnorm);
            double rb = b_sqnorm * (c_sqnorm + a_sqnorm - b_sqnorm);
            double rc = c_sqnorm * (a_sqnorm + b_sqnorm - c_sqnorm);

            Vector3D center = (ra * triangle.V2 + rb * triangle.V0 + rc * triangle.V1) / (ra + rb + rc);
            Vector3D normal = -a * c;
            double radius = (a_norm * b_norm * c_norm) / Math.Sqrt((a_norm + b_norm + c_norm) * (-a_norm + b_norm + c_norm) * (a_norm - b_norm + c_norm) * (a_norm + b_norm - c_norm));

            return new Circle3D(center, normal, radius);
        }

        /// <summary>内接円</summary>
        public static Circle3D Incircle(Triangle3D triangle) {
            Vector3D a = triangle.V0 - triangle.V1, b = triangle.V1 - triangle.V2, c = triangle.V2 - triangle.V0;

            double a_norm = a.Norm, b_norm = b.Norm, c_norm = c.Norm, s = triangle.Area, sum_norm = a_norm + b_norm + c_norm;
            
            Vector3D center = (a_norm * triangle.V2 + b_norm * triangle.V0 + c_norm * triangle.V1) / sum_norm;
            Vector3D normal = -a * c;
            double radius = 2 * s / sum_norm;

            return new Circle3D(center, normal, radius);
        }

        /// <summary>不正な円</summary>
        public static Circle3D Invalid => new Circle3D(Vector3D.Invalid, Vector3D.Invalid, double.NaN);

        /// <summary>有効な円であるか判定</summary>
        public static bool IsValid(Circle3D circle) {
            return Vector3D.IsValid(circle.Center) && Vector3D.IsValid(circle.Normal) && !double.IsNaN(circle.Radius) &&  !double.IsInfinity(circle.Radius);
        }
    }
}

関連項目
空間ベクトル
空間上の同次変換行列
空間上の線分
空間上の直線
空間上の三角形
空間上の平面
空間上の球体
空間上の四面体
空間上の交差
四元数
空間上の円 単体テスト

ライブラリライブラリ
確率統計確率統計
線形代数線形代数
幾何学幾何学
最適化最適化
微分方程式微分方程式
画像処理画像処理
補間補間
機械学習機械学習
クラスタリングクラスタリング
パズルゲーム・パズル
未分類未分類