[计算几何]POJ 1266 三角形的外接圆 圆的参数方程
2008-09-08 17:54
429 查看
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.141592653589793232846
double 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>0) return 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;
}
题目大意是给定一个圆弧上的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.141592653589793232846
double 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>0) return 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;
}
相关文章推荐
- (计算几何8.1.2.3)POJ 1329 Circle Through Three Points(利用叉积来计算三角形的外接圆的圆心)
- 三角形的外接圆 - 计算几何
- 三角形的内切圆与外接圆面积之比【几何计算】
- POJ1266 Cover an Arc (计算几何模板)
- poj1329 解析几何-三角形求外接圆
- ACM 计算几何模板 点在三角形内 加强版 HDU4380
- 【POJ】1269 Intersecting Lines(计算几何基础)
- poj 1127 计算几何
- 【POJ】1556 The Doors(计算几何基础+spfa)
- POJ 1556 The Doors 计算几何+MST
- [转] POJ计算几何
- POJ 2420 A Star not a Tree? (计算几何-费马点)
- POJ 3301 Texas Trip 计算几何 三分法求极值点
- POJ 1673 几何证明加计算几何。。。
- POJ 1269(计算几何初步——简单处理解析几何,求直线交点)
- POJ 3304 计算几何 直线与线段相交
- POJ 1410 计算几何 线段矩形相交
- #51 Codeforces-E. Very simple problem (计算几何)(点被多少个三角形包含)
- POJ 2007 计算几何水题
- 计算几何 之 hdu 1077 poj 1981 O(n^3)