연산자 오버로딩
C#에서 연산자도 하나의 메소드형 멤버로 간주하므로 오버로딩이 가능하다
형식
{한정자} {반환형} operaotr {연산자} ({매개변수})
오버로딩 가능한 연산자
+, -, *, /, %, &, |, ^, <<, >>, !, ~, ++, ==, !=, <, >, <=, >=
(관계 연산자는 pair로 오버로드 해야함)
오버로딩 예시
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LearnAlgorithm
{
class DataTemp
{
int Val;
public DataTemp(int val)
{
Val = val;
}
public override string ToString()
{
return "Val : " + Val.ToString();
}
public override bool Equals(object obj)
{
return Val == ((DataTemp)obj).Val;
}
public override int GetHashCode()
{
return Val;
}
public static int operator +(DataTemp src, int v)
{
return src.Val + v;
}
public static int operator +(int v, DataTemp src)
{
return v + src.Val;
}
public static DataTemp operator +(DataTemp left, DataTemp right)
{
int result = left.Val + right.Val;
return new DataTemp(result);
}
public static bool operator ==(DataTemp left, DataTemp right)
{
return left.Val == right.Val;
}
public static bool operator !=(DataTemp left, DataTemp right)
{
return left.Val != right.Val;
}
}
}
벡터의 이해와 벡터연산
벡터 덧셈과 뺄셈
벡터의 각 성분별로 연산을 한다
벡터의 덧셈은 게임 개발에서 위치이동에 많이 쓰인다.
(현재위치 + 이동방향 및 거리)
벡터의 뺄셈은 게임 개발에서 현재 위치에서 목적지까지의 거리와 방향을 알아내는 데에 쓰인다.
(목적지 - 현재위치)
스칼라곱
백터의 각 성분에 스칼라를 연산시킨다.
정규화
힘의 값을 1로 만들도록 스칼라 곱을 하는 것
백터의 내적(Dot)
두 벡터가 가리키는 방향의 차이를 연산으로 구한다.
결과 값으로 스칼라값이 나온다.
내적의 결과는 두 벡터의 크기 사이각의 연산과 같다.
2차원, 3차원에서 모두 가능
벡터의 외적(Cross)
3차원 벡터에서만 계산 가능
두 3차원 벡터의 외적은 벡터곱이라고 하며, 연산의 결과, 두 벡터에 대해 수직인 벡터(법선 벡터)가 생성된다.
[과제1]
아래 조건에 따른 나의 이동 후 좌표 값을 계산해보세요.
내 현재 벡터는 (3,4)이다. (-2,5)의 방향, 시속 400의 속도로 10분 27초간 이동했다.
[과제2]
x, y, z 정보가 필요 (외부에서 확인 가능)
Vector의 길이(Magnitude), 정규화 벡터(Normalize)
매게변수가 없는 생성자와, 매게변수 4개가 있는 생성자가 있다.
벡터합, 차, 스칼라곱은 연산자 오버로드가 되어 있어야 한다.
외적과 내적 연산은 전역 함수처럼 사용 할 수 있어야 한다.
내 답안
using System;
namespace LearnAlgorithm_BasicMath
{
class MyVector3
{
protected float x, y, z;
public float X { get { return x; } }
public float Y { get { return y; } }
public float Z { get { return Z; } }
public float Magnitude
{
get
{
return (float)Math.Sqrt(x * x + y * y + z * z);
}
}
public override string ToString()
{
return $"(x:{x}, y:{y}, z:{z})";
}
public MyVector3 Normalize
{
get
{
return new MyVector3(x / Magnitude, y / Magnitude, z / Magnitude);
}
}
public MyVector3()
{
x = y = z = 0f;
}
public MyVector3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
public static MyVector3 operator +(MyVector3 left, MyVector3 right)
{
return new MyVector3(
left.x + right.x,
left.y + right.y,
left.z + right.z
);
}
public static MyVector3 operator -(MyVector3 left, MyVector3 right)
{
return new MyVector3(
left.x - right.x,
left.y - right.y,
left.z - right.z
);
}
public static MyVector3 operator *(MyVector3 myVector3, float scalar)
{
return new MyVector3(myVector3.x * scalar, myVector3.y * scalar, myVector3.z * scalar);
}
public static MyVector3 operator *(float scalar, MyVector3 myVector3)
{
return new MyVector3(myVector3.x * scalar, myVector3.y * scalar, myVector3.z * scalar);
}
public static float Dot(MyVector3 left, MyVector3 right)
{
return new MyVector3(left.x * right.x, left.y * right.y, left.z * right.z).Magnitude;
}
public static MyVector3 Cross(MyVector3 left, MyVector3 right)
{
return new MyVector3(left.y * right.z - left.z * right.y, left.z * right.x - left.x * right.z, left.x * right.y - left.y * right.x);
}
}
}
using System;
namespace LearnAlgorithm_BasicMath
{
internal class Program
{
static void Main(string[] args)
{
var currentVector = new MyVector3(3, 0, 4);
var dirVector = new MyVector3(-2, 0, 5);
const float speed = 400f; // 속도(시속)
const int min = 10; // 이동한 시간 (분)
const int second = 27; // 이동한 시간 (초)
float totalSecond;
float length;
totalSecond = (min * 60f) + second;
length = speed / 60f / 60f * totalSecond; // 시속 400으로 10분 27초간 이동한 거리
MyVector3 moveVector = dirVector.Normalize * length;
MyVector3 newVector = currentVector + moveVector;
Console.WriteLine($"현재위치{currentVector}에서 {dirVector}방향으로 시속 {speed:F0}의 속도로 {min}분 {second}초를 움직이면 {newVector}에 도착한다.");
Console.WriteLine();
Console.ReadKey();
}
}
}