53

试图更多地理解向量。

对向量进行归一化需要什么?

如果我有一个向量,N = (x, y, z)

当你规范化它时你实际上得到了什么 - 我明白你必须除以 x/|N| 是/|N| &z/|N|。我的问题是,我们为什么要做这件事,我的意思是我们从这个等式中得到什么?

这样做的意义或“内部”目的是什么。

有点数学问题,我很抱歉,但我真的不清楚这个话题。

4

6 回答 6

86

对于任何向量V = (x, y, z)|V| = sqrt(x*x + y*y + z*z)给出向量的长度。

当我们对一个向量进行归一化时,我们实际上计算V/|V| = (x/|V|, y/|V|, z/|V|).

很容易看出,归一化向量的长度为 1。这是因为:

| V/|V| | = sqrt((x/|V|)*(x/|V|) + (y/|V|)*(y/|V|) + (z/|V|)*(z/|V|))
          = sqrt(x*x + y*y + z*z) / |V|
          = |V| / |V|
          = 1

因此,我们可以将归一化向量称为单位向量(即具有单位长度的向量)。

任何向量,当归一化时,只会改变它的大小,而不是它的方向。此外,指向同一方向的每个向量都被归一化为同一向量(因为幅度和方向唯一地定义了一个向量)。因此,单位向量对于提供方向非常有用。

但是请注意,上述所有讨论都是针对 3 维笛卡尔坐标(x, y, z)的。但笛卡尔坐标的真正含义是什么?

事实证明,要在 3D 空间中定义一个向量,我们需要一些参考方向。这些参考方向被规范地称为ijk(或 i、 j 、 k 上面有小大写字母 - 称为“i cap”、“j cap”和“k cap”)。我们认为的任何向量V = (x, y, z)实际上都可以写为V = xi + yj + zk。(注意:我不再用大写字母来称呼它们,我只会称它们为 i、j、k)。i、j 和 k 是 X、Y 和 Z 方向上的单位向量,它们形成一组相互正交的单位向量。它们是所有笛卡尔坐标几何的基础。

还有其他形式的坐标(例如圆柱坐标和球坐标),虽然它们的坐标不像 那样直接理解(x, y, z),但它们也是由一组 3 个相互正交的单位向量组成,这些单位向量构成了 3 个坐标相乘的基础产生一个向量。

所以,上面的讨论清楚地表明我们需要单位向量来定义其他向量,但你为什么要关心呢?

因为有时,只有量级很重要。那是当您使用“常规”数字时(例如 4 或 1/3 或 3.141592653 - 不,对于所有强迫症怪胎,我不会把 Pi 放在那里 - 这将保持一个终止小数,因为我是邪恶的化身)。你不想扔到一个讨厌的方向,是吗?我的意思是,说我要4公斤西瓜面向西方真的有意义吗?当然,除非你是一些疯狂的狂热分子。

其他时候,只有方向很重要。你只是不在乎量级,或者量级太大而无法理解(有点像无限,只是没有人真正知道无限到底是什么——万岁伟大的无限,因为他有无限的无限......对不起,有点忘乎所以)。在这种情况下,我们使用向量的归一化。例如,说我们有一条面向北 4 公里的线没有任何意义。说我们有一条面向北方的线更有意义。那你怎么办?你摆脱了4公里。你破坏了规模。你所剩下的就是北方(冬天来了)。经常这样做,你将不得不给你正在做的事情一个名字和符号。您不能只称其为“忽略大小”。那太粗鲁了。你是数学家

顺便说一句,因为我提到了笛卡尔坐标,所以这里是强制性的 XKCD:XKCD

于 2015-07-11T18:17:42.350 回答
54

阅读有关单位向量、归一化和点积的Godot 游戏引擎 文档确实很有意义。这是这篇文章:

单位向量

好的,所以我们知道什么是向量。它有方向和幅度。我们也知道如何在 Godot 中使用它们。下一步是学习单位向量。任何长度为 1 的向量都被视为单位向量。在 2D 中,想象绘制一个半径为 1 的圆。该圆包含所有存在的二维单位向量:

