一个向量由一个坐标系和一个大小组成,这个大小相当于它的长度,向量很多时候用来表示两个点之间,从第一个个顶点到第二点之间的位移,一系列从原点出发的向量可以用来表示坐标系,然后用来表示其他的顶点或者坐标。
在maya中,所有的向量都是3维的,三个坐标值被命名为xyz。有一件很重要的事,你得理解尽管砸许多书上书上的向量会在坐标中某个位置被表示出来,但是向量是没有位置的。
向量表示一个相对位移的偏移量,对于位置而言,向量在用于表示位置的时候无法脱离点,向量可以加在一个点以得到一个新的点,但是向量绝不会用来单独表示一个位置。
有时向量会直接被想象成从原点出发的一个箭头,这有助于理解向量并不是一个位置而是更类似一个方向。想象所有的向量都是围绕着原点创建的,这样他们的旋转以及翻转等操作会变得更加直观。
3.1MEL
一个向量可以使用vector数据类型表示,mel并没有在顶点和向量之间加以区分,顶点可以使用的操作向量也可以使用。
3.2 c++ api
C++中顶点和向量的使用是有区别的,类似顶点用MPoint类表示,向量用MVector类,他们使用之前提到的数学规则,MVector类由三个值,xy和z。所有的值都都是双精度浮点类型,同样的也有使用单精度浮点值作为数据类型的类——MFloatVector。通常用下面这种方式来表示0向量:
MVectorvec ;//x = y = z = 0
尽管maya 在数学上区分了顶点和向量,但是MPoint和MVector类可以相互转化:
MPointpt;
MVectorvec;
pt= vec;
vec= pt ;
同样的MFloatPoint和MFloatVector也可以分别转化为 MPoint和MVector。要注意的是,当MPonit转化为MVector时,maya默认这个顶点处于笛卡尔坐标系。如果不处于笛卡尔坐标系,可以向下面的例子一样在操作之前使用cartesianize函数。为了方便起见,先声明几个MVector的实例,
MVector :: zero //vector(0,0,0)
MVector :: xAxis //vector(1,0,0)
MVector :: yAxis //vector(0,1,0)
MVector :: zAxis //vector(0,0,1)
MVector :: xNegAxis //vector(-1,0,0)
MVector :: yNegAxis //vector(0,-1,0)
MVector :: zNegAxis //vector(0,0,-1)
它们可以像其他类一样使用,比如下面这样:
MVector v0;
If(v0 == MVector :: xAxis)
MGlobal::displayInfo(“vectoris the same as the x axis”);
3.3 向量加法
如图3.1所示,a和b两个向量相加会得到一个新的向量c。虚线表示了另外一种理解向量相加的方式。把每个向量分别头尾相连,最后的到的向量就是相加的结果。
对于两个向量的加法,只需要将每个坐标分别相加,最后将得到一个新的坐标
它遵循以下的运算法则:
a+b = b+a 加法交换律
a+(b+c) = (a+b)+c 加法结合律
a+0 = a 加法恒等
a+(-a) = 0 加法逆运算
3.4 向量减法
如图3.2所示,a向量减去b向量,将会得到一个新的向量c
C = a + b
虚线展示了一种更加直观的理解方法。减法可以想象成和加法类似的首尾相连得到一个新的向量,不过第二个向量是反过来的,你可以理解为:
C = a +(-b)
减法满足以下的法则:
A – b ≠b – a 不可交换性
A – (b-c)≠(a-b) -c 不可结合性
A -0 = a 减法恒等
3.5 缩放
一个向量的长度可以通过等比例缩放而改变。向量a可以通过用缩放系数s乘以每一个坐标值来进行等比缩放
B = sa
图3.3展示了把a向量缩放2倍和-1倍的结果。其中,缩放-1倍相当于把坐标反向,如图,-1倍的结果和a反向相反
向量的缩放遵循以下的规律:
(st)a = s(ta) 结合律
(s+t)a = sa +ta 分配率
S(a+b) = sa +sb 分配率
1a = a 乘法恒等
3.6长度
计算向量的长度一般会像图3.4这样使用勾股定律,图中三角形为直角三角形。
C向量三角形中最长的边——三角形的斜边。同时他也是2维向量(a,b)的长度,在直角三角形中的c可以以下面的勾股定律求得:
两边开方:
我们会用双竖线||表示向量的长度
这和单竖线|是不同,一般而言,单竖线用来表示绝对矢量。a和b的值可以用向量的x和y坐标值癌替代,即:
对于三维向量而言,它的长度就是:
这同样适合n维向量。所有的坐标值平方之后求和,最后开方的结果就是这个n维向量的长度。
3.6.1 Mel
向量:
计算向量的长度,可以使用mag命令语句
vector $v
float$length = mag($v);
如果要计算2d向量的长度,可以使用hypot语句
vector $v = <<2.4,4.6,0.0>>;
float $length = hypot($v.x , $v.y);
print $length; //Print 5.188449
浮点数组:
如果将向量作为一个浮点数组进行计算,可以用下面这种方法计算长度
proc float len( float $v[])
{
return sqrt($v[0]*$v[0] + $v[1]*$[1] + $v[2]*$v[2]);
}
然后像下面这样来使用这个方法:
float $v[] = [2.4,4.6,7.3];
float $length = len($v);
print $length; //Print 5.188449
3.6.2 C++ API
可以使用length函数直接获取向量的长度:
MVector v ;
double len = v.length();
3.7 两顶点间的距离
两顶点之间的欧几里得距离就是两顶点之间向量的长度(译:欧几里得度量(euclidean metric)(也称欧氏距离)是一个通常采用的距离定义,指在m维空间中两个点之间的真实距离,或者向量的自然长度(即该点到原点的距离)。在二维和三维空间中的欧氏距离就是两点之间的实际距离。选自百度百科),给定两个顶点p0和p1,那么他们两者间的距离就是
另外一种有用的距离是曼哈顿距离。
3.7.1 MEL
向量
用下面的例子对两点之间的距离进行计算。
vector $p0 = <<1,0,0>>;
vecctor $p1 = <<2,0,0>>;
vector $v = $p0 - $p1;
float $len = mag($v);
浮点数组
计算两顶点之间的距离可以让两个顶点相减,然后使用len方法(见前面的章节)来求得顶点之间的距离。
3.7.2 C++ API
两顶点之间的距离可以使用MPoint’s中的distance函数:
MPoint p0(1.0,0.0,0.0);
MPoint p1(2.0,0.0,0.0);
double distance = p0.distanceTo(p1);
3.8向量标准化
当向量的长度为单位1的时候,我们称之为单位矢量,要把任意一个向量转化成单位矢量,就需要使用标准化,像下面这样
把每个坐标值除以向量的模,这个向量的长度就会变成单位1。单位向量通过带“帽子”(^)来表示。三维向量就像下面这样计算:
长度为1的向量也被称之为标准化向量。这可能会造成一些混淆,normal(主要是区别normalzing和normal)对于向量是另外一个意思。标准化(normalzing)仅仅只是表示把一个向量的长度缩放成1。
3.8.1 MEL
向量:
要想把一个向量标准化,可以使用unit命令:
vector $v = <<2.4,4.6,7.3>>;
float $len = mag($v);
print $len; //Prints 8.9560041
$v = unit($v);
$len = mag($v);
print $len; //Prints 1.0
浮点数组:
如果你使用浮点数组作为向量表示方法,可以使用normalize命令
float $v[] = {2.4,4.6,7.3};
float $len = normalize($v);
print $len;
3.8.2 C++API
想要标准化向量,可以调用normalize函数。他可以直接返回一个标准化的向量。
MVector v;
v.normalize();
如果想要得到一个向量的标准化向量,并把它赋予一个新的向量,可以使用normal函数。这会赋值一个函数并标准化它。0向量是不会由任何改变的
MVector v;
MVector norm = v.normal();