矢量数学

介绍

本教程是对线性代数的一个简短而实用的介绍,因为它适用于游戏开发。线性代数是研究向量及其应用的学科。矢量在二维和三维开发中有许多应用,Godot广泛使用它们。对矢量数学有一个良好的理解对于成为一个强大的游戏开发者是至关重要的。

注解

本教程是 not 关于线性代数的正式教科书。我们将只关注它是如何应用于游戏开发的。要更广泛地了解数学,请参阅https://www.khanacolademy.org/math/linear-algebra

坐标系(2d)

在二维空间中,坐标是使用水平轴定义的。 (x )和垂直轴 (y )二维空间中的特定位置被写成一对值,例如 (4, 3) .

../../_images/vector_axis1.png

注解

如果你对计算机图形学不太熟悉,那么肯定会觉得奇怪 y 轴点 向下 而不是像你在数学课上学到的那样向上。然而,这在大多数计算机图形应用中很常见。

二维平面上的任何位置都可以通过一对数字来识别。但是,我们也可以考虑 (4, 3) 作为 抵消(0, 0) 点,或 起源 . 绘制从原点指向点的箭头:

../../_images/vector_xy1.png

这是一个 矢量 . 矢量代表了许多有用的信息。同时告诉我们重点是 (4, 3) 我们也可以把它看作一个角度 θ 长度(或量级) m . 在这种情况下,箭头是 位置矢量 -它表示空间中相对于原点的位置。

关于向量的一个非常重要的考虑点是它们只表示 相对的 方向和大小。没有矢量位置的概念。以下两个矢量相同:

../../_images/vector_xy2.png

两个向量都表示一个点,右边是4个单位,在某个起点下面是3个单位。不管你在平面上哪里画向量,它总是代表一个相对的方向和大小。

向量运算

可以使用方法(x和y坐标或角度和幅度)来引用向量,但为了方便起见,程序员通常使用坐标表示法。例如,在godot中,原点是屏幕的左上角,因此要放置名为 Node2D 右侧400像素,下方300像素,使用以下代码:

$Node2D.position = Vector2(400, 300)
var node2D = (Node2D) GetNode("Node2D");
node2D.Position = new Vector2(400, 300);

Godot同时支持 Vector2Vector3 分别用于二维和三维。本文讨论的相同数学规则适用于这两种类型。

  • 成员访问

可以通过名称直接访问向量的各个组件。

# create a vector with coordinates (2, 5)
var a = Vector2(2, 5)
# create a vector and assign x and y manually
var b = Vector2()
b.x = 3
b.y = 1
// create a vector with coordinates (2, 5)
var a = new Vector2(2, 5);
// create a vector and assign x and y manually
var b = new Vector2();
b.x = 3;
b.y = 1;
  • 添加向量

添加或减去两个矢量时,将添加相应的组件:

var c = a + b  # (2, 5) + (3, 1) = (5, 6)
var c = a + b;  // (2, 5) + (3, 1) = (5, 6)

我们还可以通过在第一个向量的末尾添加第二个向量来直观地看到这一点:

../../_images/vector_add1.png

注意添加 a + b 结果与 b + a .

  • 标量乘法

注解

矢量代表方向和大小。一个只表示数量级的值称为 标量 .

向量可以乘以 标量

var c = a * 2  # (2, 5) * 2 = (4, 10)
var d = b / 3  # (3, 6) / 3 = (1, 2)
var c = a * 2;  // (2, 5) * 2 = (4, 10)
var d = b / 3;  // (3, 6) / 3 = (1, 2)
../../_images/vector_mult1.png

注解

将一个向量乘以一个标量并不会改变它的方向,只会改变它的大小。你就是这样 规模 矢量。

实际应用

让我们看看向量加减的两个常见用法。

  • 移动

矢量可以表示 any 具有大小和方向的量。典型的例子有:位置、速度、加速度和力。在这张图中,步骤1的宇宙飞船的位置矢量为 (1,3) 速度矢量为 (2,1) . 速度矢量表示船舶每一步的移动距离。我们可以通过将速度加到当前位置来找到步骤2的位置。

../../_images/vector_movement1.png

小技巧

速度测量 改变 按时间单位就位。新的位置是通过向上一个位置添加速度来找到的。

  • 指向目标

在这个场景中,你有一个坦克想要把它的炮塔指向一个机器人。从机器人的位置减去水箱的位置,就得到了从水箱指向机器人的向量。

../../_images/vector_subtract2.png

小技巧

找到一个指向 AB 使用 B - A .

