不要忘记你的数学
在开始3d图形编程之前,让我们一步步谈论三角数学和矢量
,
嘿,不要打瞌睡,我很严肃,你要使用三角函数定义和矢量数
学处理3d图形
三角函数和直角三角形
大量的3d 图形问题可以被直角三角形解决,直角三角形有
一个角是90度,解决一个直角,或计算全部的边长和另两个
角度,你需要知道至少两个信息:两个边或一个边,一个角度
你可能熟悉这个表达式:a2+b2=c2. 这个表达式叫毕达哥
拉斯订立,a,b,c是直角三角形的边,斜边也就是直角的对边
是c, 这个表达式告诉确定这两个边长就可以知道第3个边
长.
可是,如果你知道一个边和一个角,图7.1中的三角函数
定义将派上用场,正玄定义,余弦和正切告示了直角和角度
的关系,你能够解决各种类型的三角形的换算,
矢量数学
当开始制作3d 图形时,我们表示一个点坐标(x,y,z)
棘手的是,需要重要的理解关于这个坐标可以联系点的空间
和矢量,一个矢量包含大小和方向,象一个速度,和一个矢量
数学的基础,举例一个方向是东,距离是55英里,如果这个x
轴点东边,那么这个矢量 (55,0,0)可以被解释为向东55英
里,相同地,如果这个z轴向南那么这个矢量(0,0,55)
可以被解释为向南55英里.
在这本书中,你开始在3d vector,但是记住矢量并不限制
这3个尺寸,它可以有仅有两个尺寸或多于3个,本文中,我们
表示矢量是一个大写字母(而不是一个小写或实数)
而且,我们表示一个矢量元素的标识为
V=(Vx, Vy, Vz)
记住,一个矢量是描述了大小和方向,它不具有起点,它不在
乎起点是哪里,换句话说,距离路易斯安那斯向东55英里和
距离巴黎向东55英里是同样的矢量(除了巴黎,你可以使用
公里,如果有这样的想法)
现在让我们讨论矢量数学,首先,最基本的矢量可以叠加
,在图7.2中所示,矢量u和v的叠加是u+v,减u就是u-v,
矢量-u和-v表示大小于正矢量相同但是方向相反.
数学中,增加两个3d矢量是叠加他们的大小
u+v=U+V=(Ux+Vx, Uy+Vy, Uz+Vz)
例如,如果一个鸟从向东55英里飞行,逆风向西10英里推动,
那么鸟和风的矢量叠加是45英里,注意增加了两个矢量值在
一个新的不同大小的矢量,一个不同的方向,或都是,当然,
相减也是同样的,更进一步,你可以将矢量的大小相乘,不改
变其方向
s V=(s Vx, s Vy, s Vz)
因此,向东55英里乘2就是向东110英里
一个矢量的大小,或者长度,其长度可以用毕达哥拉斯定理
得立体版表达:
|V|=(Vx2+Vy2+Vz2)1/2
一个长度为1的矢量叫做单位矢量,或者归一矢量,你可以归
一矢量除它的长度,一个单位矢量的符号是个带帽子的U
Û=U/|U|
这里快速介绍了矢量数学,在本章的结尾我们介绍更多的矢
量内容,但是但目前为止我们学到的知识,要进一步创建一
个有用的矢量类---vectoe3D,我们之所以们使用float类型做更多的3d 计算,主要因为它比double类型花费更小,而且满足我们所需要的精度
Listing 7.1 Vector3D.java
package com.brackeen.javagamebook.math3D;
/**
The Vector3D class implements a 3D vector with the
floating-point values x, y, and z. Vectors can be thought of
either as a (x,y,z) point or as a vector from (0,0,0) to
(x,y,z).
*/
public class Vector3D implements Transformable {
public float x;
public float y;
public float z;
/**
Creates a new Vector3D at (0,0,0).
*/
public Vector3D() {
this(0,0,0);
}
/**
Creates a new Vector3D with the same values as the
specified Vector3D.
*/
public Vector3D(Vector3D v) {
this(v.x, v.y, v.z);
}
/**
Creates a new Vector3D with the specified (x, y, z) values.
*/
public Vector3D(float x, float y, float z) {
setTo(x, y, z);
}
/**
Checks if this Vector3D is equal to the specified Object.
They are equal only if the specified Object is a Vector3D
and the two Vector3D's x, y, and z coordinates are equal.
*/
public boolean equals(Object obj) {
Vector3D v = (Vector3D)obj;
return (v.x == x && v.y == y && v.z == z);
}
/**
Checks if this Vector3D is equal to the specified
x, y, and z coordinates.
*/
public boolean equals(float x, float y, float z) {
return (this.x == x && this.y == y && this.z == z);
}
/**
Sets the vector to the same values as the specified
Vector3D.
*/
public void setTo(Vector3D v) {
setTo(v.x, v.y, v.z);
}
/**
Sets this vector to the specified (x, y, z) values.
*/
public void setTo(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
/**
Adds the specified (x, y, z) values to this vector.
*/
public void add(float x, float y, float z) {
this.x+=x;
this.y+=y;
this.z+=z;
}
/**
Subtracts the specified (x, y, z) values to this vector.
*/
public void subtract(float x, float y, float z) {
add(-x, -y, -z);
}
/**
Adds the specified vector to this vector.
*/
public void add(Vector3D v) {
add(v.x, v.y, v.z);
}
/**
Subtracts the specified vector from this vector.
*/
public void subtract(Vector3D v) {
add(-v.x, -v.y, -v.z);
}
/**
Multiplies this vector by the specified value. The new
length of this vector will be length()*s.
*/
public void multiply(float s) {
x*=s;
y*=s;
z*=s;
}
/**
Divides this vector by the specified value. The new
length of this vector will be length()/s.
*/
public void divide(float s) {
x/=s;
y/=s;
z/=s;
}
/**
Returns the length of this vector as a float.
*/
public float length() {
return (float)Math.sqrt(x*x + y*y + z*z);
}
/**
Converts this Vector3D to a unit vector, or, in other
words, a vector of length 1. Same as calling
v.divide(v.length()).
*/
public void normalize() {
divide(length());
}
/**
Converts this Vector3D to a String representation.
*/
public String toString() {
return "(" + x + ", v + y + ", " + z + ")";
}
}
这里没有什么复杂的,vector3d有加减乘除,长度和单位矢量