uva 11275

来源:互联网 发布:2017昆明行知中学官网 编辑:程序博客网 时间:2024/06/07 09:44
#include <bits/stdc++.h>using namespace std;const double eps = 1e-8;const double PI = acos(-1);int T;double X, Y, Z;struct Point3{double x, y, z;Point3(double x = 0, double y = 0, double z = 0): x(x), y(y), z(z) {}};typedef Point3 Vector3;int dcmp(double x){if (fabs(x) < eps)return 0;return x < 0 ? -1 : 1;}Vector3 operator + (Vector3 A, Vector3 B){return Vector3(A.x + B.x, A.y + B.y, A.z + B.z);}Vector3 operator - (Vector3 A, Vector3 B){return Vector3(A.x - B.x, A.y - B.y, A.z - B.z);}Vector3 operator * (Vector3 A, double b){return Vector3(A.x * b, A.y * b, A.z * b);}Vector3 operator / (Vector3 A, double b){return Vector3(A.x / b, A.y / b, A.z / b);}double Dot (Vector3 A, Vector3 B){return A.x * B.x + A.y * B.y + A.z * B.z;}double Length(Vector3 A){return sqrt(Dot(A, A));}double Angle(Vector3 A, Vector3 B){return acos(Dot(A, B) / Length(A) / Length(B));}//点p到平面p0 - n的距离,n必须为单位法向量double DistanceToPlane(const Point3& p, const Point3& p0, const Vector3& n){return fabs(Dot(p - p0, n));}//点p在平面上的投影i,n必须为单位法向量Point3 GetPlaneProjection(const Point3& p, const Point3& p0, const Vector3& n){return p - n * Dot(p - p0, n);}//直线p1p2到平面p0-n的交点Point3 LinePlaneIntersection(Point3 p1, Point3 p2, Point3 p0, Vector3 n){Vector3 v = p2 - p1;double t = Dot(n, p0 - p1) / Dot(n, p2 - p1);//判断分母是否为0return p1 + v * t; //如果是线段,判断t是不是在0和1之间}Vector3 Cross(Vector3 A, Vector3 B){return Vector3(A.y * B.z - A.z * B.y, A.z * B.x - A.x * B.z, A.x * B.y - A.y * B.x);}double Area2(Point3 A, Point3 B, Point3 C){return Length(Cross(B - A, C - A));}//点p是否在三角形P0P1P2中,假定p在三角形所在平面内bool PointInTri(Point3 P, Point3 P0, Point3 P1, Point3 P2){double area1 = Area2(P, P0, P1);double area2 = Area2(P, P1, P2);double area3 = Area2(P, P2, P0);return dcmp(area1 + area2 + area3 - Area2(P0, P1, P2)) == 0;}//判断线段和三角形是否相交//三角形p0p1p2和线段abbool TriSegmentIntersection(Point3 P0, Point3 P1, Point3 P2, Point3 A, Point3 B, Point3& P){Vector3 n = Cross(P1 - P0, P2 - P0);if (dcmp(Dot(n, B - A)) == 0)return false; // 平行或共面double t = Dot(n, P0 - A) / Dot(n, B - A);if (dcmp(t) < 0 || dcmp(t - 1) > 0)return false; //交点不在线段AB上P = A + (B - A) * t;return PointInTri(P, P0, P1, P2); //判断交点是否在三角形内}//点p到直线AB的距离,面积法double DistanceToLine(Point3 P, Point3 A, Point3 B){Vector3 v1 = B - A, v2 = P - A;return Length(Cross(v1, v2)) / Length(v1);}//点到线段AB的距离double DistanceToSegment(Point3 P, Point3 A, Point3 B){Vector3 v1 = B - A, v2 = P - A, v3 = P - B;if (dcmp(Dot(v1, v2)) < 0)return Length(v2);if (dcmp(Dot(v1, v3)) > 0)return Length(v3);return Length(Cross(v1, v2)) / Length(v1);}//四面体体积double Volume6(Point3 A, Point3 B, Point3 C, Point3 D){return Dot(D - A, Cross(B - A, C - A));}bool TriTriIntersection(Point3* Tri1, Point3* Tri2){Point3 P;for (int i = 0; i < 3; i++){if (TriSegmentIntersection(Tri1[0], Tri1[1], Tri1[2], Tri2[i], Tri2[(i + 1) % 3], P))return true;if (TriSegmentIntersection(Tri2[0], Tri2[1], Tri2[2], Tri1[i], Tri1[(i + 1) % 3], P))return true;}return false;}Point3 read_point3(){scanf("%lf%lf%lf", &X, &Y, &Z);return Point3(X, Y, Z);}int main(int argc, char const *argv[]){scanf("%d", &T);while (T--){Point3 T1[3], T2[3];for (int i = 0; i < 3; i++) T1[i] = read_point3();for (int i = 0; i < 3; i++) T2[i] = read_point3();printf("%d\n", TriTriIntersection(T1, T2) ? 1 : 0);}return 0;}


求立体空间中两个三角形是否有公共点;


解法:如果相交,一个三角形的边一定经过另一个三角形的内部或边或顶点。

0 0
原创粉丝点击