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

Hun*_*der 30 normalizing vector

试图更多地理解向量.

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

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

当你标准化它时你实际得到了什么 - 我得到你必须划分x/| N |的想法 Y/| N | &z/| N |.我的问题是,为什么我们这样做,我的意思是我们从这个等式中得到什么?

这样做的意义或'内部'目的是什么.

有点数学问题,我道歉,但我真的不清楚这个话题.

Jay*_*iya 48

对于任何向量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
Run Code Online (Sandbox Code Playgroud)

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

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

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

事实证明,要在3D空间中定义矢量,我们需要一些参考方向.这些参考方向被规范地称为i,j,k(或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 - nope,对于你所有的OCD怪胎,我不会把Pi放在那里 - 这将保持终止小数,只因为我是邪恶的化身).你不会想要陷入一个讨厌的方向,对吗?我的意思是说,我想要面向西方的4公斤西瓜真的有意义吗?当然,除非你是一个疯狂的狂热分子.

其他时候,只有方向很重要.你只是不关心幅度,或者幅度太大而无法理解(像无限的东西,只有没有人真正知道无穷大是什么 - 所有冰雹无穷无尽,因为他有无限的无限...对不起,有点被带走了).在这种情况下,我们使用向量的归一化.例如,它没有任何意义,说我们有一条面向北4公里的线.说我们有一条面向北方的线更有意义.那么你做什么呢?你摆脱了4公里.你破坏了规模.剩下的就是北方(冬天来了).经常这样做,你必须给你的名字和符号.你不能只称它为"无视大小".那太粗鲁了.你是一名数学家,所以你把它称为"规范化",你给它带有"上限"的符号(可能是因为你想参加一个派对而不是被卡住了).

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

  • 这是一个很好的解释。事实上,我一直喜欢这类问题,因为它会产生这种答案,而且这里的一些人总是自己解释这些行话,而不解释其为何被称为“为什么”。我是开发人员,经常被行话所困扰(我根本不在乎),但有时在某些时候,它们命名的原因对我来说比它的作用更重要。例如(Espresso 单元测试中的预期方法与预期方法)和(反应式中的映射方法与 flatMap 方法)。 (3认同)
  • 非常有帮助.提供关于正常化重要性的清晰图景. (2认同)
  • 比接受的答案要好得多. (2认同)

Ade*_*lin 27

阅读关于单位向量,规范化和点积的戈多游戏引擎 文档确实很有意义.这是文章:

单位向量

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

在此输入图像描述

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

迫不及待想要了解更多关于单位向量的奇妙属性,但一步一步.那么,如何从常规向量创建单位向量?

正常化

采用任何矢量并将其幅度减小到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
Run Code Online (Sandbox Code Playgroud)

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

当然,Vector2和Vector3已经提供了一种方法:

a = a.normalized()
Run Code Online (Sandbox Code Playgroud)

点产品

好的,点积是矢量数学中最重要的部分.如果没有dot产品,Quake将永远不会被制造出来.这是本教程中最重要的部分,因此请务必正确掌握.大多数试图理解矢量数学的人都放弃了,因为尽管它有多么简单,但它们无法从中做出正面或反面.为什么?这就是为什么,这是因为...

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

var s = a.x*b.x + a.y*b.y
Run Code Online (Sandbox Code Playgroud)

是的,几乎就是这样.将x从矢量a乘以x从矢量b乘以.对y执行相同操作并将其添加到一起.在3D中它几乎是一样的:

var s = a.x*b.x + a.y*b.y + a.z*b.z
Run Code Online (Sandbox Code Playgroud)

我知道,这完全没有意义!您甚至可以使用内置函数执行此操作:

var s = a.dot(b)
Run Code Online (Sandbox Code Playgroud)

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

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

在此输入图像描述