在此处输入图像描述

那么,单位向量有什么特别之处呢?单位向量是惊人的。换句话说,单位向量有几个非常有用的属性。

迫不及待地想了解更多关于单位向量奇妙特性的信息,但一步一步来。那么,如何从正则向量创建单位向量呢?

正常化

取任何向量并在保持其方向的同时将其幅度减小到 1.0 称为归一化。归一化是通过将向量的 x 和 y(以及 3D 中的 z)分量除以其大小来执行的:

var a = Vector2(2,4)
var m = sqrt(a.x*a.x + a.y*a.y)
a.x /= m
a.y /= m

正如您可能已经猜到的那样,如果向量的大小为 0(这意味着它不是向量,而是原点也称为零向量),则会发生除以零,并且宇宙会经历第二次大爆炸,除了极性相反然后返回. 结果,人类是安全的,但 Godot 会打印一个错误。记住!Vector(0,0) 无法归一化!

当然,Vector2 和 Vector3 已经提供了一种方法来做到这一点:

a = a.normalized()

点积

好的,点积是向量数学中最重要的部分。如果没有点积,Quake 就不会被制作出来。这是本教程中最重要的部分,因此请务必正确掌握。大多数试图理解向量数学的人在这里放弃了,因为尽管它很简单,但他们无法从中得出正面或反面。为什么?这就是为什么,这是因为...

点积采用两个向量并返回一个标量:

var s = a.x*b.x + a.y*b.y

是的,差不多就是这样。将向量 a 中的 x 乘以向量 b 中的 x。对 y 执行相同操作并将其相加。在 3D 中几乎相同:

var s = a.x*b.x + a.y*b.y + a.z*b.z

我知道,这完全没有意义!你甚至可以使用内置函数来做到这一点:

var s = a.dot(b)

两个向量的顺序无关紧要,a.dot(b)返回与 相同的值b.dot(a)

这就是绝望开始的地方,书籍和教程向您展示了这个公式:

A ⋅ B = ∥A∥ ∥B∥ cos(θ)

你意识到是时候放弃制作 3D 游戏或复杂的 2D 游戏了。这么简单的事情怎么会这么复杂?其他人将不得不制作下一个塞尔达或使命召唤。毕竟,自上而下的 RPG 看起来并没有那么糟糕。是的,我听说有人对 Steam 上的其中一个做了很好的决定...

所以这是你的时刻,这是你发光的时刻。不放弃!在这一点上,本教程将急转直下,重点关注点积的有用之处。这就是为什么它有用。我们将一一关注点积的用例,以及现实生活中的应用。没有更多没有任何意义的公式。一旦你了解了它们的用途,公式就会变得有意义。

侧板 点积的第一个有用且最重要的属性是检查侧边的内容。假设我们有任意两个向量,a 和 b。任何方向或大小(无原点)。不管它们是什么,但让我们假设我们计算它们之间的点积。

var s = a.dot(b)

该操作将返回一个浮点数(但由于我们处于向量世界中,我们称它们为标量,从现在开始将继续使用该术语)。这个数字将告诉我们以下信息:

如果数字大于零,则两者都朝向同一方向(它们之间的角度小于 90°)。如果数字小于零,则两者都朝相反的方向看(它们之间的角度> 90°)。如果数字为零,则向量的形状为 L(它们之间的角度为 90°)。

在此处输入图像描述

因此,让我们考虑一个真实的用例场景。想象 Snake 正在穿过一片森林,然后附近有一个敌人。我们如何快速判断敌人是否看到发现了 Snake?为了发现他,敌人必须能够看到 Snake。让我们说,然后:

Snake 在位置 A。敌人在位置 B。敌人面向方向向量 F。

在此处输入图像描述

因此,让我们创建一个从守卫 (B) 到 Snake (A) 的新向量 BA,方法是将两者相减:

var BA = A - B

在此处输入图像描述

理想情况下,如果守卫直视蛇,为了进行眼神交流,它会在与向量 BA 相同的方向上进行。

