题意:三维空间中,给出两个三角形的左边,问是否相交。

面积法判断点在三角形内:

  1. #include<cstdio>
  2. #include<cmath>
  3. #include<cstring>
  4. #include<algorithm>
  5. #include<iostream>
  6. #include<memory.h>
  7. #include<cstdlib>
  8. #include<vector>
  9. #define clc(a,b) memset(a,b,sizeof(a))
  10. #define LL long long int
  11. #define up(i,x,y) for(i=x;i<=y;i++)
  12. #define w(a) while(a)
  13. const double inf=0x3f3f3f3f;
  14. const double PI = acos(-1.0);
  15. using namespace std;
  16.  
  17. struct Point3
  18. {
  19. double x, y, z;
  20. Point3(double x=, double y=, double z=):x(x),y(y),z(z) { }
  21. };
  22.  
  23. typedef Point3 Vector3;
  24.  
  25. Vector3 operator + (const Vector3& A, const Vector3& B)
  26. {
  27. return Vector3(A.x+B.x, A.y+B.y, A.z+B.z);
  28. }
  29. Vector3 operator - (const Point3& A, const Point3& B)
  30. {
  31. return Vector3(A.x-B.x, A.y-B.y, A.z-B.z);
  32. }
  33. Vector3 operator * (const Vector3& A, double p)
  34. {
  35. return Vector3(A.x*p, A.y*p, A.z*p);
  36. }
  37. Vector3 operator / (const Vector3& A, double p)
  38. {
  39. return Vector3(A.x/p, A.y/p, A.z/p);
  40. }
  41.  
  42. const double eps = 1e-;
  43. int dcmp(double x)
  44. {
  45. if(fabs(x) < eps) return ;
  46. else return x < ? - : ;
  47. }
  48.  
  49. double Dot(const Vector3& A, const Vector3& B)
  50. {
  51. return A.x*B.x + A.y*B.y + A.z*B.z;
  52. }
  53. double Length(const Vector3& A)
  54. {
  55. return sqrt(Dot(A, A));
  56. }
  57. double Angle(const Vector3& A, const Vector3& B)
  58. {
  59. return acos(Dot(A, B) / Length(A) / Length(B));
  60. }
  61. Vector3 Cross(const Vector3& A, const Vector3& B)
  62. {
  63. 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);
  64. }
  65. double Area2(const Point3& A, const Point3& B, const Point3& C)
  66. {
  67. return Length(Cross(B-A, C-A));
  68. }
  69.  
  70. Point3 read_point3()
  71. {
  72. Point3 p;
  73. scanf("%lf%lf%lf", &p.x, &p.y, &p.z);
  74. return p;
  75. }
  76.  
  77. // 点在三角形P0, P1, P2中
  78. bool PointInTri(const Point3& P, const Point3& P0, const Point3& P1, const Point3& P2)
  79. {
  80. double area1 = Area2(P, P0, P1);
  81. double area2 = Area2(P, P1, P2);
  82. double area3 = Area2(P, P2, P0);
  83. return dcmp(area1 + area2 + area3 - Area2(P0, P1, P2)) == ;
  84. }
  85.  
  86. // 三角形P0P1P2是否和线段AB相交
  87. bool TriSegIntersection(const Point3& P0, const Point3& P1, const Point3& P2, const Point3& A, const Point3& B, Point3& P)
  88. {
  89. Vector3 n = Cross(P1-P0, P2-P0);
  90. if(dcmp(Dot(n, B-A)) == ) return false; // 线段A-B和平面P0P1P2平行或共面
  91. else // 平面A和直线P1-P2有惟一交点
  92. {
  93. double t = Dot(n, P0-A) / Dot(n, B-A);
  94. if(dcmp(t) < || dcmp(t-) > ) return false; // 不在线段AB上
  95. P = A + (B-A)*t; // 交点
  96. return PointInTri(P, P0, P1, P2);
  97. }
  98. }
  99.  
  100. bool TriTriIntersection(Point3* T1, Point3* T2)
  101. {
  102. Point3 P;
  103. for(int i = ; i < ; i++)
  104. {
  105. if(TriSegIntersection(T1[], T1[], T1[], T2[i], T2[(i+)%], P)) return true;
  106. if(TriSegIntersection(T2[], T2[], T2[], T1[i], T1[(i+)%], P)) return true;
  107. }
  108. return false;
  109. }
  110.  
  111. int main()
  112. {
  113. int T;
  114. scanf("%d", &T);
  115. while(T--)
  116. {
  117. Point3 T1[], T2[];
  118. for(int i = ; i < ; i++) T1[i] = read_point3();
  119. for(int i = ; i < ; i++) T2[i] = read_point3();
  120. printf("%d\n", TriTriIntersection(T1, T2) ? : );
  121. }
  122. return ;
  123. }

