C++で2D平面上の点から直線への垂線の足を求める方法
2次元平面上に点 P と直線の方程式が与えられているとき、点 P からその直線へ下ろした垂線の足(交点)の座標を求めるのが本記事のテーマです。幾何学やコンピュータグラフィックスの分野でよく使われる基本的な計算なので、数式的な背景と合わせてC++での実装方法を解説します。
数学的な背景
直線の方程式は ax + by + c = 0 と表されます。点 P を通ってこの直線に垂直な直線の方程式は、ay − bx + d = 0 の形になります。ここで、点 P の座標を (x₁, y₁)、垂線の足となる点を Q(x₂, y₂) とします。
点 P の座標を垂直な直線の方程式に代入すると、ay₁ − bx₁ + d = 0 となるため、d = bx₁ − ay₁ が導かれます。
さらに、Q は「与えられた直線」と「点 P を通る垂線」の交点にあたるため、次の2つの連立方程式を解けばよいことになります。
ax + by + c = 0 および ay − bx + (bx₁ − ay₁) = 0
a、b、c、d がすべて既知であれば、次の公式を使って垂線の足の座標を直接計算できます。
$$\frac{x-x_{1}}{a}=\frac{y-y_{1}}{b}=\frac{-(ax_{1}+by_{1}+c)}{a^{2}+b^{2}}$$
C++での実装例
それでは、上記の公式をC++のコードに実装してみましょう。
#include<iostream>
using namespace std;
// 点(x1, y1)から直線 ax + by + c = 0 へ下ろした垂線の足を求める
void getFootCoordinate(double a, double b, double c, double x1, double y1) {
// 公式の共通の値を計算
double p = -1 * (a * x1 + b * y1 + c) / (a * a + b * b);
// 垂線の足の座標を算出
double x = p * a + x1;
double y = p * b + y1;
cout << "(" << x << ", " << y << ")";
}
int main() {
// 直線: 0・x + 1・y - 2 = 0(つまり y = 2)
double a = 0.0;
double b = 1.0;
double c = -2;
// 点 P(3, 3)
double x1 = 3.0;
double y1 = 3.0;
cout << "The coordinate is: ";
getFootCoordinate(a, b, c, x1, y1);
}
出力結果
The coordinate is: (3, 2)
コードの解説
関数 getFootCoordinate では、まず p = −(a·x₁ + b·y₁ + c) / (a² + b²) を計算しています。これは先ほどの公式における共通の値に相当します。その後、x = p·a + x₁、y = p·b + y₁ とすることで、垂線の足の座標を簡単に求められます。
このサンプルでは、直線を y − 2 = 0(水平線 y = 2)、点を P(3, 3) としています。点 P から直線へ垂直に下ろすと、x座標は変わらず y座標が 2 になるため、答えは (3, 2) となり、プログラムの出力と一致します。
このアルゴリズムの計算量は O(1) であり、係数 a、b が両方ゼロにならない限り、任意の直線と点の組み合わせに対して正しく動作します。幾何計算ライブラリや当たり判定など、さまざまな場面で応用できる便利な手法です。
-
C++で2次元平面上の点の鏡像(鏡映点)を求める方法
この記事では、2次元平面上の点Pと、直線の方程式 ax + by + c = 0 の係数 a・b・c が与えられたときに、この直線を鏡とした点Pの鏡像(鏡映点)をC++で求める方法を解説します。 問題を理解するための例 入力 P = (2, 1), a = 1, b = -1, c = 0 出力 (1, 2) 説明 与えられる直線は y = x です。この直線を鏡として点 (2, 1) を反射すると、x座標とy座標が入れ替わった位置 (1, 2) が鏡像となります。平面の様子は下図の通りです。 解法アプローチ この問題を解くには、鏡像となる点P(x, y) の座標を求める必要があり
-
C++で線分の中点を求める方法とサンプルコード
本記事では、C++を使って線分の中点(ミッドポイント)を求めるプログラムの作成方法を解説します。線分の始点Aと終点Bの2つの座標が与えられたとき、その中点を計算するアルゴリズムについて学びましょう。 問題の概要 始点A(x1, y1)と終点B(x2, y2)で構成される線分があります。この線分の中点を求めるのが課題です。 入力例 a(x1, y1) = (4, -5) b(x2, y2) = (-2, 6) 出力例 (1, 0.5) 計算の説明 (x1 + x2)/2 = (4 + (-2)) / 2 = 1 (y1 + y2)/2 = (-5 + 6) / 2 = 0.5 解決アプローチ:中