而且你意识到是时候放弃制作3D游戏或复杂的2D游戏了.如此简单的事情如何变得如此复杂?其他人将不得不制作下一个塞尔达或使命召唤.自上而下的RPG看起来并不那么糟糕.是的,我听说有人在Steam上与其中一个人做过相当的意愿......

所以这是你的时刻,这是你发光的时候.不要放弃!在这一点上,本教程将急转直下,重点关注点积有用的原因.这就是它有用的原因.我们将逐一关注点积的用例,以及实际应用.没有更多没有任何意义的公式.一旦你了解了它们的用途,公式就会有意义.

Siding dot产品的第一个有用且最重要的属性是检查正在查看的内容.让我们假设我们有两个向量,a和b.任何方向或幅度(均不是原点).无论它们是什么,但我们假设我们计算它们之间的点积.

var s = a.dot(b)
Run Code Online (Sandbox Code Playgroud)

该操作将返回一个浮点数(但因为我们是在矢量的世界里,我们称之为标量,使用期限将继续从现在起).这个号码会告诉我们以下内容:

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

在此输入图像描述

因此,让我们考虑一个真实的用例场景.想象一下Snake正在穿过森林,然后附近有一个敌人.我们怎样才能快速判断敌人是否已经看到了Snake?为了发现他,敌人必须能够看到Snake.那么说吧那就是:

蛇处于A位置.敌人处于B位置.敌人面向方向向量F.

在此输入图像描述

所以,让我们创建一个新的向量BA,从守卫(B)到Snake(A),减去两个:

var BA = A - B
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

理想情况下,如果护卫员直视蛇,要进行目光接触,它会在与矢量BA相同的方向上进行.

如果F和BA之间的点积大于0,则会发现Snake.发生这种情况是因为我们能够告诉警卫面向他:

if (BA.dot(F) > 0):
    print("!")
Run Code Online (Sandbox Code Playgroud)

看来Snake到目前为止是安全的.

用单位向量支持好吧,现在我们知道两个向量之间的点积将让我们知道它们是朝向同一侧,相对侧还是彼此垂直.

这与所有向量的工作方式相同,无论大小如此,单位向量都不例外.但是,使用与单位向量相同的属性会产生更有趣的结果,因为添加了额外的属性:

如果两个向量面向完全相同的方向(彼此平行,它们之间的角度为0°),则得到的标量为1.如果两个向量面向完全相反的方向(彼此平行,但它们之间的角度)是180°),得到的标量是-1.这意味着单位矢量之间的点积总是在1和-1之间.再说......

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

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

在此输入图像描述

在绘制由此产生的标量时!

在此输入图像描述

啊哈!这一切都有意义,这是余弦功能!

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

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

var angle_in_radians = acos( a.dot(b) )
Run Code Online (Sandbox Code Playgroud)

这对什么有用?直接获得角度可能不那么有用,但只是能够告诉角度对于参考是有用的.一个例子是在运动学角色演示中,当角色沿某个方向移动然后我们击中一个物体.如何判断我们打的是什么?

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

这样做的好处在于,相同的代码完全相同,并且不需要在3D中进行修改.矢量数学在很大程度上与维度量无关,因此添加或删除轴只会增加非常小的复杂性.

  • 这是一篇非常好的文章。我认为他们已经编辑并删除了其中的许多部分。 (2认同)
  • 您可以在这里查看文章:https://docs.godotengine.org/en/2.1/learning/features/math/vector_math.html (2认同)

Sir*_*Guy 10

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

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

一旦你开始在线性代数中玩够矩阵,你就会想要正交向量。例子太多了,无法一一列举。

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

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

  • @StanlyMoses 可以根据两个分量来考虑向量 - 方向和幅度。通过将向量除以其幅度,我们只保留方向分量并丢弃幅度。例如,&lt;1,1&gt; 和 &lt;2,2&gt; 变成等价的。这对于许多操作(例如投影)很有用。 (6认同)
  • 规范化的优点是什么? (2认同)