用Barycentric坐标法判断点在三角形内(重心法)

  1. #include<cstdio>
  2. #include<cmath>
  3. using namespace std;
  4.  
  5. struct Point3
  6. {
  7. double x, y, z;
  8. Point3(double x=, double y=, double z=):x(x),y(y),z(z) { }
  9. };
  10.  
  11. typedef Point3 Vector3;
  12.  
  13. Vector3 operator + (const Vector3& A, const Vector3& B)
  14. {
  15. return Vector3(A.x+B.x, A.y+B.y, A.z+B.z);
  16. }
  17. Vector3 operator - (const Point3& A, const Point3& B)
  18. {
  19. return Vector3(A.x-B.x, A.y-B.y, A.z-B.z);
  20. }
  21. Vector3 operator * (const Vector3& A, double p)
  22. {
  23. return Vector3(A.x*p, A.y*p, A.z*p);
  24. }
  25. Vector3 operator / (const Vector3& A, double p)
  26. {
  27. return Vector3(A.x/p, A.y/p, A.z/p);
  28. }
  29.  
  30. const double eps = 1e-;
  31. int dcmp(double x)
  32. {
  33. if(fabs(x) < eps) return ;
  34. else return x < ? - : ;
  35. }
  36.  
  37. double Dot(const Vector3& A, const Vector3& B)
  38. {
  39. return A.x*B.x + A.y*B.y + A.z*B.z;
  40. }
  41. double Length(const Vector3& A)
  42. {
  43. return sqrt(Dot(A, A));
  44. }
  45. double Angle(const Vector3& A, const Vector3& B)
  46. {
  47. return acos(Dot(A, B) / Length(A) / Length(B));
  48. }
  49. Vector3 Cross(const Vector3& A, const Vector3& B)
  50. {
  51. 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);
  52. }
  53. double Area2(const Point3& A, const Point3& B, const Point3& C)
  54. {
  55. return Length(Cross(B-A, C-A));
  56. }
  57.  
  58. Point3 read_point3()
  59. {
  60. Point3 p;
  61. scanf("%lf%lf%lf", &p.x, &p.y, &p.z);
  62. return p;
  63. }
  64.  
  65. // 点在三角形P0, P1, P2中
  66. // http://www.blackpawn.com/texts/pointinpoly/default.html
  67. bool PointInTri(const Point3& P, const Point3& P0, const Point3& P1, const Point3& P2)
  68. {
  69. Vector3 v0 = P2 - P0;
  70. Vector3 v1 = P1 - P0;
  71. Vector3 v2 = P - P0;
  72.  
  73. // Compute dot products
  74. double dot00 = Dot(v0, v0);
  75. double dot01 = Dot(v0, v1);
  76. double dot02 = Dot(v0, v2);
  77. double dot11 = Dot(v1, v1);
  78. double dot12 = Dot(v1, v2);
  79.  
  80. // Compute barycentric coordinates
  81. double invDenom = / (dot00 * dot11 - dot01 * dot01);
  82. double u = (dot11 * dot02 - dot01 * dot12) * invDenom;
  83. double v = (dot00 * dot12 - dot01 * dot02) * invDenom;
  84.  
  85. // Check if point is in triangle
  86. return (dcmp(u) >= ) && (dcmp(v) >= ) && (dcmp(u + v - ) <= );
  87. }
  88.  
  89. // 三角形P0P1P2是否和线段AB相交
  90. bool TriSegIntersection(const Point3& P0, const Point3& P1, const Point3& P2, const Point3& A, const Point3& B, Point3& P)
  91. {
  92. Vector3 n = Cross(P1-P0, P2-P0);
  93. if(dcmp(Dot(n, B-A)) == ) return false; // 线段A-B和平面P0P1P2平行或共面
  94. else // 平面A和直线P1-P2有惟一交点
  95. {
  96. double t = Dot(n, P0-A) / Dot(n, B-A);
  97. if(dcmp(t) < || dcmp(t-) > ) return false; // 不在线段AB上
  98. P = A + (B-A)*t; // 交点
  99. return PointInTri(P, P0, P1, P2);
  100. }
  101. }
  102.  
  103. bool TriTriIntersection(Point3* T1, Point3* T2)
  104. {
  105. Point3 P;
  106. for(int i = ; i < ; i++)
  107. {
  108. if(TriSegIntersection(T1[], T1[], T1[], T2[i], T2[(i+)%], P)) return true;
  109. if(TriSegIntersection(T2[], T2[], T2[], T1[i], T1[(i+)%], P)) return true;
  110. }
  111. return false;
  112. }
  113.  
  114. int main()
  115. {
  116. int T;
  117. scanf("%d", &T);
  118. while(T--)
  119. {
  120. Point3 T1[], T2[];
  121. for(int i = ; i < ; i++) T1[i] = read_point3();
  122. for(int i = ; i < ; i++) T2[i] = read_point3();
  123. printf("%d\n", TriTriIntersection(T1, T2) ? : );
  124. }
  125. return ;
  126. }

证明可以参考http://www.cnblogs.com/graphics/archive/2010/08/05/1793393.html

三角形的三个点在同一个平面上,如果选中其中一个点,其他两个点不过是相对该点的位移而已,比如选择点A作为起点,那么点B相当于在AB方向移动一段距离得到,而点C相当于在AC方向移动一段距离得到。

所以对于平面内任意一点,都可以由如下方程来表示

P = A +  u * (C – A) + v * (B - A) // 方程1

如果系数u或v为负值,那么相当于朝相反的方向移动,即BA或CA方向。那么如果想让P位于三角形ABC内部,u和v必须满足什么条件呢?有如下三个条件

u >= 0

v >= 0

u + v <= 1

几个边界情况,当u = 0且v = 0时,就是点A,当u = 0,v = 1时,就是点B,而当u = 1, v = 0时,就是点C

整理方程1得到P – A = u(C - A) + v(B - A)

令v0 = C – A, v1 = B – A, v2 = P – A,则v2 = u * v0 + v * v1,现在是一个方程,两个未知数,无法解出u和v,将等式两边分别点乘v0和v1的到两个等式

(v2) • v0 = (u * v0 + v * v1) • v0

(v2) • v1 = (u * v0 + v * v1) • v1

注意到这里u和v是数,而v0,v1和v2是向量,所以可以将点积展开得到下面的式子。

v2 • v0 = u * (v0 • v0) + v * (v1 • v0)  // 式1

v2 • v1 = u * (v0 • v1) + v * (v1• v1)   // 式2

解这个方程得到

u = ((v1•v1)(v2•v0)-(v1•v0)(v2•v1)) / ((v0•v0)(v1•v1) - (v0•v1)(v1•v0))

v = ((v0•v0)(v2•v1)-(v0•v1)(v2•v0)) / ((v0•v0)(v1•v1) - (v0•v1)(v1•v0))

