1. 程式人生 > >【立體幾何】Journey to Jupiter Gym - 101991J 立體幾何模板

【立體幾何】Journey to Jupiter Gym - 101991J 立體幾何模板

print https 分享 向量 函數 技術分享 cross 方向 esp

https://cn.vjudge.net/problem/Gym-101991J

題目很長,其實就是給你一個正三角形,它的中心穿過Z軸,並且告訴你它的法向量,邊長和定點A的坐標,讓你求A,B,C到Z軸上一點H的距離。

技術分享圖片

題解:高考向量題,考慮正三角形,我是把OB拆成OD加DB,OD=-OA/2,DB可以通過連立三個方程得到(它垂直於AO和法向量,他的長度為L/2)

技術分享圖片

坑:我解方程的時候寫錯了orz然後y寫成xorz 最後沒考慮逆時針輸出orz(這裏要用叉積判一下,OA X OB 的方向要與法向量同)

#include<algorithm>
#include<iostream>
#include
<stdlib.h> #include<string.h> #include<math.h> #include<stdio.h> #include<vector> #include<queue> #include<string> #include<ctime> #include<stack> #include<map> #include<set> #include<list> using namespace std; #define rep(i,j,k) for(int i = (int)j;i <= (int)k;i ++) #define
per(i,j,k) for(int i = (int)j;i >= (int)k;i --) #define debug(x) cerr<<#x<<" = "<<(x)<<endl #define mmm(a,b) memset(a,b,sizeof(a)) #define pb push_back //#define x first //#define y second typedef double db; typedef long long ll; const int MAXN = 100010;; const int maxn = MAXN;
struct V { db x, y,z; V() {} void sc() { scanf("%lf%lf", &x, &y); } V(db a, db b) : x(a), y(b) { } V operator+(V o) { return V(x + o.x, y + o.y); } V operator-(V o) { return V(x - o.x, y - o.y); } db L() { return sqrt(x * x + y * y); } V N() { db l = L(); return V(x / l, y / l); } V rot(db th) { return V(x * cos(th) - y * sin(th), x * sin(th) + y * cos(th)); } V operator*(db z) { return V(x * z, y * z); } db operator*(V o) { return x * o.x + y * o.y; } db operator|(V o) { return x * o.y - o.x * y; } void pr() { printf("%lf %lf\n", x, y); } } p[maxn]; //三維幾何函數庫 #define eps 1e-8 #define zero(x) (((x)>0?(x):-(x))<eps) struct point3 { db x, y, z; }; struct line3 { point3 a, b; }; struct plane3 { point3 a, b, c; }; //計算cross product U x V point3 xmult(point3 u, point3 v) { point3 ret; ret.x = u.y*v.z - v.y*u.z; ret.y = u.z*v.x - u.x*v.z; ret.z = u.x*v.y - u.y*v.x; return ret; } //計算dot product U . V db dmult(point3 u, point3 v) { return u.x*v.x + u.y*v.y + u.z*v.z; } //矢量差 U - V point3 subt(point3 u, point3 v) { point3 ret; ret.x = u.x - v.x; ret.y = u.y - v.y; ret.z = u.z - v.z; return ret; } point3 addt(point3 u, point3 v) { point3 ret; ret.x = u.x + v.x; ret.y = u.y + v.y; ret.z = u.z + v.z; return ret; } //取平面法向量 point3 pvec(plane3 s) { return xmult(subt(s.a, s.b), subt(s.b, s.c)); } point3 pvec(point3 s1, point3 s2, point3 s3) { return xmult(subt(s1, s2), subt(s2, s3)); } //兩點距離,單參數取向量大小 db distance(point3 p1, point3 p2) { return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y) + (p1.z - p2.z)*(p1.z - p2.z)); } //向量大小 db vlen(point3 p) { return sqrt(p.x*p.x + p.y*p.y + p.z*p.z); } int main() { freopen("jupiter.in", "r", stdin); int t; cin >> t; while (t--) { point3 N, A; db l, h; scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &N.x, &N.y, &N.z, &A.x, &A.y, &A.z, &l, &h); //scanf("%f%f%f%f%f%f%f%f", &N.x, &N.y, &N.z, &A.x, &A.y, &A.z, &l, &h); //cin >> N.x >> N.y >> N.z >> A.x >> A.y >> A.z >> l >> h; point3 H = { 0.,0.,-h }; db La, Lb, Lc; db up = N.z*A.x - A.z*N.x; db under = N.y*A.x - A.y*N.x; db coy = -up / under; db cox =( N.z + N.y*coy)/(-N.x); cox = (A.z + A.y*coy) / (-A.x); db zz=l*l / 4.0/(coy*coy + cox*cox + 1.0) ; db z = l/sqrt(coy*coy + cox * cox + 1.0)/2.0; //db z = l / 2.0 / (coy + cox + 1.0); db x = cox * z; db y = coy * z; point3 b = { x,y,z }; point3 c = { -x,-y,-z }; point3 t = xmult(A, b); if (t.z*N.z > 0); else swap(b, c); point3 unA = { -A.x / 2.,-A.y / 2.,-A.z / 2. }; point3 B = addt(unA, b); point3 C = addt(unA, c); La = distance(A, H); Lb = distance(B, H); Lc = distance(C, H); //if (N.z < 0)swap(Lb, Lc); printf("%.6lf %.6lf %.6lf\n", La,Lb,Lc); } //cin >> t; } /* 2 13 -18 1 7 5 -1 15 12 -12 -17 1 7 -5 -1 15 3 2 13 -18 1 7 5 -1 15 12 -12 -17 1 7 -5 -1 15 3 */

【立體幾何】Journey to Jupiter Gym - 101991J 立體幾何模板