📄 vector3.cpp
字号:
/**
@file Vector3.cpp
3D vector class
@maintainer Morgan McGuire, matrix@graphics3d.com
@cite Portions based on Dave Eberly's Magic Software Library at http://www.magic-software.com
@created 2001-06-02
@edited 2006-01-30
*/
#include <limits>
#include <stdlib.h>
#include "G3D/Vector3.h"
#include "G3D/g3dmath.h"
#include "G3D/format.h"
#include "G3D/stringutils.h"
#include "G3D/Vector3int16.h"
#include "G3D/Matrix3.h"
#include "G3D/Vector2.h"
namespace G3D {
Vector3 Vector3::dummy;
// Deprecated.
const Vector3 Vector3::ZERO(0, 0, 0);
const Vector3 Vector3::ZERO3(0, 0, 0);
const Vector3 Vector3::UNIT_X(1, 0, 0);
const Vector3 Vector3::UNIT_Y(0, 1, 0);
const Vector3 Vector3::UNIT_Z(0, 0, 1);
const Vector3 Vector3::INF3((float)G3D::inf(), (float)G3D::inf(), (float)G3D::inf());
const Vector3 Vector3::NAN3((float)G3D::nan(), (float)G3D::nan(), (float)G3D::nan());
Vector3::Vector3(const class Vector2& v, float _z) : x(v.x), y(v.y), z(_z) {
}
Vector3::Axis Vector3::primaryAxis() const {
Axis a = X_AXIS;
double nx = abs(x);
double ny = abs(y);
double nz = abs(z);
if (nx > ny) {
if (nx > nz) {
a = X_AXIS;
} else {
a = Z_AXIS;
}
} else {
if (ny > nz) {
a = Y_AXIS;
} else {
a = Z_AXIS;
}
}
return a;
}
size_t Vector3::hashCode() const {
size_t xhash = (*(size_t*)(void*)(&x));
size_t yhash = (*(size_t*)(void*)(&y));
size_t zhash = (*(size_t*)(void*)(&z));
return xhash + (yhash * 37) + (zhash * 101);
}
std::ostream& operator<<(std::ostream& os, const Vector3& v) {
return os << v.toString();
}
//----------------------------------------------------------------------------
double frand() {
return rand() / (double) RAND_MAX;
}
Vector3::Vector3(const class Vector3int16& v) {
x = v.x;
y = v.y;
z = v.z;
}
Vector3 Vector3::random() {
Vector3 result;
do {
result = Vector3(uniformRandom(-1.0, 1.0),
uniformRandom(-1.0, 1.0),
uniformRandom(-1.0, 1.0));
} while (result.squaredMagnitude() >= 1.0f);
result.unitize();
return result;
}
//----------------------------------------------------------------------------
Vector3 Vector3::operator/ (float fScalar) const {
Vector3 kQuot;
if ( fScalar != 0.0 ) {
float fInvScalar = 1.0f / fScalar;
kQuot.x = fInvScalar * x;
kQuot.y = fInvScalar * y;
kQuot.z = fInvScalar * z;
return kQuot;
} else {
return Vector3::inf();
}
}
//----------------------------------------------------------------------------
Vector3& Vector3::operator/= (float fScalar) {
if (fScalar != 0.0) {
float fInvScalar = 1.0f / fScalar;
x *= fInvScalar;
y *= fInvScalar;
z *= fInvScalar;
} else {
x = (float)G3D::inf();
y = (float)G3D::inf();
z = (float)G3D::inf();
}
return *this;
}
//----------------------------------------------------------------------------
float Vector3::unitize (float fTolerance) {
float fMagnitude = magnitude();
if (fMagnitude > fTolerance) {
float fInvMagnitude = 1.0f / fMagnitude;
x *= fInvMagnitude;
y *= fInvMagnitude;
z *= fInvMagnitude;
} else {
fMagnitude = 0.0f;
}
return fMagnitude;
}
//----------------------------------------------------------------------------
Vector3 Vector3::reflectAbout(const Vector3& normal) const {
Vector3 out;
Vector3 N = normal.direction();
// 2 * normal.dot(this) * normal - this
return N * 2 * this->dot(N) - *this;
}
//----------------------------------------------------------------------------
#if 0
Vector3 Vector3::cosRandom(const Vector3& normal) {
double e1 = G3D::random(0, 1);
double e2 = G3D::random(0, 1);
// Angle from normal
double theta = acos(sqrt(e1));
// Angle about normal
double phi = 2 * G3D_PI * e2;
// Make a coordinate system
Vector3 U = normal.direction();
Vector3 V = Vector3::unitX();
if (abs(U.dot(V)) > .9) {
V = Vector3::unitY();
}
Vector3 W = U.cross(V).direction();
V = W.cross(U);
// Convert to rectangular form
return cos(theta) * U + sin(theta) * (cos(phi) * V + sin(phi) * W);
}
//----------------------------------------------------------------------------
Vector3 Vector3::hemiRandom(const Vector3& normal) {
Vector3 V = Vector3::random();
if (V.dot(normal) < 0) {
return -V;
} else {
return V;
}
}
#endif
//----------------------------------------------------------------------------
Vector3 Vector3::reflectionDirection(const Vector3& normal) const {
return -reflectAbout(normal).direction();
}
//----------------------------------------------------------------------------
Vector3 Vector3::refractionDirection(
const Vector3& normal,
float iInside,
float iOutside) const {
// From pg. 24 of Henrik Wann Jensen. Realistic Image Synthesis
// Using Photon Mapping. AK Peters. ISBN: 1568811470. July 2001.
// Invert the directions from Wann Jensen's formulation
// and normalize the vectors.
const Vector3 W = -direction();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -