#include "Vector3f.h"
#include <cmath>
Vector3f::Vector3f(float x, float y, float z) {
this->x = x;
this->y = y;
this->z = z;
}
Vector3f Vector3f::crossProduct(const Vector3f &v) {
float nx = y * v.z - z * v.y; // y->z
float ny = z * v.x - x * v.z; // z->x
float nz = x * v.y - y * v.x; // x->y
return Vector3f(nx, ny, nz);
}
/**
* Given three points in the order counter-clockwise.
*/
Vector3f calculateNormal(const Point3f &p1, const Point3f &p2, const Point3f &p3) {
Vector3f vector1(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z);
Vector3f vector2(p3.x - p1.x, p3.y - p1.y, p3.z - p1.z);
return vector1.crossProduct(vector2);
}
Vector3f normalize(const Vector3f &v) {
float length = sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
if (length >= -0.001f && length <= 0.001f) {
return Vector3f(0.0f, 0.0f, 0.0f);
}
return Vector3f(v.x / length, v.y / length, v.z / length);
}
如果是给组成物体的每个小平面都指定一条法线的话, 最后使用光照后得到的物体表面是faceted jewel(像有小面的珠宝似的), 使得物体表面不是平滑的. 解决这个问题的办法是给每个顶点指点一条法线, 而不是给每个小平面指定法线: 先计算每个小平面的法线. 然后再用这些面的法线来计算顶点的法线:
共享有这个顶点的所有小平面的法线的平均值就是这个顶点的法线(近似).