uva 11275 3D Triangles的更多相关文章

  1. uva 11275 3D Triangles (3D-Geometry)

    uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem= ...

  2. UVA 12075 - Counting Triangles(容斥原理计数)

    题目链接:12075 - Counting Triangles 题意:求n * m矩形内,最多能组成几个三角形 这题和UVA 1393类似,把总情况扣去三点共线情况,那么问题转化为求三点共线的情况,对 ...

  3. [ACM_几何] F. 3D Triangles (三维三角行相交)

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28235#problem/A 题目大意:给出三维空间两个三角形三个顶点,判断二者是否有公共 ...

  4. UVA 12075 Counting Triangles

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  5. UVA 1393 Highways,UVA 12075 Counting Triangles —— (组合数,dp)

    先看第一题,有n*m个点,求在这些点中,有多少条直线,经过了至少两点,且不是水平的也不是竖直的. 分析:由于对称性,我们只要求一个方向的线即可.该题分成两个过程,第一个过程是求出n*m的矩形中,dp[ ...

  6. 2D and 3D Linear Geometry Kernel ( Geometry Kernels) CGAL 4.13 -User Manual

    1 Introduction CGAL, the Computational Geometry Algorithms Library, is written in C++ and consists o ...

  7. IGeometryCollection Interface

    Come from ArcGIS Online IGeometryCollection Interface Provides access to members that can be used fo ...

  8. Matlab geom3d函数注释

    Matlab geom3d函数解析 geom3d函数库 geom3d库的目的是处理和可视化三维几何原语,如点.线.平面.多面体等.它提供了操作三维几何原语的底层功能,使得开发更复杂的几何算法变得更加容 ...

  9. uva 12508 - Triangles in the Grid(几何+计数)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u011328934/article/details/35244875 题目链接:uva 12508 ...

随机推荐

  1. Spring MVC控制层的返回类型--String类型与Bean类型

    SpringMVC控制层的返回类型形式多样,现拿其中的两种--String类型与Bean类型作以说明. 一.测试项目的结构 说明:(jsp的名字没起好) 控制层:UserController.java ...

  2. 解决WIN8 磁盘100 活动占用100% win8硬盘一直响

    一.先看最终效果: 二.再说解决办法:   1.任务管理器关闭进程 taskhost.exe和类似于taskhostxx.exe开头的进程. 2.在电源管理里面设置2分钟不使用硬盘则关闭硬盘,看我的截 ...

  3. 获取属性名:PropertyNameHelper

    获取属性名:PropertyNameHelper namespace NCS.Infrastructure.Querying { public static class PropertyNameHel ...

  4. spoj 394

    每段可以连续的串的可能性是个Fibonacci数列   但是直接dp更好吧~~ #include <cstdio> #include <cstring> using names ...

  5. HTTPS访问:weblogic下配置SSL

    进入Weblogic安装路径下的JDK安装目录bin文件下,通过keytool工具生成密钥对(标识密钥库) 输入命令,生成密钥 keytool.exe -genkey -v -alias weblog ...

  6. easyui源码翻译1.32+API翻译全篇导航 (提供下载源码)

    前言 EasyUI每个组件都会有 属性.方法.事件 属性 所有的属性都定义在jQuery.fn.{plugin}.defaults里面.例如,对话框属性定义在jQuery.fn.dialog.defa ...

  7. iOS 10 使用相机及相簿闪退的问题修正

    http://www.cnblogs.com/onechen/p/5935579.html

  8. [企业级linux安全管理]- 安全管理基础(1)

    1. 操作条件:  (1)装有 Cent OS Linux 操作系统的虚拟机一台 2. 背景: 某企业有一台服务器,其信息如下: (1)  该服务器上存在管理员 root,密码为 root,另存有一些 ...

  9. Android EditView 阻止软键盘自动弹出

    最近再做一个查询内的小应用,界面最上面是一个EditText查询框,进行Activity后,总会弹起软键盘.这样就挡住了查询框下面的其他查询条件 控件,感觉很不友好.所以现在要做的就是在进入Activ ...

  10. 一篇文章教会你,如何做到招聘要求中的“要有扎实的Java基础

    来历 本文来自于一次和群里猿友的交流,具体的情况且听LZ慢慢道来. 一日,LZ在群里发话,“招人啦.” 然某群友曰,“群主,俺想去.” LZ回之,“你年几何?” 群友曰,“两年也.” LZ憾言之,“惜 ...