一道十分简单的计算几何题
这么简单的数学题放在高中可能都不屑于看吧,忘记了,我是个大学生了,hhhh, 怪不得写的这么吃力,希望数学老师不要揍我 。
To see the problem cilck here
前两天刚刚看了一大堆计算几何的板子呵;看见这题忍不住就开始一顿猛打,真是恨不得把我见过的所有板子都灵活运用一遍,xswl。
不过还是得不厚道的夸自己这化简为繁是为了早日融会贯通,hh。
先上大佬的代码
#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1);
double dis(int x1, int y1, int x2, int y2)
{
return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
int main()
{
int T; scanf("%d",&T);
int rx, ry, r, x, y;
double ans, p, k, c, s, e, v;
while(T--)
{
scanf("%d%d%d%d%d",&rx, &ry, &r, &x, &y);
if(abs(x - rx) >= r)
{
if(x > rx) ans = dis(rx + r, ry, x, y);
else ans = dis(rx - r, ry, x, y);
ans += pi * 2 * r / 4;
}
else
{
p = dis(rx, ry, x, y);
ans = sqrt(p * p - r * r);
c = r / p;
s = acos(c) * 180 / pi;
e = (y - ry) / p;
v = asin(e) * 180 / pi;
v = v - s;
ans += pi * 2 * r * (v + 90) / 360;
}
printf("%.4f\n", ans);
}
}
————————————————
版权声明:本文为CSDN博主「sugarbliss」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sugarbliss/article/details/90637103
QAQ,虽然·我也好奇我为啥可以写这么长,实力不允许吧,哈哈哈
#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-8;
const double PI = atan(1.0)*4;
//判断x是否等于0
int sgn(double x){
if(fabs(x) < eps) return 0;
else return x < 0 ? -1:1;
}
//定义点及其基本运算
struct Point{
double x, y;
Point(){}
Point(double x, double y):x(x),y(y){}
Point operator + (Point B){return Point(x+B.x,y+B.y);}
Point operator - (Point B){return Point(x-B.x,y-B.y);}
Point operator * (double k){return Point(x*k,y*k);}
Point operator / (double k){return Point(x/k,y/k);}
};
typedef Point Vector; //定义向量
double Dot(Vector A, Vector B){return A.x*B.x+A.y*B.y;} //点积
double Len(Vector A){return sqrt(Dot(A,A));}//向量的长度
double Len2(Vector A){return Dot(A,A);}//向量长度的平方
double Cross(Vector A, Vector B){return A.x*B.y-A.y*B.x;}//叉积
double Distance(Point A, Point B){return hypot(A.x-B.x,A.y-B.y);}
double Angle(Vector A, Vector B){return acos(Dot(A,B)/Len(A)/Len(B));}
double get_arc(double d, double r){return d * r;}
struct Line{
Point p1, p2;
Line(){}
Line(Point p1, Point p2):p1(p1),p2(p2){}
Line(double a, double b, double c){
if(sgn(a) == 0){
p1 = Point(0, -c/b);
p2 = Point(1, -c/b);
}
else if(sgn(b) == 0){
p1 = Point(-c/a, 0);
p2 = Point(-c/a, 1);
}
else {
p1 = Point(0, -c/b);
p2 = Point(1, (-c-a)/b);
}
}
};
double Dis_point_line(Point p, Line v){//点到直线的距离
return fabs(Cross(p - v.p1,v.p2 - v.p1))/Distance(v.p1, v.p2);
}
struct Circle{
Point c;
double r;
Circle(){}
Circle(Point c, double r):c(c),r(r){}
Circle(double x, double y, double _r){c = Point(x,y), r = _r;}
};
int Line_circle_relation(Line v, Circle C){
double dst = Dis_point_line(C.c, v);
if(sgn(dst - C.r) < 0) return 0;
if(sgn(dst - C.r) == 0) return 1;
return 2;
}
Point Point_line_proj(Point p, Line v){//点在直线上的投影
double k = Dot(v.p2 - v.p1, p - v.p1)/Len2(v.p2 - v.p1);
return v.p1 + (v.p2-v.p1)*k;
}
//直线和圆的交点,pa,pb是交点,返回值是焦点的个数
int Line_cross_circle(Line v, Circle C, Point &pa, Point &pb){
if(Line_circle_relation(v, C) == 2) return 0;//无交点
Point q = Point_line_proj(C.c, v);//圆心在直线上的投影点
double d = Dis_point_line(C.c, v);//圆心到直线的距离
double k = sqrt(C.r*C.r-d*d);
if(sgn(k) == 0){//一个交点,直线与圆相切
pa = q; pb = q; return 1;
}
Point n = (v.p2 - v.p1)/Len(v.p2 - v.p1);//单位向量
pa = q + n * k;
pb = q - n * k;
return 2;//两个交点
}
int main(){
int T;
scanf("%d", &T);
while(T --){
double rx ,ry, r, x, y;
scanf("%lf%lf%lf%lf%lf", &rx, &ry, &r, &x, &y);
double arc_length = PI/2.0*r;
if(x <= rx - r || x >= rx + r){//x = rx-r 或x = rx + r 左右, 距离等于四分之一圆加两点距离
double xx = (x >= rx)?rx + r:rx - r;
Point A = {x, y}, B = {xx, ry};
arc_length += Distance(A, B);
}
else {//否则是劣弧的弧长+切点到目标点的距离
Point pa, pb;
Vector A = {x - rx, y - ry};
Circle C = {rx, ry, r};
double rr2 = Len2(A)-r*r;
Line v = {2*(x - rx), 2*(y - ry), rx*rx+ry*ry-x*x-y*y-r*r+rr2};
if(Line_cross_circle(v, C, pa, pb) > 0){
double xx = (x >= rx)?rx + r:rx - r;
Point a = {x, y}, b = {xx, ry};
if(x >= rx){//判断劣弧
Vector E = {r, 0}, F = {pa.x-rx, pa.y-ry};
arc_length += Distance(pa, a);
double d = Angle(E, F);
arc_length += get_arc(d, r);
}
else{
Vector E = {-r, 0}, F = {pb.x-rx, pb.y-ry};
arc_length += Distance(pb, a);
double d = Angle(E, F);
arc_length += get_arc(d, r);
}
}
}
printf("%.4lf\n", arc_length);
}
return 0;
}
希望这只弱鸡也能有把代码写的高深莫测的那一天…