[关闭]
@Dmaxiya 2019-02-12T23:11:46.000000Z 字数 1806 阅读 914

计算几何

板子


基础函数

  1. const double eps = 1e-8;
  2. struct Point {
  3. double x, y;
  4. Point() {}
  5. Point(double xx, double yy) {
  6. x = xx;
  7. y = yy;
  8. }
  9. };
  10. struct Line {
  11. Point s, e;
  12. };
  13. int sign(const double &x) {
  14. if(fabs(x) < eps) {
  15. return 0;
  16. }
  17. return x > 0? 1: -1;
  18. }
  19. bool operator<(const Point &a, const Point &b) {
  20. if(sign(a.x - b.x) == 0) {
  21. return a.y < b.y;
  22. }
  23. return a.x < b.x;
  24. }
  25. // 叉积
  26. double operator^(const Point &a, const Point &b) {
  27. return a.x * b.y - a.y * b.x;
  28. }
  29. Point operator-(const Point &a, const Point &b) {
  30. return Point(a.x - b.x, a.y - b.y);
  31. }
  32. // 点积
  33. double operator*(const Point &a, const Point &b) {
  34. return a.x * b.x + a.y * b.y;
  35. }
  36. // 计算两点距离
  37. double dis(const Point &a, const Point &b) {
  38. return sqrt((a - b) * (a - b));
  39. }

判断两线段是否相交(51nod 1264)

  1. bool inter(Line l1, Line l2) {
  2. return max(l1.s.x, l1.e.x) >= min(l2.s.x, l2.e.x) &&
  3. max(l2.s.x, l2.e.x) >= min(l1.s.x, l1.e.x) &&
  4. max(l1.s.y, l1.e.y) >= min(l2.s.y, l2.e.y) &&
  5. max(l2.s.y, l2.e.y) >= min(l1.s.y, l1.e.y) &&
  6. sign((l2.s - l1.e) ^ (l1.s - l1.e)) * sign((l2.e - l1.e) ^ (l1.s - l1.e)) <= 0 &&
  7. sign((l1.s - l2.e) ^ (l2.s - l2.e)) * sign((l1.e - l2.e) ^ (l2.s - l2.e)) <= 0;
  8. }

找到线段上离某点距离最近的点(51nod 1298)

  1. Point NearestPointToLineSeg(Point p, Line l) {
  2. Point result;
  3. double t = ((p - l.s) * (l.e - l.s)) / ((l.e - l.s) * (l.e - l.s));
  4. if(t >= 0 && t <= 1) {
  5. result.x = l.s.x + (l.e.x - l.s.x) * t;
  6. result.y = l.s.y + (l.e.y - l.s.y) * t;
  7. } else {
  8. if(dis(p, l.s) < dis(p, l.e)) {
  9. result = l.s;
  10. } else {
  11. result = l.e;
  12. }
  13. }
  14. return result;
  15. }

构造凸包(HDU 1392)

  1. const int maxn = 200000 + 100;
  2. int n, top;
  3. Point point[maxn], sta[maxn];
  4. // p 的数组下标为 [1, n]
  5. // 构造的凸包存在 sta 里,从栈底到 top 点的顺序为逆时针
  6. // 凸包上的点不存在三点共线和重复点
  7. void ConvexHull(Point *p, int n) {
  8. top = 0;
  9. sort(p + 1, p + n + 1);
  10. for(int i = 1; i <= n; ++i) {
  11. while(top > 1 && ((sta[top - 1] - sta[top - 2]) ^ (p[i] - sta[top - 2])) <= 0) {
  12. --top;
  13. }
  14. sta[top++] = p[i];
  15. }
  16. int ttop = top;
  17. for(int i = n; i > 0; --i) {
  18. while(top > ttop && ((sta[top - 1] - sta[top - 2]) ^ (p[i] - sta[top - 2])) <= 0) {
  19. --top;
  20. }
  21. sta[top++] = p[i];
  22. }
  23. --top;
  24. }

在三维空间内判断四点共面

将四个点构成的三个向量 写成行列式:

计算行列式的值,若行列式的值为 ,则四点共面,否则不共面。

三角形外接圆半径

其中 分别为三边程度, 为三角形面积。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注