高校数学のベクトル問題解いてる感じ。
http://yukicoder.me/problems/147
問題
3次元座標上で、頂点PとN個の頂点Q[i]の座標が与えられる。
頂点Q[i]、Q[j]、Q[k]が成す平面と頂点Pの距離をdist(i,j,k)とする。
を求めよ。
なお、3頂点が一直線に並んだり、4頂点が同一平面に来ることはない。
解法
各頂点の座標を平行移動して、Pが原点に来るようにすると後が楽。
Nは高々300なので、(i,j,k)の組を総当たりしても間に合う。
あとは、Q[i]、Q[j]、Q[k]の3頂点が成す平面に対する原点からの距離を求める問題となる。
解き方は色々あるだろうが、自分はとのベクトル積を正規化し、との内積を取った。
3頂点が並ぶなどのコーナーケースが無いことが事前に知らされているのでだいぶ楽。
想定解では、Q[i]・Q[j]・Q[k]を底面とし、原点を頂点とする三角錐の体積を求めて、底面積で割れば高さがでるらしい…そんな解法思いつかない。
int N; double X[1010],Y[1010],Z[1010]; double PX,PY,PZ; double hoge(int a,int b,int c) { double dx[2],dy[2],dz[2]; dx[0]=X[b]-X[a]; dy[0]=Y[b]-Y[a]; dz[0]=Z[b]-Z[a]; dx[1]=X[c]-X[a]; dy[1]=Y[c]-Y[a]; dz[1]=Z[c]-Z[a]; double rx=dy[0]*dz[1]-dy[1]*dz[0]; double ry=dz[0]*dx[1]-dz[1]*dx[0]; double rz=dx[0]*dy[1]-dx[1]*dy[0]; double r=sqrt(rx*rx+ry*ry+rz*rz); return abs(X[a]*rx+Y[a]*ry+Z[a]*rz)/r; } void solve() { int i,j,k,l,r,x,y,z; string s; cin>>N; cin>>PX>>PY>>PZ; FOR(i,N) { cin>>X[i]>>Y[i]>>Z[i]; X[i]-=PX; Y[i]-=PY; Z[i]-=PZ; } double ret=0; FOR(x,N) FOR(y,x) FOR(z,y) ret += hoge(z,y,x); _P("%.12lf\n",ret); }
まとめ
やっぱり3次元ライブラリ必要なのかなぁ。