반응형
// 그냥 "이런식으로 구현할 수 있다." 의 수준이므로 실제 사용은 상용 라이브러리를 쓸 것을 권장. 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
반응형