单位向量

矢量 震级 属于 1 被称为 单位矢量 . 它们有时也被称为 方向向量法线 . 当你需要跟踪一个方向时,单位向量是有用的。

归一化

正火 矢量意味着将其长度减少到 1 同时保持它的方向。这是通过将每个分量除以其大小来实现的:

var a = Vector2(2, 4)
var m = sqrt(a.x*a.x + a.y*a.y)  # get magnitude "m" using the Pythagorean theorem
a.x /= m
a.y /= m
var a = new Vector2(2, 4);
var m = Mathf.Sqrt(a.x*a.x + a.y*a.y);  // get magnitude "m" using the Pythagorean theorem
a.x /= m;
a.y /= m;

因为这是一个很常见的操作, Vector2Vector3 提供规范化方法:

a = a.normalized()
a = a.Normalized();

警告

因为规范化涉及到除以向量的长度,所以不能规范化长度向量。 0 . 尝试这样做将导致错误。

反射

单位向量的常用用法是表示 法线 . 法向量是与曲面垂直对齐的单位向量,定义其方向。它们通常用于照明、碰撞和涉及表面的其他操作。

例如,假设我们有一个要从墙上或其他物体上弹回的移动球:

../../_images/vector_reflect1.png

曲面法向的值为 (0, -1) 因为这是一个水平面。当球碰撞时,我们采取它的剩余运动(当它撞击表面时剩余的量)并用法向反射。在Godot, Vector2 类有 bounce() 方法来处理此问题。下面是上面图表的gdscript示例,使用 KinematicBody2D

# object "collision" contains information about the collision
var collision = move_and_collide(velocity * delta)
if collision:
    var reflect = collision.remainder.bounce(collision.normal)
    velocity = velocity.bounce(collision.normal)
    move_and_collide(reflect)
// KinematicCollision2D contains information about the collision
KinematicCollision2D collision = MoveAndCollide(_velocity * delta);
if (collision != null)
{
    var reflect = collision.Remainder.Bounce(collision.Normal);
    _velocity = _velocity.Bounce(collision.Normal);
    MoveAndCollide(reflect);
}

DOT产品

这个 DOT产品 是矢量数学中最重要的概念之一,但常被误解。点积是对返回 标量 . 与既包含大小又包含方向的向量不同,标量值只有大小。

点积公式有两种常见形式:

System Message: WARNING/2 (a cdot b=左a 右左B 右cos theta)

