csu1812
csu1812
题意
求三角形和矩形交的面积。
分析
半平面交。把三角形的三条边当作直线去切割矩形,最后求切割后的多边形面积即可。
code
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const double eps = 1e-8;
int sgn(double x) { // 误差
if(fabs(x) < eps) return 0;
return x < 0 ? -1 : 1;
}
struct P {
double x, y;
P() {}
P(double x, double y) : x(x), y(y) {}
P operator + (const P p) const {
return P(x + p.x, y + p.y);
}
P operator - (const P p) const {
return P(x - p.x, y - p.y);
}
P operator * (const double tt) const {
return P(x * tt, y * tt);
}
P operator / (const double tt) const {
return P(x / tt, y / tt);
}
bool operator < (const P &p) const { // 坐标排序规则
return x < p.x || (x == p.x && y < p.y);
}
double dot(const P &p) const { // 点积
return x * p.x + y * p.y;
}
double det(const P &p) const { // 叉积
return x * p.y - y * p.x;
}
};
P tri[4], rec[5];
P b[5], c[5];
double A, B, C;
int m;
double cross(P o, P p, P q) { // 向量 op 和 oq 的叉积
return (p.x - o.x) * (q.y - o.y) - (q.x - o.x) * (p.y - o.y);
}
void init() { // 顺时针排序
if(sgn(cross(tri[0], tri[1], tri[2])) < 0)
reverse(tri, tri + 3);
}
// 得到直线 pq : A * x + B * y + C = 0
// f(x,y) = A * x + B * y + C
// f(x,y) < 0 表示点(x,y)在直线pq的左边(此时可把pq当做向量)
void getLine(P p, P q) {
A = q.y - p.y;
B = p.x - q.x;
C = q.det(p);
}
// 直线 A * x + B * y + C = 0 与 直线 pq 的交点
P intersect(P p, P q) {
double u = fabs(A * p.x + B * p.y + C);
double v = fabs(A * q.x + B * q.y + C);
return P((p.x * v + q.x * u) / (u + v), (p.y * v + q.y * u) / (u + v));
}
double cal(P p) {
return sgn(A * p.x + B * p.y + C);
}
void cut() {
int tmpm = 0;
for (int i = 0; i < m; i++) {
if (cal(b[i]) <= 0) { // 判断是否在多边形内,这里指点在直线A * x + B * y + C = 0的左边或直线上
c[tmpm++] = b[i];
} else { // 虽然不在多边形内,但是可能和多边形内的点组成的直线与多边形产生新的交点
if (cal(b[(i - 1 + m) % m]) < 0) {
c[tmpm++] = intersect(b[(i - 1 + m) % m], b[i]);
}
if (cal(b[i + 1]) < 0) {
c[tmpm++] = intersect(b[i + 1], b[i]);
}
}
}
for (int i = 0; i < tmpm; i++)
b[i] = c[i];
b[tmpm] = c[0];
m = tmpm;
}
void solve() {
tri[3] = tri[0];
rec[4] = rec[0];
memcpy(b, rec, sizeof rec);
m = 4;
for(int i = 0; i < 3; i++) {
getLine(tri[i], tri[i + 1]);
cut();
}
}
// 求多边形面积 (a[]为多边形的点 n为点的个数)
double polygon_area(P *a, int n) {
a[n] = a[0];
double area = 0;
for(int i = 0; i < n; i++) {
area += a[i].det(a[i + 1]);
}
return fabs(area) / 2;
}
int main() {
double x1, y1, x2, y2, x3, y3, x4, y4;
while(~scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4)) {
tri[0] = P(x1, y1);
tri[1] = P(x2, y1);
tri[2] = P(x1, y2);
init();
rec[0] = P(x3, y3);
rec[1] = P(x4, y3);
rec[2] = P(x4, y4);
rec[3] = P(x3, y4);
solve();
printf("%.8f\n", polygon_area(b, m));
}
return 0;
}
csu1812的更多相关文章
- 【CSU1812】三角形和矩形 【半平面交】
检验半平面交的板子. #include <stdio.h> #include <bits/stdc++.h> using namespace std; #define gg p ...
- 2017年暑假ACM集训日志
20170710: hdu1074,hdu1087,hdu1114,hdu1159,hdu1160,hdu1171,hdu1176,hdu1010,hdu1203 20170711: hdu1231, ...
随机推荐
- 5.0 Genymotion安装以及基础使用
后续考虑到python+appium多设备并发执行,需要多台手机,所以这里就直接更新一个jenymotion,后续多设备执行直接用真机+模拟器操作!Genymotion第一步:百度搜索[Genymot ...
- Python 自学 Day1
作业二:编写登陆接口 输入用户名密码 认证成功后显示欢迎信息 输错三次后锁定 #!/usr/bin/env python import getpass def log(): uname = input ...
- Linux 网卡特性配置ethtool详解
近期遇到一个自定义报文传输性能问题,解决过程中借助了ethtool这个工具,因此发掘一下与此工具相关的网卡的一些特性. ethtool 常用命令如下,比如对eth0的操作: ethtool eth0 ...
- Vuex, api, SSR, module
vuex https://vuex.vuejs.org/zh/guide/actions.html 单向数据流 单例模式 & 多个组件共享状态 State & 状态注入 Vue.use ...
- CSS绘制三角形的原理剖析
今天学习Bootstrap时候,看到按钮的向下三角形源码: .caret { display: inline-block; ; ; margin-left: 2px; vertical-align: ...
- hdu 1211 RSA (逆元)
RSA Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- poj 2406 Power Strings (后缀数组 || KMP)
Power Strings Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 28859 Accepted: 12045 D ...
- [CF482B]Interesting Array
题目大意:构造一个序列$S$,有$m$条限制,每条为$l\;r\;q$,表示$\&_{i=l}^r S_i=q$ 题解:每条限制就把$[l,r]$内的数或上$q$,最后判断就行了 卡点:我又写 ...
- 2017 多校1 I Curse Myself
2017 多校2 I Curse Myself(第k小生成树) 题目: 给一张带权无向连通图,该图的任意一条边最多只会经过一个简单环,定义\(V(k)为第k小生成树的权值和\),求出\(\sum_{k ...
- python注解(装饰器)的用法
带参数的要用三层def,第一层写注解里的参数,第二层写函数,第三层写具体逻辑. 如果是不带参数的注解,直接使用后两层即可 def needPermission(permissionstr): def ...