如果 F 和 BA 之间的点积大于 0,那么就会发现 Snake。发生这种情况是因为我们将能够判断守卫面向他:

if (BA.dot(F) > 0):
    print("!")

到目前为止,Snake 似乎是安全的。

与单位向量对齐 好的,所以现在我们知道两个向量之间的点积将让我们知道它们是朝向同一侧、相反侧还是彼此垂直。

无论大小如何,这对所有向量都适用,因此单位向量也不例外。但是,将相同的属性与单位向量一起使用会产生更有趣的结果,因为添加了一个额外的属性:

如果两个向量都面向完全相同的方向(彼此平行,它们之间的角度为 0°),则结果标量为 1。如果两个向量都面向完全相同的方向(彼此平行,但它们之间的角度)为 180°),得到的标量为 -1。这意味着单位向量之间的点积总是在 1 到 -1 的范围内。所以又...

如果它们的角度为0°,点积为1。如果它们的角度为90°,则点积为0。如果它们的角度为180°,则点积为-1。呃……这奇怪的熟悉……以前见过……在哪里?

让我们取两个单位向量。第一个是向上的,第二个也是,但是我们将它从上(0°)一直旋转到下(180°)......

在此处输入图像描述

在绘制结果标量时!

在此处输入图像描述

啊哈!现在一切都说得通了,这是一个余弦函数!

我们可以这样说,那么,作为一项规则......

两个单位向量之间的点积是这两个向量之间夹角的余弦值。因此,要获得两个向量之间的角度,我们必须这样做:

var angle_in_radians = acos( a.dot(b) )

这有什么用?那么直接获得角度可能没有那么有用,但是能够分辨出角度是有用的参考。一个例子是在运动学角色演示中,当角色向某个方向移动时,我们会撞到一个物体。如何判断我们击中的是不是地板?

通过将碰撞点的法线与先前计算的角度进行比较。

这样做的美妙之处在于,相同的代码在 3D 中的工作方式完全相同且无需修改。矢量数学在很大程度上与维度数量无关,因此添加或删除轴只会增加很少的复杂性。

于 2017-07-31T08:20:48.210 回答
10

这有点像问我们为什么要乘以数字。它总是出现。

我们使用的笛卡尔坐标系是正交基(由相互正交的长度为 1 的向量组成,基意味着任何向量都可以由这些向量的唯一组合表示),当您要旋转基时(当您环顾四周时,会出现在视频游戏机制中)您使用行和列是正交向量的矩阵。

一旦你开始在线性代数中使用矩阵,你就会需要正交向量。例子太多了,不一一列举。

归根结底,我们不需要归一化向量(就像我们不需要汉堡包一样,我们可以没有它们,但谁会去呢?),但类似的模式v / |v|经常出现,以至于人们决定给它一个名字和一个特殊的符号(向量上的 ^ 表示它是一个标准化向量)作为快捷方式。

归一化向量(也称为单位向量)基本上是生活中的事实。

于 2012-04-03T23:49:30.857 回答
1

您将其长度设为 1 - 找到指向同一方向的单位向量。

这对于各种目的很有用,例如,如果您将向量与单位向量进行点积,则您将获得该向量在单位向量方向上的分量的长度。

于 2012-04-03T23:29:50.147 回答
1

法线应该仅用作方向向量。它们用于照明计算,这需要归一化的法线向量。

于 2012-04-03T23:54:15.797 回答
0

我看到帖子很老了,但我仍然想回答它,因为我没有看到明确的答案,为什么我们要规范化。向量归一化的原因是要找到向量的确切大小以及它在另一个向量上的投影。

示例=向量 a 在 b 上的投影是 b.cos(theta)

在此处输入图像描述

但在点积的情况下,两个向量 a 和 b 的点积是 abcos(theta)

这意味着点积是 a 超过 b 乘以 a 的投影。因此,我们将它除以 a 以归一化以找到投影的确切长度,即 (b.cos(theta))。希望很清楚。

于 2020-05-25T05:43:27.153 回答