LoginSignup
0
0

More than 1 year has passed since last update.

[UE4]指定した座標に一番近い、直線上の座標を求める(ベクトルの投影)

Last updated at Posted at 2021-04-09

【概要】

タイトルの通り、指定した座標に一番近い、直線上の座標を求めます。
今回は例として、下の画像のようにコーンから伸びる青い線上の、スフィアの座標に一番近い座標(赤い点の座標)を求めます。
尚、直線はただの方向ベクトルとして扱うので、終点は考慮していません。

※2021/05/21追記
相対座標への変換などを行わなくても、UKismetMathLibrary::FindClosestPointOnLineで同じ結果が得られるようです。

gif.gif
環境はUE4.24を使用しています。

【実装】

先に実装をお見せすると、以下のような形になります。
ProjectVectorOnToVectorのノードを使うことにより、座標を線に投影することが出来ます。
引数のVにはコーンから見たスフィアの相対座標、TargetにはコーンのUpVector(尖っている方向)のベクトルを与えています。
ReturnValueは原点基準の座標になっているので、コーンの座標に足して最終的な座標としています。
image.png

【解説】

折角なのでProjectVectorOnToVectorの中身でやっていることを含め、見ていきたいと思います。

まず現状のActorの配置を図に表すと以下のようになります。
原点:ワールドの原点
A:コーンの座標
A':コーンの座標にコーンのUpVectorを足した座標
B:スフィアの座標
P:求めたい座標
image.png

このままだと計算し辛いので、コーンの座標を原点とします。
image.png

点に一番近い直線上の座標を求めるには、正射影ベクトルの公式を使用します。
https://examist.jp/mathematics/planar-vector/seisyaei-vector/

この公式に今回の例を当てはめると以下のようになります。

\vec{AP} = \vec{AA'}*((\vec{AA'}・\vec{AB})/(|\vec{AA'}|*|\vec{AA'}|))\\

ベクトルの内積は各成分同士を掛けて全部足すことで求められるので、以下のようになります。

\vec{AP} = (1,0)*(((1*3)+(0*2)/(1*1))\\
=(3,0)

これでPの座標が(3,0)であることが分かりました。
最後に、原点基準で計算していたので、元の座標系に戻す為にコーンの座標を足して、最終的な座標は(6,3)になりました。

以上が実装のところでお見せしたBlueprintの詳細になります。
実際にProjectVectorOnToVectorの中を見ると、同じように正射影ベクトルの公式を使用していることが分かると思います。

Vector.h
FORCEINLINE FVector FVector::ProjectOnTo(const FVector& A) const 
{ 
    return (A * ((*this | A) / (A | A))); 
}

割る値が公式のように|→a|の2乗ではないですが、同じベクトルの内積は大きさの2乗とイコールなので、同じ意味になります。
https://kou.benesse.co.jp/nigate/math/a13m1502.html

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0