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

推荐订阅源

Jina AI
Jina AI
T
Threat Research - Cisco Blogs
量子位
Last Week in AI
Last Week in AI
aimingoo的专栏
aimingoo的专栏
Martin Fowler
Martin Fowler
F
Fortinet All Blogs
爱范儿
爱范儿
D
Docker
人人都是产品经理
人人都是产品经理
S
SegmentFault 最新的问题
Microsoft Azure Blog
Microsoft Azure Blog
B
Blog RSS Feed
A
About on SuperTechFans
P
Proofpoint News Feed
博客园 - 司徒正美
Recent Announcements
Recent Announcements
I
InfoQ
Hugging Face - Blog
Hugging Face - Blog
Microsoft Security Blog
Microsoft Security Blog
有赞技术团队
有赞技术团队
Webroot Blog
Webroot Blog
云风的 BLOG
云风的 BLOG
Vercel News
Vercel News
SecWiki News
SecWiki News
Attack and Defense Labs
Attack and Defense Labs
Hacker News: Ask HN
Hacker News: Ask HN
AI
AI
博客园_首页
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Recorded Future
Recorded Future
T
Tailwind CSS Blog
MyScale Blog
MyScale Blog
T
Tenable Blog
宝玉的分享
宝玉的分享
Google Online Security Blog
Google Online Security Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
S
Secure Thoughts
C
Check Point Blog
S
Security Affairs
L
LINUX DO - 最新话题
大猫的无限游戏
大猫的无限游戏
Scott Helme
Scott Helme
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Hacker News - Newest:
Hacker News - Newest: "LLM"
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
月光博客
月光博客
Y
Y Combinator Blog

博客园 - 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;
}