当前位置:网站首页>Computational geometry (2)
Computational geometry (2)
2022-07-19 06:05:00 【lovesickman】
Computational geometry (2)
2022 year 4 month 18 Japan 21:31:04
Find convex hull ( Surround all points The smallest perimeter , The area is not necessarily the smallest The polygon of ) The algorithm of .
Graham Algorithm
Andrew Algorithm O ( n l o g n ) O(nlogn) O(nlogn)
- Sort the points ,x For the first keyword ,y For the second keyword . bottleneck
- Maintain the upper half of the convex polygon from left to right , Then maintain the lower part from right to left .( Use Stack maintain )
- For a clockwise convex polygon , First add the first two points to the stack , Judge from the third point , Judge the relationship between the extension line of the straight line composed of the current point and the midpoint of the stack , If the point to be added is to the left of the extension line of the straight line ( Anti-clockwise ), Push stack out of stack , Then judge , Until the point to be added is on the right of the straight extension , Then add the point to the stack , Finally, update the stack with the starting point .
Try rolling one by yourself .
2022 year 4 month 19 Japan 14:28:13
Hand rolling failed , Study y Master code .
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cstdlib>
#include<stack>
#include<map>
#include<queue>
#include<cmath>
#include<set>
#include<cassert>
#define fo(i,a,n) for(int i=(a);i<=(n);i++)
#define fo_(i,a,n) for(int i=(a);i<(n);i++)
#define debug(x) cout<<#x<<":"<<x<<endl
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define endl '\n'
using namespace std;
const int N = 1e5+10;
const int M = 510*510;
const double inf = 1e8;
typedef long long ll;
#define xx first
#define yy second
typedef pair<double,double> PDD;
typedef pair<double,double> Vector;
PDD a[N];
int n,stk[N],top;
bool used[N];
double cross(double x1,double y1,double x2,double y2){
// The first dot crosses the second dot
return x1*y2-x2*y1;
}
double dis(Vector A,Vector B){
return sqrt((A.xx-B.xx)*(A.xx-B.xx)+(A.yy-B.yy)*(A.yy-B.yy));
}
int main(){
cin>>n;
fo(i,1,n){
cin>>a[i].xx>>a[i].yy;
}
sort(a+1,a+n+1,[&](PDD a,PDD b){
if(a.xx==b.xx)return a.yy>b.yy;
return a.xx<b.xx;
});
stk[++top]={
1};
stk[++top]={
2};
used[1]=used[2]=1;
fo(i,3,n){
Vector C = a[i];
while(top>1){
// There must be at least one point in the convex hull set .
Vector B = a[stk[top]];
Vector A = a[stk[top-1]];
if(cross(C.xx-A.xx,C.yy-A.yy,B.xx-A.xx,B.yy-A.yy) < 0){
used[top]=false;
top--;
}
}
stk[++top]=i;
used[i]=true;
break;
}
for(int i=n;i>=2;i--){
if(used[i])continue;
Vector C = a[i];
while(top>1){
// There must be at least one point in the convex hull set .
Vector B = a[stk[top]];
Vector A = a[stk[top-1]];
if(cross(C.xx-A.xx,C.yy-A.yy,B.xx-A.xx,B.yy-A.yy) < 0){
used[top]=false;
top--;
}
}
stk[++top]=i;
used[i]=true;
break;
}
// The first point of special judgment
Vector C = a[1];
while(1){
if(top>1){
// There must be at least one point in the convex hull set .
Vector B = a[stk[top]];
Vector A = a[stk[top-1]];
if(cross(C.xx-A.xx,C.yy-A.yy,B.xx-A.xx,B.yy-A.yy) < 0){
used[top]=false;
top--;
}
}
stk[++top]=1;
used[1]=true;
break;
}
// fo(i,1,n){
// if(used[i]){
// cout<<i<<" ";
// }
// }
// cout<<endl;
bool flag=0;
int last,first;
double res=0;
fo(i,1,n){
if(!used[i])continue;
if(!flag){
flag=1;
last = i;
first = i;
continue;
}
res+=dis(a[i],a[last]);
last = i;
}
res+=dis(a[last],a[first]);
printf("%.2lf",res);
return 0;
}
Where you can learn .
stk[++top]={
1};
stk[++top]={
2};
used[1]=used[2]=1;
fo(i,3,n){
Vector C = a[i];
while(top>1){
// There must be at least one point in the convex hull set .
Vector B = a[stk[top]];
Vector A = a[stk[top-1]];
if(cross(C.xx-A.xx,C.yy-A.yy,B.xx-A.xx,B.yy-A.yy) < 0){
used[top]=false;
top--;
}
}
stk[++top]=i;
used[i]=true;
break;
}
----------------------------------------------
y The general way of writing :
for (int i = 0; i < n; i ++ )
{
while (top >= 2 && area(q[stk[top - 1]], q[stk[top]], q[i]) <= 0)
{
// Even if the point on the convex hull boundary is deleted from the stack , Nor can it be deleted used The mark on the wall
if (area(q[stk[top - 1]], q[stk[top]], q[i]) < 0)
used[stk[top -- ]] = false;
else top -- ;
}
stk[ ++ top] = i;
used[i] = true;
}
What you learned : At present, several can be directly added , But it needs to be used while When circulating special judgment , You can refer to y The total , Put all the code in for Inside the loop ,while Add another judgment .
used[0] = false;
for (int i = n - 1; i >= 0; i -- )
{
if (used[i]) continue;
while (top >= 2 && area(q[stk[top - 1]], q[stk[top]], q[i]) <= 0)
top -- ;
stk[ ++ top] = i;
}
You need to use the 1 The added points update the entire convex hull , Very clever use used[0] = 0;
such ,stk Will appear twice 0 Number point , Last stk[top] It must be equal to 0 , It's just convenient to calculate the perimeter .
double res = 0;
for (int i = 2; i <= top; i ++ )
res += get_dist(q[stk[i - 1]], q[stk[i]]);
return res;
Computational geometry templates
double get_dist(PDD a, PDD b)
{
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
double cross(PDD a, PDD b)
{
return a.x * b.y - a.y * b.x;
}
// a->b Vector and a->c Find the cross product of vectors .
double area(PDD a, PDD b, PDD c)
{
return cross(b - a, c - a);// First reload two points and subtract
}
Refer to the big guy's code
Can pass acwing and luogu( No visual inspection bug), There is no need to judge the problem of collinearity
Examples :
2
0 0
0 1
Output :
2
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define x first
#define y second
using namespace std;
typedef pair<double, double> PDD;
const int N = 10010;
int n;
PDD q[N];
int stk[N];
double get_dist(PDD a, PDD b)
{
double dx = a.x - b.x;
double dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
PDD operator-(PDD a, PDD b)
{
return {
a.x - b.x, a.y - b.y};
}
double cross(PDD a, PDD b)
{
return a.x * b.y - a.y * b.x;
}
double area(PDD a, PDD b, PDD c)
{
return cross(b - a, c - a);
}
double andrew()
{
sort(q, q + n);
int top = 0;
for (int i = 0; i < n; i ++ )
{
while (top >= 2 && area(q[stk[top - 1]], q[stk[top]], q[i]) <= 0)
top -- ;
stk[ ++ top] = i;
}
int k = top;
for (int i = n - 1; i >= 0; i -- )
{
// When you don't want to delete the convex hull , The point on the far right , The first point on the left can still be added again when finding the convex hull stk in .
while (top > k && area(q[stk[top - 1]], q[stk[top]], q[i]) <= 0)
top -- ;
stk[ ++ top] = i;
}
double res = 0;
for (int i = 2; i <= top; i ++ )
res += get_dist(q[stk[i - 1]], q[stk[i]]);
return res;
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%lf%lf", &q[i].x, &q[i].y);
double res = andrew();
printf("%.2lf\n", res);
return 0;
}
Credit card bumps
Spinning bug I've been looking for it for a long time qwq
#include<bits/stdc++.h>
using namespace std;
typedef pair<double,double>PDD;
#define xx first
#define yy second
#define pi acos(-1)
const int N = 1e5+10;
int n,stk[N],top,idx;
double a,b,r;
PDD A[N];// Turn a rectangular square into four corners .
double dis(PDD a,PDD b){
double dx = a.xx-b.xx;
double dy = a.yy-b.yy;
return sqrt(dx*dx+dy*dy);
}
PDD operator - (PDD a,PDD b){
return {
a.xx-b.xx,a.yy-b.yy};
}
double cross(double x1,double y1,double x2,double y2){
return x1*y2-x2*y1;
}
double area(PDD a,PDD b,PDD c){
return cross(b.xx-a.xx,b.yy-a.yy,c.xx-a.xx,c.yy-a.yy);
}
double get(){
sort(A+1,A+idx+1);
double res=0;
for(int i=1;i<=idx;i++){
//idx A little bit
while(top>=2 && area(A[stk[top-1]], A[stk[top]], A[i])<=0){
top--;
}
stk[++top]=i;
}
int k = top;
for(int i=idx;i>=1;i--){
while(top>k && area(A[stk[top-1]], A[stk[top]], A[i]) <=0){
top--;
}
stk[++top]=i;
}
for(int i=2;i<=top;i++){
res+=dis(A[stk[i]],A[stk[i-1]]);
}
return res;
}
PDD rotate(double x,double y,double theta){
double X = x*cos(theta)+y*sin(theta);
double Y = -x*sin(theta)+y*cos(theta);
return {
X,Y};
}
int main(){
cin>>n>>a>>b>>r;
/* The wrong way to write , But it's hard to see bug The original midpoint (x,y), Don't rotate , In the upper right corner is (x+b/2-r,y+a/2-r) So the rotation vector is (b/2-r,a/2-r) , But you can't use this vector instead of turning four times . Because the angle between the diagonals of a rectangle is not necessarily 45 degree . Suppose you rotate theta horn , for(int i=1;i<=n;i++){ double x,y,theta; cin>>x>>y>>theta; // Corner formula ? PDD t = rotate((b/2)-r,(a/2)-r,-theta); A[++idx] = {x + t.xx, y + t.yy}; A[++idx] = {x + t.xx, y - t.yy}; A[++idx] = {x - t.xx, y + t.yy}; A[++idx] = {x - t.xx, y - t.yy}; } */
int dx[]={
1,1,-1,-1};
int dy[]={
1,-1,1,-1};
for(int i=1;i<=n;i++){
double x,y,theta;
cin>>x>>y>>theta;
// Corner formula ?
for(int j=0;j<4;j++){
// This bug So hard
PDD t = rotate(dx[j]*((b/2)-r),dy[j]*((a/2)-r),-theta);
A[++idx] = {
x + t.xx, y + t.yy};
}
}
// cout<<idx<<endl;
// for(int i=1;i<=idx;i++){
// cout<<i<<" "<<A[i].xx<<" "<<A[i].yy<<endl;
// }
// return 0;
double res= get();
printf("%.2lf",res + 2*pi*r);
return 0;
}
边栏推荐
- Ehab the Xorcist (异或性质,构造)
- Complete scheme diagram of lth7 five pin chip fs4054 charging circuit principle
- Speed sensor signal isolation, acquisition and transformation, sine wave and sawtooth wave signal input, square wave signal output, signal converter
- 2021-09-15
- Decorate Apple Tree
- 3.7V lithium battery boost to 5v1a, fs2114 boost conversion chip design layout
- 2022/07/14 学习笔记 (day07)数组
- 4路编码器脉冲计数器,转速测量,8路DO,Modbus TCP数据采集模块
- 嵌入式C语言volatile作用
- VSCode 即时英文翻译插件 【翻译(英汉词典)】
猜你喜欢

Introduction to basic knowledge of Minio

【力扣】翻转二叉树

Tips for using tp4054 charging IC -- used in conjunction with Zhongke Lanxun ab5365b

Go language introduction and application scenario analysis

3.7V lithium battery boost to 5v1a, fs2114 boost conversion chip design layout
![Chrome browser settings [display the translation language icon in the upper right corner]](/img/87/018e0ab92f698b77ada98ef555bba8.png)
Chrome browser settings [display the translation language icon in the upper right corner]

Hra2460d-2w high voltage power supply high voltage module - high voltage - high precision hra2460d-2w

Qt Creator闪退解决办法

[antdv: Each record in table should have a unique `key` prop,or set `rowKey` to an unique.....

有线电视网(树上分组)
随机推荐
Introduction to goroutine, a high concurrency feature of golang
Introduction to basic knowledge of Minio
busybox 指定日期修改 暂时不需要clock -w 写入硬件
QTSS数据类型
[BJOI2019] 排兵布阵(分组背包)
Qtss data type
QTSS常数
HRA2460D-2w高压电源高压模块-高压---高精度hra2460d-2w
计算几何(4.17)
ES聚合分析报错:“reason“ : “Text fields are not optimised for operations
Fs5383a lithium battery 3.7V input power supply solar lawn lamp drive IC
go语言介绍及应用场景分析
Low power LDO linear regulator IC
MySQL Workbench基本使用【创建一个数据库】
Computational geometry (4.17)
Lithium battery charging management chip
Darwin's analytical experience
软考初、中、高级考试全体验
宽电压输入高电压输出 电压控制型
Configure the 'log' shortcut key in vscode and remove the console log(‘‘); Semicolon in;