latex exited with error [stdout] This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016/Debian) (preloaded format=latex) restricted \write18 enabled. entering extended mode (./math.tex LaTeX2e <2017/01/01> patch level 3 Babel <3.9r> and hyphenation patterns for 12 language(s) loaded. (/usr/share/texlive/texmf-dist/tex/latex/base/article.cls Document Class: article 2014/09/29 v1.4h Standard LaTeX document class (/usr/share/texlive/texmf-dist/tex/latex/base/size12.clo)) (/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty (/usr/share/texlive/texmf-dist/tex/latex/base/utf8.def (/usr/share/texlive/texmf-dist/tex/latex/base/t1enc.dfu) (/usr/share/texlive/texmf-dist/tex/latex/base/ot1enc.dfu) (/usr/share/texlive/texmf-dist/tex/latex/base/omsenc.dfu))) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty For additional information on amsmath, use the `?' option. (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty)) (/usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty)) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty) (/usr/share/texlive/texmf-dist/tex/latex/tools/bm.sty) No file math.aux. (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd) ! Package inputenc Error: Unicode char 左 (U+5DE6) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...dot b=左a 右左B 右cos theta\end{split} ! Package inputenc Error: Unicode char 右 (U+53F3) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...dot b=左a 右左B 右cos theta\end{split} ! Package inputenc Error: Unicode char 左 (U+5DE6) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...dot b=左a 右左B 右cos theta\end{split} ! Package inputenc Error: Unicode char 右 (U+53F3) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...dot b=左a 右左B 右cos theta\end{split} ! Package inputenc Error: Unicode char 左 (U+5DE6) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...dot b=左a 右左B 右cos theta\end{split} ! Package inputenc Error: Unicode char 右 (U+53F3) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...dot b=左a 右左B 右cos theta\end{split} ! Package inputenc Error: Unicode char 左 (U+5DE6) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...dot b=左a 右左B 右cos theta\end{split} ! Package inputenc Error: Unicode char 右 (U+53F3) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...dot b=左a 右左B 右cos theta\end{split} [1] (./math.aux) ) (see the transcript file for additional information) Output written on math.dvi (1 page, 304 bytes). Transcript written on math.log.

System Message: WARNING/2 (acdot b=a_x_b_x+a_y_b_y_)

latex exited with error [stdout] This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016/Debian) (preloaded format=latex) restricted \write18 enabled. entering extended mode (./math.tex LaTeX2e <2017/01/01> patch level 3 Babel <3.9r> and hyphenation patterns for 12 language(s) loaded. (/usr/share/texlive/texmf-dist/tex/latex/base/article.cls Document Class: article 2014/09/29 v1.4h Standard LaTeX document class (/usr/share/texlive/texmf-dist/tex/latex/base/size12.clo)) (/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty (/usr/share/texlive/texmf-dist/tex/latex/base/utf8.def (/usr/share/texlive/texmf-dist/tex/latex/base/t1enc.dfu) (/usr/share/texlive/texmf-dist/tex/latex/base/ot1enc.dfu) (/usr/share/texlive/texmf-dist/tex/latex/base/omsenc.dfu))) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty For additional information on amsmath, use the `?' option. (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty)) (/usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty)) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty) (/usr/share/texlive/texmf-dist/tex/latex/tools/bm.sty) (./math.aux) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd) ! Double subscript. <argument> \split@tag \begin {split}acdot b=a_x_ b_x+a_y_b_y_\end {split} l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Double subscript. <argument> \split@tag \begin {split}acdot b=a_x_b_ x+a_y_b_y_\end {split} l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Double subscript. <argument> ...g \begin {split}acdot b=a_x_b_x+a_y_ b_y_\end {split} l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Double subscript. <argument> ...\begin {split}acdot b=a_x_b_x+a_y_b_ y_\end {split} l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Double subscript. <argument> ...egin {split}acdot b=a_x_b_x+a_y_b_y_ \end {split} l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Missing { inserted. <to be read again> } l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Missing } inserted. <inserted text> } l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Double subscript. <argument> \split@tag \begin {split}acdot b=a_x_ b_x+a_y_b_y_\end {split} l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Double subscript. <argument> \split@tag \begin {split}acdot b=a_x_b_ x+a_y_b_y_\end {split} l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Double subscript. <argument> ...g \begin {split}acdot b=a_x_b_x+a_y_ b_y_\end {split} l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Double subscript. <argument> ...\begin {split}acdot b=a_x_b_x+a_y_b_ y_\end {split} l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Double subscript. <argument> ...egin {split}acdot b=a_x_b_x+a_y_b_y_ \end {split} l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Missing { inserted. <to be read again> } l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} ! Missing } inserted. <inserted text> } l.14 ...{split}acdot b=a_x_b_x+a_y_b_y_\end{split} [1] (./math.aux) ) (see the transcript file for additional information) Output written on math.dvi (1 page, 408 bytes). Transcript written on math.log.

但是,在大多数情况下,最容易使用内置方法。注意,这两个向量的顺序并不重要:

var c = a.dot(b)
var d = b.dot(a)  # these are equivalent
float c = a.Dot(b);
float d = b.Dot(a);  // these are equivalent

当与单位向量一起使用时,点积最有用,使第一个公式简化为 cosθ . 这意味着我们可以用点积来告诉我们两个向量之间的角度:

../../_images/vector_dot3.png

当使用单位向量时,结果总是介于 -1 (180°)和 1 (0°)。

外装

我们可以利用这个事实来检测一个物体是否朝向另一个物体。在下图中,玩家 P 试图避开僵尸 AB . 假设僵尸的视野是 180° ,他们能看到那个球员吗?

../../_images/vector_facing2.png

绿色箭头 fAfB单位向量 代表僵尸的朝向,蓝色半圆代表它的视野。对于僵尸 A ,我们找到方向向量 AP 使用指向播放器 P - A 并使其正常化。如果这个向量和对向向量之间的角度小于90°,那么僵尸可以看到玩家。

代码如下:

var AP = (P - A).normalized()
if AP.dot(fA) > 0:
    print("A sees P!")
var AP = (P - A).Normalized();
if (AP.Dot(fA) > 0)
{
    GD.Print("A sees P!");
}

交叉积

就像点产品一样, 交叉积 是对两个向量的运算。然而,交叉积的结果是一个方向与两者垂直的向量。它的大小取决于它们的相对角度。如果两个向量是平行的,则其交叉积的结果将是一个空向量。

System Message: WARNING/2 (左A 乘以B 右=左A 右左B 右sin(a,b)|)

latex exited with error [stdout] This is pdfTeX, Version 3.14159265-2.6-1.40.17 (TeX Live 2016/Debian) (preloaded format=latex) restricted \write18 enabled. entering extended mode (./math.tex LaTeX2e <2017/01/01> patch level 3 Babel <3.9r> and hyphenation patterns for 12 language(s) loaded. (/usr/share/texlive/texmf-dist/tex/latex/base/article.cls Document Class: article 2014/09/29 v1.4h Standard LaTeX document class (/usr/share/texlive/texmf-dist/tex/latex/base/size12.clo)) (/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty (/usr/share/texlive/texmf-dist/tex/latex/base/utf8.def (/usr/share/texlive/texmf-dist/tex/latex/base/t1enc.dfu) (/usr/share/texlive/texmf-dist/tex/latex/base/ot1enc.dfu) (/usr/share/texlive/texmf-dist/tex/latex/base/omsenc.dfu))) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsmath.sty For additional information on amsmath, use the `?' option. (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amstext.sty (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsgen.sty)) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsbsy.sty) (/usr/share/texlive/texmf-dist/tex/latex/amsmath/amsopn.sty)) (/usr/share/texlive/texmf-dist/tex/latex/amscls/amsthm.sty) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amssymb.sty (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/amsfonts.sty)) (/usr/share/texlive/texmf-dist/tex/latex/anyfontsize/anyfontsize.sty) (/usr/share/texlive/texmf-dist/tex/latex/tools/bm.sty) (./math.aux) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsa.fd) (/usr/share/texlive/texmf-dist/tex/latex/amsfonts/umsb.fd) ! Package inputenc Error: Unicode char 左 (U+5DE6) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 乘 (U+4E58) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 以 (U+4EE5) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 右 (U+53F3) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 左 (U+5DE6) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 右 (U+53F3) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 左 (U+5DE6) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 右 (U+53F3) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char ( (U+FF08) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char , (U+FF0C) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char ) (U+FF09) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 左 (U+5DE6) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 乘 (U+4E58) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 以 (U+4EE5) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 右 (U+53F3) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 左 (U+5DE6) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 右 (U+53F3) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 左 (U+5DE6) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char 右 (U+53F3) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char ( (U+FF08) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char , (U+FF0C) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} ! Package inputenc Error: Unicode char ) (U+FF09) (inputenc) not set up for use with LaTeX. See the inputenc package documentation for explanation. Type H <return> for immediate help. ... l.14 ...左A 右左B 右sin(a,b)|\end{split} [1] (./math.aux) ) (see the transcript file for additional information) Output written on math.dvi (1 page, 348 bytes). Transcript written on math.log.

../../_images/tutovec16.png

交叉积的计算方法如下:

var c = Vector3()
c.x = (a.y * b.z) - (a.z * b.y)
c.y = (a.z * b.x) - (a.x * b.z)
c.z = (a.x * b.y) - (a.y * b.x)
var c = new Vector3();
c.x = (a.y * b.z) - (a.z * b.y);
c.y = (a.z * b.x) - (a.x * b.z);
c.z = (a.x * b.y) - (a.y * b.x);

使用godot,您可以使用内置方法:

var c = a.cross(b)
var c = a.Cross(b);

注解

在叉积中,顺序很重要。 a.cross(b) 结果与 b.cross(a) . 结果向量指向 相反的 方向。

计算法线

交叉积的一个常用用法是在三维空间中求平面或曲面的曲面法向。如果我们有三角形 ABC 我们可以用向量减法求两条边 ABAC . 使用叉积, AB x AC 生成一个垂直于两者的向量:曲面法向。

下面是一个计算三角形法向的函数:

func get_triangle_normal(a, b, c):
    # find the surface normal given 3 vertices
    var side1 = b - a
    var side2 = c - a
    var normal = side1.cross(side2)
    return normal
Vector3 GetTriangleNormal(Vector3 a, Vector3 b, Vector3 c)
{
    // find the surface normal given 3 vertices
    var side1 = b - a;
    var side2 = c - a;
    var normal = side1.Cross(side2);
    return normal;
}

指向目标

在上面的点积部分,我们看到了如何使用它来找到两个向量之间的角度。然而,在3D中,这是不够的信息。我们还需要知道旋转的轴是什么。我们可以通过计算当前面向方向和目标方向的叉积来发现这一点。由此产生的垂直矢量是旋转轴。

更多信息

有关在Godot中使用矢量数学的更多信息,请参阅以下文章: