惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 【当耐特】
L
Lohrmann on Cybersecurity
Google DeepMind News
Google DeepMind News
Schneier on Security
Schneier on Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
The Last Watchdog
The Last Watchdog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
N
News and Events Feed by Topic
P
Proofpoint News Feed
H
Heimdal Security Blog
云风的 BLOG
云风的 BLOG
H
Hacker News: Front Page
量子位
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
L
LINUX DO - 最新话题
F
Full Disclosure
小众软件
小众软件
Martin Fowler
Martin Fowler
Security Latest
Security Latest
The Cloudflare Blog
Hacker News: Ask HN
Hacker News: Ask HN
C
Check Point Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
I
InfoQ
AI
AI
Blog — PlanetScale
Blog — PlanetScale
I
Intezer
H
Hackread – Cybersecurity News, Data Breaches, AI and More
M
MIT News - Artificial intelligence
V
Vulnerabilities – Threatpost
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
www.infosecurity-magazine.com
www.infosecurity-magazine.com
V
V2EX
N
News and Events Feed by Topic
C
Cybersecurity and Infrastructure Security Agency CISA
T
Troy Hunt's Blog
大猫的无限游戏
大猫的无限游戏
Hacker News - Newest:
Hacker News - Newest: "LLM"
The Register - Security
The Register - Security
Forbes - Security
Forbes - Security
Recent Announcements
Recent Announcements
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cisco Talos Blog
Cisco Talos Blog
Microsoft Azure Blog
Microsoft Azure Blog
A
About on SuperTechFans
S
SegmentFault 最新的问题
S
Securelist
Cloudbric
Cloudbric
T
Tenable Blog
D
Docker

博客园 - woodfish

偏序集的Dilworth定理 XJOJ历经2个月终于完成啦~~ fork()调用的一个趣题 实现google那种输入框提示的功能 POJ 3691 安徽第二题 有限状态自动机+DP 哈尔滨赛区网络预选赛总结 [计算几何]点集中的点能组成多少个正方形 [计算几何]POJ 1375 点对圆的切线+线段重叠 [计算几何]POJ 1556 判断线段相交+Dijkstra [计算几何] POJ 1873 暴力+凸包 POJ 1026 置换群 [计算几何]POJ 1031 计算点对多边形的偏转角度 [计算几何]POJ2079 求点集中面积最大的三角形 [计算几何]POJ3608 求2个不相交凸包的最短距离 [计算几何]凸包的旋转卡壳算法 C++禁止一个类被继承的技术 C与汇编的接口技术 计算位数的3种方法 避免使用条件分支
[计算几何]POJ 1266 三角形的外接圆 圆的参数方程
woodfish · 2008-09-08 · via 博客园 - woodfish

http://acm.pku.edu.cn/JudgeOnline/problem?id=1266

题目大意是给定一个圆弧上的3个点(先给2个端点,再给定圆弧中间的一个点),要求出覆盖此圆弧的最小矩形(矩形的4个角坐标必须为整数)

先由给定的3个点可以确定这个圆弧所在圆的圆心的半径,用三角形外接圆圆心公式(好长的公式啊):

x=mx1+(0.5*((mx2-mx1)*(mx2-mx1)+(my2-my1)*(my2-my1))*(my3-my1)
          
-0.5*((mx3-mx1)*(mx3-mx1)+(my3-my1)*(my3-my1))*(my2-my1))
          
/((mx2-mx1)*(my3-my1)-(mx3-mx1)*(my2-my1)); 
    y
=my1+(0.5*((mx3-mx1)*(mx3-mx1)+(my3-my1)*(my3-my1))*(mx2-mx1)
          
-0.5*((mx2-mx1)*(mx2-mx1)+(my2-my1)*(my2-my1))*(mx3-mx1))
        
/((mx2-mx1)*(my3-my1)-(mx3-mx1)*(my2-my1));

下面求出3个点相对于圆心的偏转角度,有了这个角度之后,我们就可以判断出这段弧是一段优弧还是一段劣弧,进而给定一个角度后,我们就可以判断这个角度的点是否在这段弧上。

然后根据圆的性质很容易求得包围这段圆弧的minx,maxx,miny,maxy

PS:又是可恶的浮点误差WA了我N次,利用floor,ceil函数的时候一定要加上误差控制!!!

floor(x+EPS),ceil(x-EPS)

#include <iostream>
#include 
<algorithm>
#include 
<cmath>
using namespace std;#define EPS 1.0e-6
#define pi 3.141592653589793232846double mx1,my1,mx2,my2,mx3,my3;
bool flag;
double a1,a2,a3;

inline 

bool zero(double r) {
    
return fabs(r)<EPS;
}
void getcircle(double mx1,double my1,double mx2,double my2,
               
double mx3,double my3,double &x,double &y) {
    x
=mx1+(0.5*((mx2-mx1)*(mx2-mx1)+(my2-my1)*(my2-my1))*(my3-my1)
          
-0.5*((mx3-mx1)*(mx3-mx1)+(my3-my1)*(my3-my1))*(my2-my1))
          
/((mx2-mx1)*(my3-my1)-(mx3-mx1)*(my2-my1)); 
    y
=my1+(0.5*((mx3-mx1)*(mx3-mx1)+(my3-my1)*(my3-my1))*(mx2-mx1)
          
-0.5*((mx2-mx1)*(mx2-mx1)+(my2-my1)*(my2-my1))*(mx3-mx1))
        
/((mx2-mx1)*(my3-my1)-(mx3-mx1)*(my2-my1));
}
double angle(double x,double y,double mx1,double my1) {
    
double dx=mx1-x,dy=my1-y;
    
double theta;
    
if(zero(dx)) {
        
if(dy>0return pi*0.5;
        
return pi*1.5;
    }
else{
        theta
=atan(dy/dx);
        
if(dx<0) theta+=pi;
        
else if(dy<0) theta+=2*pi;
    }
    
return theta;
}
bool onarc(double angle) {
    
return ((angle-a1)*(angle-a2)<=0)==flag;
}
int main() {
    cin
>>mx1>>my1>>mx2>>my2>>mx3>>my3;
    
double x,y;
    getcircle(mx1,my1,mx2,my2,mx3,my3,x,y);
    
double r=sqrt((x-mx1)*(x-mx1)+(y-my1)*(y-my1));
    a1
=angle(x,y,mx1,my1);
    a2
=angle(x,y,mx2,my2);
    a3
=angle(x,y,mx3,my3);
    flag
=(a3-a1)*(a3-a2)<=0;
    
int minx,maxx,miny,maxy;
    
if(onarc(0)) {
        maxx
=ceil(x+r-EPS);
    }
else{
        maxx
=ceil(max(mx1,mx2)-EPS);
    }
    
if(onarc(pi)) {
        minx
=floor(x-r+EPS);
    }
else{
        minx
=floor(min(mx1,mx2)+EPS);
    }
    
if(onarc(pi*0.5)) {
        maxy
=ceil(y+r-EPS);
    }
else{
        maxy
=ceil(max(my1,my2)-EPS);
    }
    
if(onarc(pi*1.5)) {
        miny
=floor(y-r+EPS);
    }
else{
        miny
=floor(min(my1,my2)+EPS);
    }
    cout
<<(((long long)(maxx-minx))*(maxy-miny))<<endl;
    
return 0;
}