找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 187|回复: 0

n维空间的多面体的有向测度和重心

[复制链接]

1

主题

0

回帖

35

积分

管理员

积分
35
发表于 2024-3-16 09:04:56 | 显示全部楼层 |阅读模式
  1. //#define LOCAL
  2. #pragma GCC optimize(2)
  3. #pragma G++ optimize(2)
  4. #pragma warning(disable:4996)
  5. #pragma comment(linker, "/STACK:1024000000,1024000000")
  6. #include <stdio.h>
  7. #include <iostream>
  8. #include <iomanip>
  9. #include <string>
  10. #include <ctype.h>
  11. #include <string.h>
  12. #include <fstream>
  13. #include <sstream>
  14. #include <math.h>
  15. #include <map>
  16. //#include <unordered采用map>
  17. #include <algorithm>
  18. #include <vector>
  19. #include <stack>
  20. #include <queue>
  21. #include <set>
  22. #include <time.h>
  23. #include <stdlib.h>
  24. #include <bitset>
  25. using namespace std;
  26. //#define int unsigned long long
  27. //#define int long long
  28. #define re register int
  29. #define ci const int
  30. #define ui unsigned int
  31. typedef pair<int, int> P;
  32. #define FE(cur) for(re h = head[cur], to; ~h; h = g[h].nxt)
  33. #define ilv inline void
  34. #define ili inline int
  35. #define ilc inline char
  36. #define ild inline double
  37. #define ilp inline P
  38. #define LEN(cur) (hjt[cur].r - hjt[cur].l)
  39. #define MID(cur) (hjt[cur].l + hjt[cur].r >> 1)
  40. #define SQUARE(x) ((x) * (x))
  41. typedef vector<int>::iterator vit;
  42. typedef set<int>::iterator sit;
  43. typedef map<int, int>::iterator mit;
  44. const int inf = ~0u >> 1;
  45. //const int inf = 0x3f3f3f3f;
  46. const double PI = acos(-1.0), eps = 1e-8;
  47. namespace fastio
  48. {
  49.     const int BUF = 1 << 21;
  50.     char fr[BUF], fw[BUF], * pr1 = fr, * pr2 = fr; int pw;
  51.     ilc gc() { return pr1 == pr2 && (pr2 = (pr1 = fr) + fread(fr, 1, BUF, stdin), *pr2 = 0, pr1 == pr2) ? EOF : *pr1++; }
  52.     ilv flush() { fwrite(fw, 1, pw, stdout); pw = 0; }
  53.     ilv pc(char c) { if (pw >= BUF) flush(); fw[pw++] = c; }
  54.     ili read(int& x)
  55.     {
  56.         x = 0; int f = 1; char c = gc(); if (!~c) return EOF;
  57.         while (!isdigit(c)) { if (c == '-') f = -1; c = gc(); }
  58.         while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = gc();
  59.         x *= f; return 1;
  60.     }
  61.     ili read(double& x)
  62.     {
  63.         int xx = 0; double f = 1.0, fraction = 1.0; char c = gc(); if (!~c) return EOF;
  64.         while (!isdigit(c)) { if (c == '-') f = -1.0; c = gc(); }
  65.         while (isdigit(c)) { xx = (xx << 3) + (xx << 1) + (c ^ 48), c = gc(); }
  66.         x = xx;
  67.         if (c ^ '.') { x = f * xx; return 1; }
  68.         c = gc();
  69.         while (isdigit(c)) x += (c ^ 48) * (fraction /= 10), c = gc();
  70.         x *= f; return 1;
  71.     }
  72.     ilv write(int x) { if (x < 0) pc('-'), x = -x; if (x > 9) write(x / 10); pc(x % 10 + 48); }
  73.     ilv writeln(int x) { write(x); pc(10); }
  74.     ili read(char* x)
  75.     {
  76.         char c = gc(); if (!~c) return EOF;
  77.         while (!isalpha(c) && !isdigit(c)) c = gc();
  78.         while (isalpha(c) || isdigit(c)) *x++ = c, c = gc();
  79.         *x = 0; return 1;
  80.     }
  81.     ili readln(char* x)
  82.     {
  83.         char c = gc(); if (!~c) return EOF;
  84.         while (c == 10) c = gc();
  85.         while (c >= 32 && c <= 126) *x++ = c, c = gc();
  86.         *x = 0; return 1;
  87.     }
  88.     ilv write(char* x) { while (*x) pc(*x++); }
  89.     ilv write(const char* x) { while (*x) pc(*x++); }
  90.     ilv writeln(char* x) { write(x); pc(10); }
  91.     ilv writeln(const char* x) { write(x); pc(10); }
  92.     ilv write(char c) { pc(c); }
  93.     ilv writeln(char c) { write(c); pc(10); }
  94. } using namespace fastio;
  95. #define cp const Point
  96. #define cs const Surface
  97. ci maxn = 105;
  98. ili dbcmp(double x)
  99. {
  100.     if (fabs(x) < eps)
  101.     {
  102.         return 0;
  103.     }
  104.     return x > eps ? 1 : -1;
  105. }
  106. ilv mmin(double& a, double b)
  107. {
  108.     if (a > b)
  109.     {
  110.         a = b;
  111.     }
  112. }
  113. struct CH3D
  114. {
  115.     struct Point
  116.     {
  117.         double x, y, z;
  118.         Point(double x = 0, double y = 0, double z = 0) :x(x), y(y), z(z) {}
  119.         Point operator + (cp& o) const
  120.         {
  121.             return Point(x + o.x, y + o.y, z + o.z);
  122.         }
  123.         Point operator - (cp& o) const
  124.         {
  125.             return Point(x - o.x, y - o.y, z - o.z);
  126.         }
  127.         double operator * (cp& o) const
  128.         {
  129.             return x * o.x + y * o.y + z * o.z;
  130.         }
  131.         Point operator / (cp& o) const
  132.         {
  133.             return Point(y * o.z - z * o.y, z * o.x - x * o.z, x * o.y - y * o.x);
  134.         }
  135.         double magnitude() const
  136.         {
  137.             return sqrt(SQUARE(x) + SQUARE(y) + SQUARE(z));
  138.         }
  139.         Point scalar(double lambda) const
  140.         {
  141.             return Point(x * lambda, y * lambda, z * lambda);
  142.         }
  143.     } ps[maxn];
  144.     int n;
  145.     struct Surface
  146.     {
  147.         int a, b, c, flag;
  148.         Surface(int a = 0, int b = 0, int c = 0) :a(a), b(b), c(c) { flag = 1; }
  149.     } surfaces[maxn << 3];
  150.     int num;
  151.     int g[maxn][maxn];
  152.     ild area(cp& a, cp& b, cp& c)
  153.     {
  154.         return ((b - a) / (c - a)).magnitude() / 2.0;
  155.     }
  156.     ild area(cs& sur)
  157.     {
  158.         return area(ps[sur.a], ps[sur.b], ps[sur.c]);
  159.     }
  160.     ild area()
  161.     {
  162.         double ans = 0;
  163.         if (n == 3)
  164.         {
  165.             return area(ps[0], ps[1], ps[2]);
  166.         }
  167.         for (re i = 0; i < num; i++)
  168.         {
  169.             ans += area(ps[surfaces[i].a], ps[surfaces[i].b], ps[surfaces[i].c]);
  170.         }
  171.         return ans;
  172.     }
  173.     ild volume(cp& a, cp& b, cp& c, cp& d)
  174.     {
  175.         return (((b - a) / (c - a)) * (d - a)) / 6.0;
  176.     }
  177.     ild volume(cp& p, cs& sur)
  178.     {
  179.         return volume(ps[sur.a], ps[sur.b], ps[sur.c], p);
  180.     }
  181.     ild volume()
  182.     {
  183.         double ans = 0;
  184.         Point o;
  185.         for (re i = 0; i < num; i++)
  186.         {
  187.             ans += volume(o, ps[surfaces[i].a], ps[surfaces[i].b], ps[surfaces[i].c]);
  188.         }
  189.         return ans;
  190.     }
  191.     ili ck(cp& p, cs& sur)
  192.     {
  193.         return dbcmp(volume(ps[sur.a], ps[sur.b], ps[sur.c], p)) == 1;
  194.     }
  195.     ili onsurface(cp& p, cs& sur)
  196.     {
  197.         return !dbcmp(volume(ps[sur.a], ps[sur.b], ps[sur.c], p));
  198.     }
  199.     ili same(cs& s, cs& t)
  200.     {
  201.         return onsurface(ps[s.a], t) && onsurface(ps[s.b], t) && onsurface(ps[s.c], t);
  202.     }
  203.     ili prework()
  204.     {
  205.         if (n < 4)
  206.         {
  207.             return 0;
  208.         }
  209.         int ok = 1;
  210.         for (re i = 1; i < n; i++)
  211.         {
  212.             if (dbcmp((ps[0] - ps[i]).magnitude()))
  213.             {
  214.                 swap(ps[1], ps[i]);
  215.                 ok = 0;
  216.                 break;
  217.             }
  218.         }
  219.         if (ok)
  220.         {
  221.             return 0;
  222.         }
  223.         ok = 1;
  224.         for (re i = 2; i < n; i++)
  225.         {
  226.             if (dbcmp(area(ps[0], ps[1], ps[i])))
  227.             {
  228.                 swap(ps[2], ps[i]);
  229.                 ok = 0;
  230.                 break;
  231.             }
  232.         }
  233.         if (ok)
  234.         {
  235.             return 0;
  236.         }
  237.         ok = 1;
  238.         for (re i = 3; i < n; i++)
  239.         {
  240.             if (dbcmp(volume(ps[0], ps[1], ps[2], ps[i])))
  241.             {
  242.                 swap(ps[3], ps[i]);
  243.                 ok = 0;
  244.                 break;
  245.             }
  246.         }
  247.         return !ok;
  248.     }
  249.     ilv construct()
  250.     {
  251.         num = 0;
  252.         if (!prework())
  253.         {
  254.             return;
  255.         }
  256.         Surface add;
  257.         for (re i = 0; i < 4; i++)
  258.         {
  259.             Surface add((i + 1) % 4, (i + 2) % 4, (i + 3) % 4);
  260.             if (ck(ps[i], add))
  261.             {
  262.                 swap(add.b, add.c);
  263.             }
  264.             g[add.a][add.b] = g[add.b][add.c] = g[add.c][add.a] = num;
  265.             surfaces[num++] = add;
  266.         }
  267.         for (re i = 4; i < n; i++)
  268.         {
  269.             for (re j = 0; j < num; j++)
  270.             {
  271.                 if (surfaces[j].flag && ck(ps[i], surfaces[j]))
  272.                 {
  273.                     dfs(i, j);
  274.                     break;
  275.                 }
  276.             }
  277.         }
  278.         int tmp = num; num = 0;
  279.         for (re i = 0; i < tmp; i++)
  280.         {
  281.             if (surfaces[i].flag)
  282.             {
  283.                 surfaces[num++] = surfaces[i];
  284.             }
  285.         }
  286.     }
  287.     void dfs(int p, int j)
  288.     {
  289.         surfaces[j].flag = 0;
  290.         rmv(p, surfaces[j].b, surfaces[j].a);
  291.         rmv(p, surfaces[j].c, surfaces[j].b);
  292.         rmv(p, surfaces[j].a, surfaces[j].c);
  293.     }
  294.     void rmv(int p, int a, int b)
  295.     {
  296.         int f = g[a][b];
  297.         if (surfaces[f].flag)
  298.         {
  299.             if (ck(ps[p], surfaces[f]))
  300.             {
  301.                 dfs(p, f);
  302.             }
  303.             else
  304.             {
  305.                 Surface add(b, a, p);
  306.                 g[b][a] = g[a][p] = g[p][b] = num;
  307.                 surfaces[num++] = add;
  308.             }
  309.         }
  310.     }
  311.     ild dis(cp& p, cs& sur)
  312.     {
  313.         return fabs(volume(p, sur)) / area(sur) * 3.0;
  314.     }
  315.     ild dis(cp& p)
  316.     {
  317.         double ans = inf;
  318.         for (int i = 0; i < num; i++)
  319.         {
  320.             mmin(ans, dis(p, surfaces[i]));
  321.         }
  322.         return ans;
  323.     }
  324.     Point gg()
  325.     {
  326.         Point ans, o = ps[0];
  327.         double v = 0, t;
  328.         for (re i = 0; i < num; i++)
  329.         {
  330.             cp& a = ps[surfaces[i].a];
  331.             cp& b = ps[surfaces[i].b];
  332.             cp& c = ps[surfaces[i].c];
  333.             t = volume(o, surfaces[i]);
  334.             ans = ans + (a + b + c + o).scalar(t / 4);
  335.             v += t;
  336.         }
  337.         return ans.scalar(1 / v);
  338.     }
  339. }ch;
  340. signed main()
  341. {
  342. #ifdef LOCAL
  343.     FILE* ALLIN = freopen("d:\\data.in", "r", stdin);
  344.     freopen("d:\\my.out", "w", stdout);
  345. #endif
  346.     while (~scanf("%d", &ch.n))
  347. //  while (~read(ch.n))
  348.     {
  349. //      for (re i = 0; i < ch.n; i++) read(ch.ps[i].x), read(ch.ps[i].y), read(ch.ps[i].z);
  350.         for (re i = 0; i < ch.n; i++) scanf("%lf%lf%lf", &ch.ps[i].x, &ch.ps[i].y, &ch.ps[i].z);
  351.         ch.construct();
  352.         CH3D::Point centroid = ch.gg();
  353.         printf("%.3lf\n", ch.dis(centroid));
  354.     }
  355.     flush();
  356. #ifdef LOCAL
  357.     fclose(ALLIN);
  358. #endif
  359.     return 0;
  360. }
  361. https://cloud.tencent.com/developer/article/1695459?areaId=106001
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2025-1-1 17:02 , Processed in 0.124528 second(s), 23 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表