반응형
// 그냥 "이런식으로 구현할 수 있다." 의 수준이므로 실제 사용은 상용 라이브러리를 쓸 것을 권장. DirectXMath.h라던가... xnamath.h라던가...
// 그러므로 include문은 생략.
header
struct float2
{
union {
struct { float x, y; };
float f[2];
};
float2();
float2(float _x, float _y);
};
struct Vector2 : float2
{
static const Vector2 Zero2;
static const Vector2 UnitX2;
static const Vector2 UnitY2;
//생성자
Vector2();
explicit Vector2(float x);
Vector2(float x, float y);
Vector2(float2& V);
Vector2(Vector2& F);
//복사 생성자
Vector2(const Vector2&) = default;
Vector2(Vector2&&) = default;
//연산자재정의
Vector2& operator=(const Vector2&) = default;
Vector2& operator=(Vector2&&) = default;
bool operator== (Vector2& V);
bool operator!= (Vector2& V);
Vector2 operator+= (Vector2 V);
Vector2 operator-= (Vector2 V);
Vector2 operator*= (float S);
Vector2 operator/= (float S);
Vector2 operator+ (Vector2 V);
Vector2 operator- (Vector2 V);
Vector2 operator* (float S);
Vector2 operator/ (float S);
Vector2 operator+ ();
Vector2 operator- ();
//멤버함수
float Length();
float LengthSquared();
float Dot(const Vector2 V);
Vector2 Normalize();
void Normalize(Vector2 result);
Vector2 Clamp(Vector2 min, Vector2 max);
void Clamp(Vector2 min, Vector2 max, Vector2 ret);
//static function
//static Vector2 operator* (float S, Vector2 V);
//static Vector2 operator/ (float S, Vector2 V);
static float Dot(Vector2 v1, Vector2 v2);
static float Distance(Vector2 v1, Vector2 v2);
static float DistanceSquared(Vector2 v1, Vector2 v2);
static Vector2 Min(Vector2 v1, Vector2 v2);
static Vector2 Max(Vector2 v1, Vector2 v2);
static Vector2 Lerp(Vector2 v1, Vector2 v2, float t); //선형 보간법
static Vector2 SmoothStep(Vector2 v1, Vector2 v2, float t); //스무스스텝. (필요한가..?)
static Vector2 Reflect(Vector2 iV, Vector2 nV); //iV:반사시킬 벡터, nV:평면의 노말벡터.
static Vector2 Refract(Vector2 iV, Vector2 nV, float rI); //iV:굴절시킬 벡터, nV:평면의 노말벡터. rI:굴절율
};
struct float3
{
union {
struct { float x, y, z; };
float f[3];
};
float3();
float3(float _x, float _y, float _z);
};
struct Vector3 : float3
{
static const Vector3 Zero3;
static const Vector3 UnitX3;
static const Vector3 UnitY3;
static const Vector3 UnitZ3;
//생성자
Vector3();
explicit Vector3(float x);
Vector3(float x, float y, float z);
Vector3(float3& F);
Vector3(Vector3& V);
//복사 생성자
Vector3(const Vector3&) = default;
Vector3(Vector3&&) = default;
//연산자재정의
Vector3& operator=(const Vector3&) = default;
Vector3& operator=(Vector3&&) = default;
bool operator== (Vector3 V);
bool operator!= (Vector3 V);
Vector3 operator+= (Vector3 V);
Vector3 operator-= (Vector3 V);
Vector3 operator*= (float S);
Vector3 operator/= (float S);
Vector3 operator+ (Vector3 V);
Vector3 operator- (Vector3 V);
Vector3 operator* (float S);
Vector3 operator/ (float S);
Vector3 operator+ ();
Vector3 operator- ();
//멤버함수
float Length();
float LengthSquared();
float Dot(Vector3 V);
Vector3 Cross(Vector3 V);
Vector3 Normalize();
void Normalize(Vector3 result);
Vector3 Clamp(Vector3 min, Vector3 max);
void Clamp(Vector3 min, Vector3 max, Vector3 ret);
//static function
//static Vector3 operator* (float S, Vector3 V);
//static Vector3 operator/ (float S, Vector3 V);
static float Dot (Vector3 v1,Vector3 v2);
static Vector3 Cross (Vector3 v1, Vector3 v2);
static Vector3 Angle(Vector3 V1, Vector3 V2);
static float Distance(Vector3 v1, Vector3 v2);
static float DistanceSquared(Vector3 v1, Vector3 v2);
static Vector3 Min(Vector3 v1, Vector3 v2);
static Vector3 Max(Vector3 v1, Vector3 v2);
static Vector3 Lerp(Vector3 v1, Vector3 v2, float t); //선형 보간법
static Vector3 SmoothStep(Vector3 v1, Vector3 v2, float t); //스무스스텝. (필요한가..?)
static Vector3 Reflect(Vector3 iV, Vector3 nV); //iV:반사시킬 벡터, nV:평면의 노말벡터.
static Vector3 Refract(Vector3 iV, Vector3 nV, float rI); //iV:굴절시킬 벡터, nV:평면의 노말벡터. rI:굴절율
};
struct float4
{
union {
struct { float x, y, z, w; };
float f[4];
};
float4();
float4(float _x, float _y, float _z, float _w);
};cpp
#pragma region float2, Vector2
float2::float2()
{
x = 0.f; y = 0.f;
}
float2::float2(float _x, float _y)
{
x = _x; y = _y;
}
//생성자
Vector2::Vector2()
: float2() {}
Vector2::Vector2(float x)
: float2(x, x) {}
Vector2::Vector2(float x, float y)
: float2(x, y) {}
Vector2::Vector2(float2& F)
{
x = F.x;
y = F.y;
}
Vector2::Vector2(Vector2& V)
{
x = V.x;
y = V.y;
}
//연산자 재정의
bool Vector2::operator== (Vector2& V)
{
if (abs(x - V.x) < L_Epsilon && abs(y - V.y) < L_Epsilon) {
return true;
}
return false;
}
bool Vector2::operator!= (Vector2& V)
{
if ( abs(x - V.x) < L_Epsilon && abs(y == V.y) < L_Epsilon) {
return false;
}
return true;
}
Vector2 Vector2::operator+= (Vector2 V)
{
Vector2 rv = { x += V.x, y += V.y };
return rv;
}
Vector2 Vector2::operator-= (Vector2 V)
{
Vector2 rv = { x -= V.x, y -= V.y};
return rv;
}
Vector2 Vector2::operator*= (float S)
{
Vector2 rv = { x *= S, y *= S };
return rv;
}
Vector2 Vector2::operator/= (float S)
{
Vector2 rv = { x /= S, y /= S };
return rv;
}
Vector2 Vector2::operator+ (Vector2 V)
{
Vector2 rv = { x + V.x, y + V.y };
return rv;
}
Vector2 Vector2::operator- (Vector2 V)
{
Vector2 rv = { x - V.x, y - V.y };
return rv;
}
Vector2 Vector2::operator* (float S)
{
Vector2 rv = { x * S, y * S };
return rv;
}
Vector2 Vector2::operator/ (float S)
{
Vector2 rv = { x / S, y / S };
return rv;
}
Vector2 Vector2::operator+ ()
{
return *this;
}
Vector2 Vector2::operator- ()
{
return Vector2(-x, -y);
}
float Vector2::Length()
{
return sqrtf(x*x + y * y);
}
float Vector2::LengthSquared()
{
return x * x + y * y;
}
float Vector2::Dot(const Vector2 V)
{
return x * V.x + y * V.y;
}
Vector2 Vector2::Normalize()
{
Vector2 bf = *this;
this->x /= Length();
this->y /= Length();
return bf;
}
void Vector2::Normalize(Vector2 result)
{
result.x /= Length();
result.y /= Length();
}
Vector2 Vector2::Clamp(const Vector2 min, const Vector2 max)
{
Vector2 bf = *this;
(x <= min.x) ? (x = min.x) : ((x > max.x) ? (x = max.x) : (x));
(y <= min.y) ? (y = min.y) : ((y > max.y) ? (y = max.y) : (y));
return bf;
}
void Vector2::Clamp(Vector2 min, Vector2 max, Vector2 ret)
{
(ret.x <= min.x) ? (ret.x = min.x) : ((ret.x > max.x) ? (ret.x = max.x) : (ret.x));
(ret.y <= min.y) ? (ret.y = min.y) : ((ret.y > max.y) ? (ret.y = max.y) : (ret.y));
}
//static function
Vector2 operator* (float S, Vector2 V)
{
Vector2 rv = { V.x * S, V.y * S };
return rv;
}
Vector2 operator/ (float S, Vector2 V)
{
Vector2 rv = { V.x / S, V.y / S };
return rv;
}
float Vector2::Dot(Vector2 v1, Vector2 v2)
{
return v1.x * v2.x + v1.y * v2.y;
}
float Vector2::Distance(Vector2 v1, Vector2 v2)
{
return (v2 - v1).Length();
}
float Vector2::DistanceSquared(Vector2 v1, Vector2 v2)
{
return (v2 - v1).LengthSquared();
}
Vector2 Vector2::Min(Vector2 v1, Vector2 v2)
{
Vector2 ret;
(v1.x <= v2.x) ? (ret.x = v1.x) : (ret.x = v2.x);
(v1.y <= v2.y) ? (ret.y = v1.y) : (ret.y = v2.y);
return ret;
}
Vector2 Vector2::Max(Vector2 v1, Vector2 v2)
{
Vector2 ret;
(v1.x >= v2.x) ? (ret.x = v1.x) : (ret.x = v2.x);
(v1.y >= v2.y) ? (ret.y = v1.y) : (ret.y = v2.y);
return ret;
}
Vector2 Vector2::Lerp(Vector2 v1, Vector2 v2, float t)
{
Vector2 ret;
t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t);
ret.x = v1.x + t * (v2.x - v1.x);
ret.y = v1.y + t * (v2.y - v1.y);
return ret;
}
Vector2 Vector2::SmoothStep(Vector2 v1, Vector2 v2, float t)
{
Vector2 ret;
t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t);
t = t * t * (3.f - 2.f*t); //극솟값이 0, 극댓값이 1, 변곡점이 0.5. (이 조건을 만족한다면 다른 식을 써도 될 듯)
ret.x = v1.x + t * (v2.x - v1.x);
ret.y = v1.y + t * (v2.y - v1.y);
return ret;
}
Vector2 Vector2::Reflect(Vector2 iV, Vector2 nV)
{
return 2.0f * Dot(iV, nV) * (iV - iV);
}
Vector2 Vector2::Refract(Vector2 iV, Vector2 nV, float rI)
{
float t = Dot(iV, nV);
float r = 1.f - (rI*rI) * (1.f - (t*t));
Vector2 rv;
if (r < 0.f) {
rv = { 0.f, 0.f };
}
else {
float s = rI * t + sqrt(r);
rv = { rI*iV.x - s * nV.x, rI*iV.y - s * nV.y };
}
}
const Vector2 Vector2::Zero2 = { 0.f, 0.f };
const Vector2 Vector2::UnitX2 = { 1.f, 0.f };
const Vector2 Vector2::UnitY2 = { 0.f, 1.f };
#pragma endregion
#pragma region float3, Vector3
float3::float3()
{
x = 0.f; y = 0.f; z = 0.f;
}
float3::float3(float _x, float _y, float _z)
{
x = _x; y = _y; z = _z;
}
//생성자
Vector3::Vector3()
: float3() {}
Vector3::Vector3(float x)
: float3(x, x, x) {}
Vector3::Vector3(float x, float y, float z)
: float3(x, y, z) {}
Vector3::Vector3(float3& F)
{
x = F.x;
y = F.y;
z = F.z;
}
Vector3::Vector3(Vector3& V)
{
x = V.x;
y = V.y;
z = V.z;
}
//연산자 재정의
bool Vector3::operator== (Vector3 V)
{
if (abs(x - V.x) < L_Epsilon && abs(y - V.y) < L_Epsilon && abs(z - V.z) < L_Epsilon) {
return true;
}
return false;
}
bool Vector3::operator!= (Vector3 V)
{
if (abs(x - V.x) < L_Epsilon && abs(y - V.y) < L_Epsilon && abs(z - V.z) < L_Epsilon) {
return false;
}
return true;
}
Vector3 Vector3::operator+= (Vector3 V)
{
Vector3 rv = { x += V.x, y += V.y, z += V.z };
return rv;
}
Vector3 Vector3::operator-= (const Vector3 V)
{
Vector3 rv = { x -= V.x, y -= V.y, z -= V.z };
return rv;
}
Vector3 Vector3::operator*= (float S)
{
Vector3 rv = { x *= S, y *= S, z *= S };
return rv;
}
Vector3 Vector3::operator/= (float S)
{
Vector3 rv = { x /= S, y /= S, z /= S };
return rv;
}
Vector3 Vector3::operator+ (Vector3 V)
{
Vector3 rv = { x + V.x, y + V.y, z + V.z };
return rv;
}
Vector3 Vector3::operator- (Vector3 V)
{
Vector3 rv = { x + V.x, y + V.y, z - V.z };
return rv;
}
Vector3 Vector3::operator* (float S)
{
Vector3 rv = { x * S, y * S, z * S };
return rv;
}
Vector3 Vector3::operator/ (float S)
{
Vector3 rv = { x / S, y / S, z / S };
return rv;
}
Vector3 Vector3::operator+ ()
{
return *this;
}
Vector3 Vector3::operator- ()
{
return Vector3(-x, -y, -z);
}
float Vector3::Length()
{
return sqrtf(x*x + y*y + z*z);
}
float Vector3::LengthSquared()
{
return x*x + y*y + z*z;
}
float Vector3::Dot(Vector3 V)
{
return x*V.x + y*V.y + z*V.z;
}
Vector3 Vector3::Cross(Vector3 V)
{
return Vector3(y*V.x - z*V.y, z*V.x - x*V.z, x*V.y - y*V.x);
}
Vector3 Vector3::Normalize()
{
Vector3 bf = *this;
this->x /= Length();
this->y /= Length();
this->z /= Length();
return bf;
}
void Vector3::Normalize(Vector3 result)
{
result.x /= Length();
result.y /= Length();
result.z /= Length();
}
Vector3 Vector3::Clamp(Vector3 min, Vector3 max)
{
Vector3 bf = *this;
(x <= min.x) ? (x = min.x) : ((x > max.x) ? (x = max.x) : (x));
(y <= min.y) ? (y = min.y) : ((y > max.y) ? (y = max.y) : (y));
(z <= min.z) ? (z = min.z) : ((z > max.z) ? (z = max.z) : (z));
return bf;
}
void Vector3::Clamp(Vector3 min, Vector3 max, Vector3 ret)
{
(ret.x <= min.x) ? (ret.x = min.x) : ((ret.x > max.x) ? (ret.x = max.x) : (ret.x));
(ret.y <= min.y) ? (ret.y = min.y) : ((ret.y > max.y) ? (ret.y = max.y) : (ret.y));
(ret.z <= min.z) ? (ret.z = min.z) : ((ret.z > max.z) ? (ret.z = max.z) : (ret.z));
}
//static function
Vector3 operator* (float S, Vector3 V)
{
Vector3 rv = { V.x * S, V.y * S, V.z * S };
return rv;
}
Vector3 operator/ (float S, Vector3 V)
{
Vector3 rv = { V.x / S, V.y / S, V.z / S };
return rv;
}
float Vector3::Dot(Vector3 v1, Vector3 v2)
{
return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
}
Vector3 Vector3::Cross(Vector3 v1, Vector3 v2)
{
return Vector3(v1.y*v2.x - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
}
Vector3 Vector3::Angle(Vector3 V1, Vector3 V2)
{
return RadianToDegree(acos(Dot(V1, V2) / (V1.Length*V2.Length)));
}
float Vector3::Distance(Vector3 v1, Vector3 v2)
{
return (v2 - v1).Length();
}
float Vector3::DistanceSquared(Vector3 v1, Vector3 v2)
{
return (v2 - v1).LengthSquared();
}
Vector3 Vector3::Min(Vector3 v1, Vector3 v2)
{
Vector3 ret;
(v1.x <= v2.x) ? (ret.x = v1.x) : (ret.x = v2.x);
(v1.y <= v2.y) ? (ret.y = v1.y) : (ret.y = v2.y);
(v1.z <= v2.z) ? (ret.z = v1.z) : (ret.z = v2.z);
return ret;
}
Vector3 Vector3::Max(Vector3 v1, Vector3 v2)
{
Vector3 ret;
(v1.x >= v2.x) ? (ret.x = v1.x) : (ret.x = v2.x);
(v1.y >= v2.y) ? (ret.y = v1.y) : (ret.y = v2.y);
(v1.z >= v2.z) ? (ret.z = v1.z) : (ret.z = v2.z);
return ret;
}
Vector3 Vector3::Lerp(Vector3 v1, Vector3 v2, float t)
{
Vector3 ret;
t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t);
ret.x = v1.x + t * (v2.x - v1.x);
ret.y = v1.y + t * (v2.y - v1.y);
ret.z = v1.z + t * (v2.z - v1.z);
return ret;
}
Vector3 Vector3::SmoothStep(Vector3 v1, Vector3 v2, float t)
{
Vector3 ret;
t = (t > 1.0f) ? 1.0f : ((t < 0.0f) ? 0.0f : t);
t = t * t * (3.f - 2.f*t); //극솟값이 0, 극댓값이 1, 변곡점이 0.5. (이 조건을 만족한다면 다른 식을 써도 될 듯)
ret.x = v1.x + t * (v2.x - v1.x);
ret.y = v1.y + t * (v2.y - v1.y);
ret.z = v1.z + t * (v2.z - v1.z);
return ret;
}
Vector3 Vector3::Reflect(Vector3 iV, Vector3 nV)
{
return 2.0f * Dot(iV, nV) * iV - iV;
}
Vector3 Vector3::Refract(Vector3 iV, Vector3 nV, float rI)
{
float t = Dot(iV, nV);
float r = 1.f - (rI*rI) * (1.f - (t*t));
Vector3 rv;
if (r < 0.f) {
rv = { 0.f, 0.f, 0.f };
}
else {
float s = rI * t + sqrt(r);
rv = { rI*iV.x - s * nV.x, rI*iV.y - s * nV.y, rI*iV.z - s * nV.z };
}
}
const Vector3 Vector3::Zero3 = { 0.f, 0.f, 0.f };
const Vector3 Vector3::UnitX3 = { 1.f, 0.f, 0.f };
const Vector3 Vector3::UnitY3 = { 0.f, 1.f, 0.f };
const Vector3 Vector3::UnitZ3 = { 0.f, 0.f, 1.f };
#pragma endregion
#pragma region float4
float4::float4()
{
x = 0.f; y = 0.f; z = 0.f; w = 0.f;
}
float4::float4(float _x, float _y, float _z, float _w)
{
x = _x; y = _y; z = _z; w = _w;
}
#pragma endregion반응형