/*----------------------基础----------------------*/
const double pi = acos(-1);
const int maxp = 500; //多边形最多点数
int equal(double a, double b) //判断double相等
{
if (fabs(a - b) <= 1e-8)
return 1;
else
return 0;
}
int sign(double num) //判断符号,负数返回-1,正数返回1,零返回0
{
if (fabs(num) < 1e-8) return 0;
if (num > 0) return 1;
return -1;
}
int dcmp(double a, double b) //浮点数比较,小于-1,等于0,大于1
{
if (fabs(a - b) <= 1e-8) return 0;
if (a < b) return -1;
return 1;
}
/*---------------------------------------------------*/
/*----------------------点,向量----------------------*/
struct point
{
double x, y;
point(double x1 = 0, double y1 = 0) { x = x1, y = y1; }
point operator+(point a) { return point(x + a.x, y + a.y); }
point operator-(point a) { return point(x - a.x, y - a.y); }
point operator*(double t) { return point(x * t, y * t); }
};
point rotate(point p, double theta) //将点p旋转θ弧度
{
return point(p.x * cos(theta) - p.y * sin(theta), p.x * sin(theta) + p.y * cos(theta));
}
double dot(point a, point b) { return a.x * b.x + a.y * b.y; } //点乘
double cross(point a, point b) { return a.x * b.y - a.y * b.x; } //叉乘
double len(point a) { return sqrt(dot(a, a)); } //向量模长
double angle(point a, point b) { return dot(a, b) / len(a) / len(b); } //两向量夹角
/*---------------------------------------------------*/
/*----------------------直线,线段----------------------*/
struct line //直线
{
point s, v;
line(point s1 = {0, 0}, point v1 = {1, 0}) { s = s1, v = v1; }
};
struct seg //线段
{
point u, v;
seg(point u1 = {0, 0}, point v1 = {1, 0}) { u = u1, v = v1; }
};
double angle(line a) //求直线与x轴夹角
{
return atan2(a.v.y, a.v.x);
}
point intersection(line a, line b) //求直线交点
{
point u = a.s - b.s;
double t = cross(b.v, u) / cross(a.v, b.v);
return a.s + a.v * t;
}
/*---------------------------------------------------*/
/*----------------------多边形----------------------*/
struct polygon
{
point p[maxp];
int cnt;
polygon() { cnt = 0; }
void add(point pp) { p[cnt++] = pp; } //加点
};
int stk[maxn]; //求凸包栈
bool used[maxn]; //求凸包标记已使用点
polygon andrew(polygon poly) //求凸包
{
int top = 0;
sort(poly.p, poly.p + poly.cnt, [](point a, point b) {
if (equal(a.x, b.x)) return a.y < b.y;
return a.x < b.x;
});
stk[++top] = 0;
used[0] = true;
for (int i = 1; i < poly.cnt; i++)
{
while (top >= 2 && sign(cross(poly.p[stk[top]] - poly.p[stk[top - 1]], poly.p[i] - poly.p[stk[top]])) >= 0)
{
used[stk[top]] = false;
top--;
}
stk[++top] = i;
used[i] = true;
}
int tmp = top;
used[0] = false;
for (int i = poly.cnt - 1; i >= 0; i--)
{
if (used[i]) continue;
while (top > tmp && sign(cross(poly.p[stk[top]] - poly.p[stk[top - 1]], poly.p[i] - poly.p[stk[top]])) >= 0)
{
used[stk[top]] = false;
top--;
}
stk[++top] = i;
used[i] = true;
}
polygon res;
for (int i = 1; i <= top; i++) res.add(poly.p[stk[i]]);
return res;
}
double area(polygon &poly) //求多边形面积
{
double res = 0;
if (poly.cnt < 3) return 0;
for (int i = 1; i < poly.cnt; i++)
{
res += cross(poly.p[i], poly.p[i - 1]);
}
res += cross(poly.p[0], poly.p[poly.cnt - 1]);
return fabs(res / 2.0);
}
double len(polygon &poly) //求多边形周长
{
double res = 0;
for (int i = 1; i < poly.cnt; i++)
{
res += len(poly.p[i] - poly.p[i - 1]);
}
res += len(poly.p[0] - poly.p[poly.cnt - 1]);
return res;
}
int on_right(line a, line b, line c) //判断bc交点是否在a的右边
{
point o = intersection(b, c);
if (sign(cross(o - a.s, a.v)) == 1) return 1;
return 0;
}
int q[maxn]; //半平面交双端队列
polygon half_plane_intersection(polygon poly[], int cnt) //求半平面交
{
vector<line> li;
for (int i = 0; i < cnt; i++)
{
for (int j = 1; j < poly[i].cnt; j++)
{
point s, v;
s = poly[i].p[j - 1];
v = poly[i].p[j] - poly[i].p[j - 1];
li.push_back(line(s, v));
}
if (poly[i].p[0] != poly[i].p[poly[i].cnt - 1])
{
point s, v;
s = poly[i].p[poly[i].cnt - 1];
v = poly[i].p[0] - poly[i].p[poly[i].cnt - 1];
li.push_back(line(s, v));
}
}
sort(li.begin(), li.end(), [](line a, line b) {
double num1, num2;
num1 = atan2(a.v.y, a.v.x);
num2 = atan2(b.v.y, b.v.x);
if (equal(num1, num2)) return sign(cross(b.s - a.s, a.v)) == 1;
return num1 < num2;
});
int hh = 0, tt = -1;
for (int i = 0; i < li.size(); i++)
{
if (i > 0 && dcmp(angle(li[i]), angle(li[i - 1])) == 0) continue;
while (hh + 1 <= tt && on_right(li[i], li[q[tt - 1]], li[q[tt]])) tt--;
while (hh + 1 <= tt && on_right(li[i], li[q[hh]], li[q[hh + 1]])) hh++;
q[++tt] = i;
}
while (hh + 1 <= tt && on_right(li[q[hh]], li[q[tt - 1]], li[q[tt]])) tt--;
while (hh + 1 <= tt && on_right(li[q[tt]], li[q[hh]], li[q[hh + 1]])) hh++;
q[++tt] = q[hh];
int k = 0;
polygon ans;
for (int i = hh; i < tt; i++)
ans.add(intersection(li[q[i]], li[q[i + 1]]));
return ans;
}
/*---------------------------------------------------*/
计算几何模板v0.1
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
决战Go语言从入门到入土v0.1
go语言从入门到入土
golang 开发语言 后端 Go 工作区 -
自动驾驶基础知识图谱v0.1
如果你觉得还行的话,就分享到你的朋友圈或QQ群或微信群,谢谢O(∩_∩)O~开篇一
软件测试 python 人工智能 github 编程语言