当前位置:网站首页>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;
}
边栏推荐
- Darwin Streaming Server 介绍
- Hm9922 switching buck LED constant current driver IC
- 2022/07/14 learning notes (day07) array
- 处理中文分词 ik分词器以及拓展和停止字典
- 2021-11-10 micropyton tb6600 step drive class
- 2021-09-15
- 2022/07/10 第五小组 丁帅 学习笔记 day03
- 2021-11-26 pyautogui cooperates with lightning simulator to realize the automation of mobile app check-in and answer questions
- [transfer] Darwin streaming server core code analysis
- 宽电压输入高电压输出 电压控制型
猜你喜欢

数字信号隔离模块 ADUM1401ARWZ 亚德诺 库存现货

结合图片看常用串口通信UART

Thermal resistance PT100 cu50 isolation converter to 4-20mA analog output temperature transmitter 0-10V

Digital signal isolation module adum1401arwz yadeno in stock

解决:无法加载文件 C:\Program Files\.. 因为在此系统上禁止运行脚本...

设置索引库结构,给用户添加可自动补全的suggestion,并将一些字段变成集合放到suggestion里面去

2021-11-17 esp32 pin reference

2021-09-15

Fs68001 wireless charging SOC chip has simple periphery and schematic diagram of 5W wireless charging scheme

Fs4061a (5V USB input, double lithium battery series application, 5V boost charging, 8.4v Management IC
随机推荐
数字信号隔离模块 ADUM1401ARWZ 亚德诺 库存现货
配置VsCode中‘log’快捷键去掉console.log(‘‘);中的分号;
Ht7727 ht7730 ht7733 ht7737 ht7750 asynchronous DCDC boost IC
宽电压输入高电压输出 电压控制型
HRA 1~12w series 12V wide voltage 9~18v to ± 250VDC boost converter
5V升压充电8.4V芯片
2022/07/12 学习笔记 (day05)JS内置函数
Boost dc/dc converter
Qtss data type
设置索引库结构,给用户添加可自动补全的suggestion,并将一些字段变成集合放到suggestion里面去
4-20ma转4-20ma 0-5v转0-5v 模拟信号隔离变送器
4-20mA to 4-20mA 0-5V to 0-5V analog signal isolation transmitter
0-10V,4-20mA电流电压转PWM隔离转换器 质料以及应用电路图
Vscode configuring golang development environment
Ehab the Xorcist (异或性质,构造)
4-channel encoder pulse counter, 8-Channel do, Modbus TCP module
结合图片看常用串口通信UART
Pressure strain bridge signal processing photoelectric isolation amplifier
DSL实现自动补全查询
Low power LDO linear regulator IC