我需要一个Point和一个Vector对象吗?还是仅使用Vector对象表示一个点就可以了?


18

在构造与朋友一起开发的引擎组件时(出于学习目的),我对此产生了疑问。

最初,我们有一个Point构造函数,如下所示:

var Point = function( x, y ) {
    this.x = x;
    this.y = y;
};

但是他们开始向其中添加一些Vector数学,他们决定将其重命名为Vector2d。

但是现在,有些方法(至少在我看来)有点令人困惑,例如下面的方法,这些方法用来做一行:

//before the renaming of Point to Vector2, the parameters were startingPoint and endingPoint
Geometry.Line = function( startingVector, endingVector ) {
    //...
};

我应该为Point对象创建特定的构造函数,还是将点定义为向量没有问题?

我知道矢量具有大小和方向,但是我看到很多人使用矢量来表示对象的位置。


1
由于位置仅仅是(0,0 {,0})的向量,因此可以使用向量。

Answers:


8

合并定义并将点视为向量不太可能出现任何问题-但要小心一点,因为某些API可能需要使用“ Point”类(用于表示例如多边形的顶点),并且您定义自己的课程,便希望能够来回移植它们。

我怎么做,虽然是在你的代码等同对待他们; 如果确实使用矢量和点可互换,则没有必要为Line()函数的声明谈论“ startingVector”和“ endingVector”。我强烈建议您回到

Geometry.Line = function( Vector startingPoint, Vector endingPoint ) {
    //...
};

点是这些参数表示的内容,即使它们使用Vector类也是如此。


我将更进一步,并typedef Vector Point在定义点的标头中的某处。这样,它的外观和感觉就像一个Point,使用它的原因没有人挠头,Vector但在内部方面,它只是一个代码库。
tpg2114

4

只需使用Vector对象。即使您觉得过去曾经/曾经错误地使用过,这也是人们的期望。另外,将向量用作点不一定是不正确的。由于这两个数据结构都需要相同的原始类型,因此很难在讨论之外进行。唯一的区别是成员函数,将它们放在同一个类中很容易,因为两者之间的方法冲突并不多。

由于您正在学习,因此最好了解做人期望的事情通常是做事的最佳方法(对于像所提出的那样琐碎的选择)。


成员函数不是点和向量之间的唯一区别;所以是w部件,这一点非常重要。
kevintodisco,2012年

3

点是空间中的位置。一旦有了坐标系,就可以将这些点描述为距原点(矢量)的距离和方向。因此,使用向量描述直线的起点和终点是完全合理的。

请注意,所有点都可以表示为向量,但是向量不是点。大多数矢量,例如速度,法线等,都没有任何位置感。

想想风,您可以谈论它的方向和强度,但不能谈论它的位置或位置。当向量不用于描述空间中的点时,这就是您应该怎么想的。


2

要定义一个点,只需一个向量。要定义一条线,您需要两个。通常,您有两个点位于直线上,或者一个矢量代表一个直线上的点,另一个矢量代表直线的方向。

将点定义为向量没有问题,因为点是方向等于其坐标且大小等于其与0,0的距离的向量。

因此,虽然一个点可能是Vector2d的子类,而其成员函数直接与您的绘图或处理直接相关,但是您可能不需要两个单独的类来表示Point和“ Vector2d”,而Vector2d可能仅执行严格的矢量数学函数,例如点产品。


2

是的,可以使用单个Vector类来定义点和向量,只要确保w向量的成分是即可0

点和向量之间的主要区别在于,点表示空间中的物理位置,偏离原点,而向量表示方向。的一个点可以被翻译,载体不能。的w2-维或3维的分量Vector类是允许的变换矩阵生效的平移分量。如果w1,则将应用平移和旋转;否则为。如果为0,则仅应用旋转。

没有w向量集的成分0会再次咬你。它会导致难以跟踪的错误。为了安全起见,您可以创建一个Point从该类继承Vector并明确设置w1Vector类,其中该类默认w0


2
许多向量类没有显式使用w组件;相当多的人将其视为隐式元素或具有相当于实现它的'ProjectiveVector'类的内容,但是引擎的大部分代码(本质上是外部渲染的所有内容)都使用了带有w组件的“经典” 3-vector完全多余。这是实现细节,不是向量点的必要部分。
史蒂文·斯塔德尼基

@StevenStadnicki是的,但是要使一个类既代表点又代表向量,w必须存在组件,否则无法确定应如何使用该对象。
kevintodisco,2012年

1
@ktodisco我认为确定应如何使用的方法是查看正在使用的上下文。
JCM 2012年

1
冉的时间来编辑评论:(要说的是,如果发动机的其中使用类的部分定义其将要使用的上下文,那么它的工作原理。
kevintodisco

2

点和向量可以被认为是同一件事。如果对您有意义,则可以考虑以这种方式表示位置的向量,然后Vector2在其他所有使用类的地方使用类是合乎逻辑的Point

在数学中,向量有时用于表示位置。当以这种方式使用时,矢量表示相对于起点的某个实体所在的位置。例如,假设您要进行嘘声,并且想要跟踪玩家的飞船在游戏区域中的位置。如果将游戏区域的左下角视为(0,0),则可以用表示玩家的位置Vector

   * Player (3,3)
  /
 /
. (0,0)

在这种情况下,矢量的意思是船在原点的右边3单位在原点上方3单位。(请注意,您还可以使用矢量作为播放器的速度,在这种情况下,播放器将向右或每隔一帧或每帧移动3个单位。位置和速度都将由相同的矢量类表示,但是它们的矢量将在播放器的脚本中进行不同的处理。)

以您的线示例为例,位置矢量表示相对于原点的起点“点”和终点“点”的位置。如果您的原点是比赛区域的中心,则可以确定一条线,如下所示:

             * (8, 2)
             |
     . (0,0) |
             |
             * (8, -2)

因此,该线的一端是比赛场地右侧的8个单位,位于比赛场地中心上方2个单位,另一端是右侧8个单位,向下2个单位。

只是要清楚一点,这并不是说您必须使用一个Vector类而不是一个Point类。这只是思考这种情况的一种方法,可以使您更轻松地决定如何实施这些想法。


仍然必须将向量作为空间中另一个点的偏移量考虑为相对坐标中的一个点。就游戏引擎而言,将其称为向量是错误的。
kevintodisco,2012年

0

这取决于实现方式。如果必须在Vector2d上使用方法而不是其原型,那么考虑到您在游戏中需要的得分数量(主要是得分),这样做会产生成本。这就是JavaScript的工作方式。在这种情况下,最好创建一个没有所有不必要功能的Point2d类。


这些方法已添加到原型中,因此这不是问题。
JCM 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.