投稿者 魔界の仮面弁士  (社会人) 投稿日時 2023/10/5 02:17:53
>> 高校数学Bの『ベクトル』
失礼しました。現在の学習指導要領までは確認していなかったのですが、検索してみたところ、
どうやら平成30年改訂にて、数学B から数学C に移行したという話が見つかりました。
『行列』の単元なども、年度や学校によってはまったく習わないことがあると聞いて驚いてます…。


> System.Windows.Vector の使い方がPoint型とあまりに似すぎて同じ印象という認識です。
その認識で OK です。
それぞれをどう扱うかはプログラマ次第ですし、現時点では必ずしも厳密にとらえる必要は無いでしょう。
実際のところ、Vector3 構造体を 3 次元座標情報として使用するケースもありますし、
その逆に Point 構造体を座標としてではなく、移動量として用いる場合もあります。

下記は C# ではなく C におけるコンソールアプリなブロック崩しですが、
このぐらいであれば、int だけでも十分に管理できますね。

int ballX, ballY が、スカラ値であるボール座標情報、
int ballVelocityX, ballVelocityY が、ベクトル値であるボール移動量情報。
https://youtu.be/1dfOCNQyYqg?t=840


> やはり座標以外の役割を持った値・・・変位だとかの値を表しているのでしょうか?
それでは、座標値と変位値が別の概念であることを示すため、変位の実装例を挙げてみましょうか。

var p = new System.Windows.Point(100d, 200d); は、「X = 100, Y = 200」の座標として使うことができます。
var v = new System.Windows.Vector(100d, -173d); なら、「右向きに 30 の大きさ、上向きに -173 の大きさ」と言えます。

単純な等速直接運動を考えた場合、この二つを組み合わせることで、
(100, 200) の座標にあったボールを右上方向約 60°の角度で移動させる様子を表すことができます。
この時のボールの移動速度は、約 200 ですね。…… Math.Sqrt(v.X * v.X + v.Y * v.Y)

移動後のボール座標を得たい場合、単に var o = p + v; とするだけで、
座標値 new Point(200d, 27d) が得られます。
これが可能な理由は Point + Vector や Vector + Point の演算を、Point 型の結果で得られるよう、
これらの型で「+ 演算子」がオーバーロードされているためです。
ちなみに、Point - Point の演算では、2 点間の変位量を Vector 型で得ることができます。

ただし、これが Point + Point という演算になるとコンパイルエラーとなります。
概念的に、座標同士の加算という行為には意味が無いため、Point 型同士の加算はできないからですね。。
(🗼東京タワーの緯度経度と、🗽自由の女神の緯度経度を足し合わせる…なんてことは無意味なわけで)

とはいえVector 型を使わなかったとしても、たとえば
Point p1; を座標値、Point p2; を変位値として扱うことにすれば、上記と同様の演算を
 Point p0 = p1.Offset(p1.X, p2.Y);
などという代用コードで済ますことが可能ではあります。
Offset メソッドは、System.Windows.Point にも System.Drawing.Point にも存在します。


> System.Windows.Vector は、C#においてどのような具体的な使い方をするのでしょうか?
WinForms で主要な名前空間は、System.Windows.Forms 名前空間と、System.Drawing 名前空間です。
.NET で使う場合は <UseWindowsForms>true</UseWindowsForms>、.NET Framework では System.Drawing.dll アセンブリ。
System.Drawing 名前空間は、主に「GDI+」系のグラフィック処理で使われます。

WPF における主要な名前空間としては、System.Windows 名前空間と System.Windows.Media 名前空間があります。
.NET では <UseWPF>true</UseWPF> ですね。.NET Framework では WindowBase.dll アセンブリ。


ということで、System.Windows.Vector は本来は WPF 向けであり、
通常は、WinForms からはさほど使われていなかったりします。


> System.Windows.Point 構造体 と
> System.Drawing.Point 構造体 では、何が違うんでしょうか?
ターゲットとしている UI 層が異なるだけで、機能的にはほぼ同じです。
名前空間ごとに似たようなクラスや構造体があるので、ややこしいですよね…。


System.Windows.Point 構造体は通常、WPF にて使われます。それに対して、
WinForms での座標では一般的に、GDI+ 用である System.Drawing.Point / PointF 構造体が使われます。
この他には Windows API で使われる、GDI 用の POINT 構造体などもあります。
https://learn.microsoft.com/ja-jp/windows/win32/api/windef/ns-windef-point


具体例としては:

WPF における MouseLeftButtonDown イベントの e.GetPosition メソッドで
得られる Point 型は System.Winodows.Point 構造体です。

WinForms における MouseClick イベントの e.Location プロパティで
得られる Point 型は、System.Drawing.Point 構造体です。

Win32 API の GetCursorPos 関数で得られる座標情報は POINT 構造体です。



その他の名前空間として、.NET では「System.Numerics 名前空間」が良く使われます。
(NuGet にある System.Numerics.Vectors によって提供されます)
こちらは比較的汎用的な実装になっているので、要件によっては使いやすいかも知れません。

この名前空間には、float なベクトル管理のための Vector2, Vector3, Vector4 構造体や、
行列演算のための System.Numerics.Matrix3x2 や System.Numerics.Matrix4x4 があります。
クォータニオン(3次元の物理回転)のための System.Numerics.Quaternion 構造体や
ジェネリックな Vector<T> 構造体もあります


この他、特定 CPU の専用命令を使って高速処理されるために用意された
「System.Runtime.Intrinsics 名前空間」の下にも、並列処理に向いた
Vector64<T>, Vector128<T>, Vector256<T> 構造体といったものが用意されています。


行列演算については、WPF なら一応 System.Windows.Media.Matrix 構造体などもありますし、
GDI+ 版なら、System.Drawing.Drawing2d.Matrix があります。
https://learn.microsoft.com/ja-jp/dotnet/api/system.drawing.drawing2d.matrix
https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/graphics-multimedia/how-to-transform-points-and-vectors

行列演算は、色変換などでも使われますね。GDI+ の ColorMatrix クラスとか。
https://dobon.net/vb/dotnet/graphics/saturation.html
https://dobon.net/vb/dotnet/graphics/colorbalance.html