📄 vecmath3.h
字号:
//
// vecmath3.h
//
// $Id: vecmath3.h,v 1.1.1.1 2001/02/28 00:28:40 cstolte Exp $
//
#ifndef SGL_VECMATH3_H
#define SGL_VECMATH3_H
#include <math.h>
#include <sgl/defs.h>
#include <sgl/mathfunc.h>
#include <sgl/tuples.h>
class Point3;
class Vector3;
class Normal3;
class Ray3;
/////////
// Point3
//
class Point3 : public Tuple3d {
public:
Point3() { }
Point3(double x1, double y1, double z1) : Tuple3d(x1, y1, z1) { }
Point3(const Tuple3d &t) : Tuple3d(t) { }
Vector3 operator-(const Point3 &) const;
inline Point3 operator+(const Vector3 &) const;
Point3 &operator+=(const Vector3 &);
Point3 operator-(const Vector3 &) const;
Point3 &operator-=(const Vector3 &);
bool between(const Point3 &, const Point3 &) const;
operator const double*() { return (const double *)this; }
static const Point3 origin;
};
inline double
distance_squared(const Point3 &a, const Point3 &b) {
double dx = a.x - b.x;
double dy = a.y - b.y;
double dz = a.z - b.z;
return (dx * dx + dy * dy + dz * dz);
}
inline double distance(const Point3 &a, const Point3 &b)
{ return sqrt(distance_squared(a, b)); }
inline Point3
midpoint(const Point3 &p1, const Point3 &p2)
{
return Point3(lerp(0.5, p1.x, p2.x),
lerp(0.5, p1.y, p2.y),
lerp(0.5, p1.z, p2.z));
}
//////////
// Vector3
//
class Vector3 : public Tuple3d {
public:
Vector3() { };
Vector3(double x1, double y1, double z1) : Tuple3d(x1, y1, z1) { }
Vector3(const Tuple3d &t) : Tuple3d(t) { }
Vector3 operator-() const;
Vector3 operator+(const Vector3 &) const;
Vector3 &operator+=(const Vector3 &);
Vector3 operator-(const Vector3 &) const;
Vector3 &operator-=(const Vector3 &);
Vector3 operator*(double) const;
Vector3 &operator*=(double);
Vector3 operator/(double) const;
Vector3 &operator/=(double);
static Vector3 polar(double theta, double phi, double r = 1);
void fromPolar(double &theta, double &phi, double &length) const;
Normal3 transpose() const;
inline Vector3 normalize() const;
inline Vector3 normalizezero() const;
Vector3 hat() const { return normalize(); }
Vector3 hatz() const { return normalizezero(); }
double length() const { return sqrt(x * x + y * y + z * z); }
double length_squared() const { return (x * x + y * y + z * z); }
bool coordSystem(Vector3 *u, Vector3 *v) const;
};
inline Vector3 operator*(double, const Vector3 &);
inline Vector3 cross(const Vector3 &, const Vector3 &);
extern double cos(const Vector3 &, const Vector3 &);
inline double
dot(const Vector3 &v1, const Vector3 &v2) {
return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z);
}
//////
// n and wi should be normalized before calling reflection() or
// refraction(), and wi should point away from the surface.
/////
extern Vector3 reflection(const Normal3 &n, const Vector3 &wi);
extern int refraction(const Normal3 &n, const Vector3 &wi,
Vector3 *wt, double ni, double nt);
//////////////////////////////////////////////////////////////////////////////
// Normal3
//
class Normal3 : public Tuple3d {
public:
Normal3() { };
Normal3(double x1, double y1, double z1) : Tuple3d(x1, y1, z1) { }
Normal3(const Tuple3d &t) : Tuple3d(t) { }
Normal3 operator-() const;
Normal3 operator+(const Normal3 &) const;
Normal3 &operator+=(const Normal3 &);
Normal3 operator-(const Normal3 &) const;
Normal3 &operator-=(const Normal3 &);
Normal3 operator*(double) const;
Normal3 &operator*=(double);
Normal3 operator/(double) const;
inline Normal3 &operator/=(double);
double length() const { return sqrt(x * x + y * y + z * z); }
double length_squared() const { return (x * x + y * y + z * z); }
Vector3 transpose() const { return Vector3(x, y, z); }
inline Normal3 normalize() const;
Normal3 hat() const { return normalize(); }
bool coordSystem(Vector3 *u, Vector3 *v) const;
};
inline Normal3 operator*(double, const Normal3 &);
inline double
dot(const Normal3 &n1, const Normal3 &n2) {
return (n1.x * n2.x + n1.y * n2.y + n1.z * n2.z);
}
inline double
dot(const Vector3 &v, const Normal3 &n) {
return (v.x * n.x + v.y * n.y + v.z * n.z);
}
inline double
dot(const Normal3 &n, const Vector3 &v) {
return (v.x * n.x + v.y * n.y + v.z * n.z);
}
extern double cos(const Normal3 &, const Normal3 &);
extern double cos(const Vector3 &, const Normal3 &);
extern double cos(const Normal3 &, const Vector3 &);
///////
// Ray3
//
class Ray3 {
public:
Ray3() { }
Ray3(const Point3 &org, const Vector3 &di)
: o(org), d(di) { }
Point3 operator()(double t) const { return o + t * d; }
const Point3 &origin() const { return o; }
const Vector3 &dir() const { return d; }
Ray3 hat() const { return Ray3(o, d.hat()); }
Point3 o;
Vector3 d;
};
extern std::ostream &operator<<(std::ostream &os, const Ray3 &);
///////////////////
// inline functions
//
inline Vector3
Point3::operator-(const Point3 &p2) const {
return Vector3(x - p2.x, y - p2.y, z - p2.z);
}
inline Point3
Point3::operator+(const Vector3 &v) const {
return Point3(x + v.x, y + v.y, z + v.z);
}
inline Point3 &
Point3::operator+=(const Vector3 &v2) {
x += v2.x;
y += v2.y;
z += v2.z;
return *this;
}
inline Point3
Point3::operator-(const Vector3 &v) const {
return Point3(x - v.x, y - v.y, z - v.z);
}
inline Point3 &
Point3::operator-=(const Vector3 &v2) {
x -= v2.x;
y -= v2.y;
z -= v2.z;
return *this;
}
inline Vector3
Vector3::operator-() const {
return Vector3(-x, -y, -z);
}
inline Vector3
Vector3::operator+(const Vector3 &v2) const {
return Vector3(x + v2.x, y + v2.y, z + v2.z);
}
inline Vector3 &
Vector3::operator+=(const Vector3 &v2) {
x += v2.x;
y += v2.y;
z += v2.z;
return *this;
}
inline Vector3
Vector3::operator-(const Vector3 &v2) const {
return Vector3(x - v2.x, y - v2.y, z - v2.z);
}
inline Vector3 &
Vector3::operator-=(const Vector3 &v2) {
x -= v2.x;
y -= v2.y;
z -= v2.z;
return *this;
}
inline Vector3
Vector3::operator*(double d) const {
return Vector3(x * d, y * d, z * d);
}
inline Vector3 &
Vector3::operator*=(double d) {
x *= d;
y *= d;
z *= d;
return *this;
}
inline Vector3
Vector3::operator/(double d) const {
double invd = 1. / d;
return Vector3(x * invd, y * invd, z * invd);
}
inline Vector3 &
Vector3::operator/=(double d) {
double invd = 1. / d;
x *= invd;
y *= invd;
z *= invd;
return *this;
}
inline Vector3
Vector3::normalize() const {
double invlen = 1. / length();
return Vector3(x * invlen, y * invlen, z * invlen);
}
inline Vector3
Vector3::normalizezero() const {
double len = length();
if (zero(len)) return Vector3(0.,0.,0.);
Vector3 ret(*this);
return ret /= len;
}
inline Vector3
cross(const Vector3 &v1, const Vector3 &v2) {
return Vector3((v1.y * v2.z) - (v1.z * v2.y),
(v1.z * v2.x) - (v1.x * v2.z),
(v1.x * v2.y) - (v1.y * v2.x));
}
inline Vector3
operator*(double d, const Vector3 &v2) {
return Vector3(v2.x * d, v2.y * d, v2.z * d);
}
inline Normal3
Normal3::normalize() const {
double invlen = 1. / length();
return Normal3(x * invlen, y * invlen, z * invlen);
}
inline Normal3
Vector3::transpose() const {
return Normal3(x, y, z);
}
inline Normal3
Normal3::operator-() const {
return Normal3(-x, -y, -z);
}
inline Normal3
Normal3::operator+(const Normal3 &n) const {
return Normal3(x + n.x, y + n.y, z + n.z);
}
inline Normal3 &
Normal3::operator+=(const Normal3 &n) {
x += n.x;
y += n.y;
z += n.z;
return *this;
}
inline Normal3
Normal3::operator-(const Normal3 &n) const {
return Normal3(x - n.x, y - n.y, z - n.z);
}
inline Normal3 &
Normal3::operator-=(const Normal3 &n) {
x -= n.x;
y -= n.y;
z -= n.z;
return *this;
}
inline Normal3
Normal3::operator*(double d) const {
return Normal3(x * d, y * d, z * d);
}
inline Normal3 &
Normal3::operator*=(double d) {
x *= d;
y *= d;
z *= d;
return *this;
}
inline Normal3
Normal3::operator/(double d) const {
double invd = 1. / d;
return Normal3(x * invd, y * invd, z * invd);
}
inline Normal3 &
Normal3::operator/=(double d) {
double invd = 1. / d;
x *= invd;
y *= invd;
z *= invd;
return *this;
}
inline Normal3
operator*(double d, const Normal3 &n) {
return Normal3(n.x * d, n.y * d, n.z * d);
}
#endif /* SGL_VECMATH3_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -