初めに
自分がベクトル関連の競プロの問題やってるときにライブラリ探したのですが、見つからなかったので作りました。間違い等見つかったらご指摘いただけると幸いです。
コード
vec2d.cpp
struct vec2d{
double x,y;
vec2d operator+(vec2d other)const{
vec2d ret;
ret.x=x+other.x;
ret.y=y+other.y;
return ret;
}
vec2d operator-(vec2d other)const{
vec2d ret;
ret.x=x-other.x;
ret.y=y-other.y;
return ret;
}
double operator*(vec2d other)const{
double ret;
ret=x*other.x+y*other.y;
return ret;
}
template <typename T>
vec2d operator*(T other)const{
vec2d ret;
ret.x=x*other,ret.y=y*other;
return ret;
}
double abs()const{
return sqrt(x*x+y*y);
}
double Abs()const{
return x*x+y*y;
}
vec2d normalize()const{
vec2d v,ret;
v={x,y};
double siz = v.abs();
ret.x=x/siz;
ret.y=y/siz;
return ret;
}
};
使い方
この構造体を張り付けた後、vec2d で型を宣言します。
vec2d は内部にxとyを持ちます。
また、加算、減算、内積、定数倍、大きさ、単位ベクトル化、に対応しています。
できる事 | 宣言方法 | 返り値 | 注意事項 |
---|---|---|---|
x成分にアクセス | vec2d a.x | double | |
y成分にアクセス | vec2d a.y | double | |
加算 | vec2d a + vec2d b | vec2d | |
減算 | vec2d a + vec2d b | vec2d | |
内積 | vec2d a * vec2d b | double | |
定数倍 | vec2d a * T b | vec2d | 順序は、絶対にvec2d が先になるようにしてください。また、Tは任意の型ですが、doubleが望ましいです。それ以外は動作確認をしておりません |
大きさ | vec2d a.abs() | double | sqrtを挟む分計算量は大きいです。tleに注意してください |
大きさ二乗 | vec2d a.Abs() | double | absと比べて計算量は少ないので、単純な大きさ比較をしたいときに使用してください |
単位ベクトル化 | vec2d a.normalize() | vec2d | 単位ベクトルを返すだけであることに注意してください。aを単位ベクトル化したい場合、a=a.normalize()と記述してください |
比較演算子
比較演算子については実装しておりません。なぜなら状況においてベクトルの何を比較したいかは異なると考えたからです。比較演算はご自身で実装するか、逐一計算する、例えば単純な大きさ比較だったらAbs関数を使う、等してください。
使用例
example_1_code.cpp
//includeは割愛します
//struct vec2d を貼ってください
int main(){
//この二つのベクトルを利用して例を示します。
vec2d a={1,4}, b={5,1};
vec2d v;
v=a+b;
cout << "加算" << " " << v.x << " " << v.y << endl;
v=a-b;
cout << "減算" << " " << v.x << " " << v.y << endl;
double naiseki = a*b;
cout << "内積" << " " << naiseki << endl;
v = a*2;
//2*aとするとエラーを吐いてしまうので注意してください
cout << "定数倍" << " " << v.x << " " << v.y << endl;
double siz = a.abs();
cout << "ベクトルの大きさ" << " " << siz << endl;
double siz_2 = a.Abs();
cout << "ベクトルの大きさの二乗" << " " << siz_2 << endl;
v = a.normalize();
cout << "単位ベクトル" << " " << v.x << " " << v.y << endl;
}
出力
example_1_out.cpp
加算 6.0000000000000 5.0000000000000
減算 -4.0000000000000 3.0000000000000
内積 9.0000000000000
定数倍 2.0000000000000 8.0000000000000
ベクトルの大きさ 4.1231056256177
ベクトルの大きさの二乗 17.0000000000000
単位ベクトル 0.2425356250363 0.9701425001453
これらを活用した関数
struct vec2d を貼った後にこの関数も貼ってご活用ください。
夾角
inc.cpp
double inc(vec2d a,vec2d b){
double cs = (a*b)/a.abs()/b.abs();
return acos(cs);
}
二つのベクトルを引数としてとることで、夾角(二つのベクトルの間の角の大きさ)をdouble型で返します。ラジアンです。csにcosを持つので途中でcsを出力させることでcosを得ることも可能です。
偏角
dec.cpp
double dec(vec2d a){
vec2d v = a.normalize();
if(a.y>=0){
double rad = acos(v.x);
return rad;
}
else {
double rad = acos(v.x)+acos(-1);
return rad;
}
}
ベクトルの偏角(x軸を軸と見た時のベクトルの角度)を返します。ラジアンです。これで偏角ソートもはかどります。
終わりに
誤字脱字、コードの間違いなどあったら非常に申し訳ありません。気づきましたら是非お知らせください。