当前位置: 首页 > news >正文

圆的面积并三角形面积并

三角形面积并

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int maxn = 110;
#define x first
#define y second
typedef pair<double, double> PDD;
const double eps = 1e-8;
const double pi = acos(-1);
const double inf = 1e12;
PDD tr[maxn][3];
PDD q[maxn];
int n;
int sign(double x)
{if(fabs(x) < eps) return 0;if(x < 0) return -1;return 1;
}
int dcmp(double x, double y)
{if(fabs(x - y) < eps) return 0;if(x < y) return -1;return 1;
}
PDD operator + (PDD a, PDD b)
{return {a.x + b.x, a.y + b.y};
}
PDD operator - (PDD a, PDD b)
{return {a.x - b.x, a.y - b.y};
}
PDD operator * (PDD a, double t)
{return {a.x * t, a.y * t};
}
PDD operator / (PDD a, double t)
{return {a.x / t, a.y / t};
}
double operator * (PDD a, PDD b)
{return a.x * b.y - a.y * b.x;
}
double operator & (PDD a, PDD b)
{return a.x * b.x + a.y * b.y;
}
bool on_segment(PDD p, PDD a, PDD b)
{return sign((p - a) & (p - b)) <= 0;
}
PDD get_line_intersection(PDD p, PDD v, PDD q, PDD w)
{if(!sign(v * w)) return {inf, inf};auto u = p - q;double t = w * u / (v * w);auto o = p + v * t;if(!on_segment(o, p, p + v) || !on_segment(o, q, q + w)) return {inf, inf};return o;
}
double line_range(double a, int side)  // 求区间上线段并集长度,side用于区分左右
{int cnt = 0;for(int i = 0; i < n; i ++){auto t = tr[i];if(dcmp(t[0].x, a) > 0 || dcmp(t[2].x, a) < 0) continue;if(!dcmp(t[0].x, a) && !dcmp(t[1].x, a)){  // 特判一下左边和直线重合的情况if(side){q[cnt ++] = {t[0].y ,t[1].y};}}else if(!dcmp(t[2].x, a) && !dcmp(t[1].x, a)){  // 特判一下右边和直线重合的情况if(!side){q[cnt ++] = {t[2].y, t[1].y};}}else{double d[3];int u = 0;for(int j = 0; j < 3; j ++){auto o = get_line_intersection(t[j], t[(j + 1) % 3] - t[j], {a, -inf}, {0, inf * 2});if(dcmp(o.x, inf)) d[u ++] = o.y;}if(u){sort(d, d + u);q[cnt ++] = {d[0], d[u - 1]};}}}if(!cnt) return 0;for(int i = 0; i < cnt; i ++){  // 确保小的在下方,大的在上方if(q[i].x > q[i].y) swap(q[i].x, q[i].y);}sort(q, q + cnt);  // 求一遍区间合并double res = 0, st = q[0].x, ed = q[0].y;for(int i = 1; i < cnt; i ++){if(q[i].x <= ed) ed = max(ed, q[i].y);else{res += ed - st;st = q[i].x, ed = q[i].y;}}res += ed - st;return res;
}
double range_area(double a, double b)
{return (line_range(a, 1) + line_range(b, 0)) * (b - a) / 2;
}
int main()
{cin >> n;vector<double> v;for(int i = 0; i < n; i ++){for(int j = 0; j < 3; j ++){cin >> tr[i][j].x >> tr[i][j].y;v.push_back(tr[i][j].x);}sort(tr[i], tr[i] + 3);  // 排序后,方便求交点}for(int i = 0; i < n; i ++){  // 求每两条边的交点for(int j = 0; j < n; j ++){for(int x = 0; x < 3; x ++){for(int y = 0; y < 3; y ++){auto o = get_line_intersection(tr[i][x], tr[i][(x + 1) % 3] - tr[i][x],tr[j][y], tr[j][(y + 1) % 3] - tr[j][y]);if(dcmp(o.x, inf)) v.push_back(o.x);  // 如果存在交点}}}}sort(v.begin(), v.end());v.erase(unique(v.begin(), v.end()), v.end());double res = 0;for(int i = 0; i < v.size() - 1; i ++){res += range_area(v[i], v[i + 1]);}printf("%.2lf\n", res);return 0;
}

圆的面积并

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 1010;
const double eps = 1e-8;
const double pi = acos(-1);
#define x first
#define y second
typedef pair<double, double> PDD;
typedef struct node
{PDD r;double R;
}Circle;
Circle a[maxn];
PDD q[maxn];
int n;
int dcmp(double x, double y)
{if(fabs(x - y) < eps) return 0;if(x < y) return -1;return 1;
}
double f(double x)  // 所有圆和X = x这条直线交集的长度
{int cnt = 0;for(int i = 0; i < n; i ++){auto X = fabs(a[i].r.x - x), R = a[i].R;if(dcmp(X, R) < 0){auto Y = sqrt(R * R - X * X);q[cnt ++] = {a[i].r.y - Y, a[i].r.y + Y};}}if(!cnt) return 0;sort(q, q + cnt); // 区间合并double res = 0, st = q[0].x, ed = q[0].y;for(int i = 1; i < cnt; i ++){if(q[i].x <= ed) ed = max(ed, q[i].y);else{res += ed - st;st = q[i].x, ed = q[i].y;}}res += ed - st;return res;
}
double simpson(double l, double r)
{auto mid = (l + r) / 2;return (r - l) * (f(l) + 4 * f(mid) + f(r)) / 6;
}
double asr(double l, double r, double s)
{double mid = (l + r) / 2;auto left = simpson(l, mid), right = simpson(mid, r);if(fabs(left + right - s) < eps) return left + right;return asr(l, mid, left) + asr(mid, r, right);
}
double get_area()
{cin >> n;double l = 2000, r = -2000; // 积分范围,根据题意来定for(int i = 0; i < n; i ++){cin >> a[i].r.x >> a[i].r.y >> a[i].R;l = min(l, a[i].r.x - a[i].R), r = max(r, a[i].r.x + a[i].R);}printf("%.3lf\n", asr(l - 100, r + 100, simpson(l, r)));
}

圆和多边形的面积并

// 求任意多边形和圆形面积交集的面积
// 利用三角剖分,将圆心和每条边的两个点连线,每次求三角形和原型交集的面积,累加求和即可。
// 要进行五种情况的分类讨论// 求三角形oab和圆面积交集的面积,圆心处于原点
PDD r;
double R;
double get_circle_triangle_area(PDD a, PDD b)
{auto da = get_dist(r, a), db = get_dist(r, b);if(dcmp(R, da) >= 0 && dcmp(R, db) >= 0) return a * b / 2;if(!sign(a * b)) return 0;PDD pa, pb;auto min_d = get_line_circle_intersection(a, b, pa, pb);if(dcmp(R, min_d) <= 0) return get_sector(a, b);if(dcmp(R, da) >= 0) return get_sector(pb, b) + a * pb / 2;if(dcmp(R, db) >= 0) return get_sector(a, pa) + pa * b / 2;return get_sector(a, pa) + pa * pb / 2 + get_sector(pb, b);
}
// 求面积,时间复杂度O(n)
double work()
{double res = 0;for(int i = 0; i < n; i ++){res += get_circle_triangle_area(q[i], q[(i + 1) % n]);}return fabs(res);
}
http://www.lryc.cn/news/382309.html

相关文章:

  • Spring Data JPA介绍与CRUD实战演练
  • Python网络爬虫实战6—下一页,模拟用户点击,切换窗口
  • Notepad++插件 Hex-Edit
  • Matlab要这样批量读取txt数据!科研效率UpUp第10期
  • buuctf----firmware
  • ssl证书90天过期?保姆级教程——使用acme.sh实现证书的自动续期
  • 由于bug造成truncate table卡住问题
  • Charles抓包工具系列文章(二)-- Repeat 回放http请求
  • jemeter基本使用
  • 【Golang】Steam 创意工坊 Mod 文件夹批量重命名
  • 求职刷题力扣DAY33--贪心算法part04
  • aws的eks(k8s)ingress+elb部署实践
  • 大数据面试题之YARN
  • 最小生成树模板(prim,heap-prim,kruskal)
  • Centos 7 或 8配置国内yum源及epel源-1
  • 轻松解决Android复杂数据结构序列化
  • 解析PDF文件中的图片为文本
  • 微信小程序表单
  • Javascript高级程序设计(第四版)--学习记录
  • DVWA-CSRF-samesite分析
  • 代码随想录训练营Day48
  • React进阶(五):导航守卫_renderroutes
  • Python基础系列教程:从零开始学习Python
  • deepl翻译的PDF文档保护密码解除
  • LeetCode 算法:二叉树的直径 c++
  • 盘立方期货Kdj幅图指标公式源码
  • SkyWalking 极简入门
  • 本篇内容:ArkTS开发系列之事件(2.8.1触屏、键鼠、焦点事件)
  • 测试的基础知识大全【测试概念、分类、模型、流程、测试用例书写、用例设计、Bug、基础功能测试实战】
  • Power Apps