ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

UVA12304 2D Geometry 110 in 1!

2021-01-05 21:02:51  阅读:169  来源: 互联网

标签:UVA12304 %. return Point Geometry db 2D operator Line


UVA12304 2D Geometry 110 in 1!

计算几何

基础函数都在里面啦!

\(Code:\)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
#include<map>
#define db double
using namespace std;
map<string,int>opt;
const db eps=1e-7;
const db Pi=acos(-1.0);
db a,b,c,d,e,f,r,r1,r2;
int q0=0,Q0=0;
db q[15];
string s;
// 等于
bool Equ(db x,db y)
{
    return fabs(x-y)<eps;
}
// 不等于
bool NEqu(db x,db y)
{
    return fabs(x-y)>=eps;
}
// 小于
bool Sm(db x,db y)
{
    return y-x>eps;
}
// 小于等于
bool Le(db x,db y)
{
    return y-x>-eps;
}
// 大于
bool Bg(db x,db y)
{
    return x-y>eps;
}
// 大于等于
bool Ge(db x,db y)
{
    return x-y>-eps;
}
// 角度转正数
db Posi(db x)
{
    if (x>=0)
        return x-(int)(x/360.0)*360.0; else
    if (Equ((int)(x/360.0)*360.0,x))
        return 0.0; else
        return x+((int)(-x/360.0)+1)*360.0;
}
// 角度转0~180度(不包含180度)
db Stan(db x)
{
    x=Posi(x);
    if (Ge(x,180.0))
        x-=180.0;
    return x;
}
// 弧度转角度
db Turn(db x)
{
    return Posi(x/Pi*180.0);
}
// 点(向量表示)
struct Point
{
    db x,y;
    Point (db xx=0.0,db yy=0.0)
    {
        x=xx,y=yy;
    }
    void read()
    {
        scanf("%lf%lf",&x,&y);
    }
    void print()
    {
        printf("%.5lf %.5lf\n",x,y);
    }
    bool operator < (const Point &A) const
    {
        if (!Equ(x,A.x))
            return Sm(x,A.x);
        return Sm(y,A.y);
    }
}A,B,C,D,E,F,G,H,I,J,K,O,O1,O2,Q[15];
// 加法
Point operator + (Point A,Point B)
{
    return Point(A.x+B.x,A.y+B.y);
}
// 减法
Point operator - (Point A,Point B)
{
    return Point(A.x-B.x,A.y-B.y);
}
// 数乘
Point operator * (Point A,db B)
{
    return Point(B*A.x,B*A.y);
}
Point operator * (db B,Point A)
{
    return Point(B*A.x,B*A.y);
}
// 数除
Point operator / (Point A,db B)
{
    return Point(A.x/B,A.y/B);
}
Point operator / (db B,Point A)
{
    return Point(A.x/B,A.y/B);
}
// 点积
db operator * (Point A,Point B)
{
    return A.x*B.x+A.y*B.y;
}
// 叉积
db operator ^ (Point A,Point B)
{
    return A.x*B.y-A.y*B.x;
}
// 等于
bool operator == (Point A,Point B)
{
    return Equ(A.x,B.x) && Equ(A.y,B.y);
}
// 不等于
bool operator != (Point A,Point B)
{
    return !Equ(A.x,B.x) || !Equ(A.y,B.y);
}
// 模长
db Len(Point A)
{
    return sqrt(A.x*A.x+A.y*A.y);
}
// 中点
Point Mid(Point A)
{
    return Point(0.5*A.x,0.5*A.y);
}
// 垂直向量
Point Verc(Point A)
{
    return Point(-A.y,A.x);
}
// 两点间距离
db Dis(Point A,Point B)
{
    return Len(A-B);
}
// 两点中点
Point Mid(Point A,Point B)
{
    return Point(0.5*(A.x+B.x),0.5*(A.y+B.y));
}
// 极角
db Angle(Point A)
{
    return atan2(A.y,A.x);
}
// 三角形角度(c边所对的角)
db Angle(db a,db b,db c)
{
    return acos((a*a+b*b-c*c)/(2.0*a*b));
}
// 旋转(将点A绕原点旋转角度k)
Point Rot(Point A,db k)
{
    db s=sin(k),c=cos(k);
    return Point(A.x*c-A.y*s,A.x*s+A.y*c);
}
// 旋转(将点A绕点B旋转角度k)
Point Rot(Point A,Point B,db k)
{
    Point C=A-B;
    db s=sin(k),c=cos(k);
    return Point(B.x+C.x*c-C.y*s,B.y+C.x*s+C.y*c);
}
// 做点A关于点B的对称点
Point Sym(Point A,Point B)
{
    return Point(2.0*B.x-A.x,2.0*B.y-A.y);
}
// 直线
struct Line
{
    // P表示直线上一点,t表示方向向量
    // L=P+kt
    Point P,t;
    Line (Point A=Point(0.0,0.0),Point B=Point(0.0,0.0))
    {
        P=A,t=B;
    }
    void print()
    {
        printf("P: %.5lf %.5lf\n",P.x,P.y);
        printf("t: %.5lf %.5lf\n",t.x,t.y);
    }
}L1,L2,L3,L4,L5,L6,L7,L8,L9,L10;
// 把两点转为直线
Line ToLine(Point A,Point B)
{
    return Line(A,B-A);
}
// 将指定的k值代入直线
Point Get(Line A,db k)
{
    return A.P+k*A.t;
}
// 得到直线上随机一点
Point Get_Rand(Line A)
{
    return A.P+19.19191919*A.t;
}
// 求中垂线
Line Median (Point A,Point B)
{
    return Line(Mid(A,B),Verc(B-A));
}
// 做平行线
Line Para(Point A,Line L)
{
    return Line(A,L.t);
}
// 做垂线
Line Verc(Point A,Line L)
{
    return Line(A,Verc(L.t));
}
// 求直线交点
Point Cross (Line L1,Line L2)
{
    Point A=Get(L1,1.0),B=Get(L1,-1.0);
    Point C=Get(L2,1.0),D=Get(L2,-1.0);
    db S1=(C-A)^(C-B);
    db S2=(D-A)^(D-B);
    Point del=D-C;
    return Point(C.x+del.x*S1/(S1-S2),C.y+del.y*S1/(S1-S2));
}
// 点到直线垂足
Point Pedal(Point A,Line L)
{
    Line L1=Verc(A,L);
    return Cross(L1,L);
}
// 判断是否在直线上
bool OnLine(Point C,Line L)
{
    Point A=Get(L,1.0),B=Get(L,-1.0);
    return Equ((C-A)^(C-B),0.0);
}
// 截取射线AB上AC=k
Point Cut(Point A,Point B,db k)
{
    Point del=B-A;
    del=(del/Len(del))*k;
    return A+del;
}
// 直线与x轴夹角
db Angle(Line A)
{
    return Angle(A.t);
}
// 圆(圆心O、半径r)
struct Circle
{
    Point O;
    db r;
    Circle (Point A=Point(0.0,0.0),db k=0.0)
    {
        O=A,r=k;
    }
    void read()
    {
        scanf("%lf%lf%lf",&O.x,&O.y,&r);
    }
}C1,C2,C3,C4,C5,C6;
int main()
{
    opt["CircumscribedCircle"]=1;
    opt["InscribedCircle"]=2;
    opt["TangentLineThroughPoint"]=3;
    opt["CircleThroughAPointAndTangentToALineWithRadius"]=4;
    opt["CircleTangentToTwoLinesWithRadius"]=5;
    opt["CircleTangentToTwoDisjointCirclesWithRadius"]=6;
    while (cin >> s)
    {
        switch (opt[s])
        {
            case 1:
                A.read(),B.read(),C.read();
                L1=Median(A,B),L2=Median(A,C);
                D=Cross(L1,L2);
                printf("(%.6lf,%.6lf,%.6lf)\n",D.x,D.y,Dis(A,D));
                break;
            case 2:
                A.read(),B.read(),C.read();
                a=Dis(B,C),b=Dis(A,C),c=Dis(A,B);
                D=B+(C-B)*(c/(c+b)),E=A+(C-A)*(c/(a+c));
                L1=ToLine(A,D),L2=ToLine(B,E);
                F=Cross(L1,L2);
                L3=ToLine(A,C);
                G=Pedal(F,ToLine(A,C));
                printf("(%.6lf,%.6lf,%.6lf)\n",F.x,F.y,Dis(F,G));
                break;
            case 3:
                C1.read(),A.read();
                q0=0;
                O=C1.O,a=Dis(O,A),b=C1.r;
                if (Sm(a,b))
                    q0=0; else
                    {
                        c=sqrt(a*a-b*b);
                        d=atan(c/b);
                        B=Rot(A,O,d),C=Rot(A,O,-d);
                        D=Cut(O,B,b),E=Cut(O,C,b);
                        q[++q0]=Angle(ToLine(A,D));
                        if (D!=E)
                            q[++q0]=Angle(ToLine(A,E));
                    }
                for (int i=1;i<=q0;++i)
                    q[i]=Stan(Turn(q[i]));
                sort(q+1,q+q0+1);
                if (!q0)
                    puts("[]"); else
                if (q0==1)
                    printf("[%.6lf]\n",q[1]); else
                    printf("[%.6lf,%.6lf]\n",q[1],q[2]);
                break;
            case 4:
                A.read(),B.read(),C.read(),scanf("%lf",&r);
                Q0=0;
                L1=ToLine(B,C);
                D=Pedal(A,L1);
                a=Dis(A,D);
                if (Equ(a,r+r))
                    Q[++Q0]=Mid(A,D); else
                if (!Bg(a,r+r))
                {
                    if (OnLine(A,L1))
                    {
                        L2=Verc(A,L1);
                        E=Get_Rand(L2);
                        G=Cut(A,E,r),H=Cut(A,E,-r);
                        Q[++Q0]=G,Q[++Q0]=H;
                    } else
                    {
                        b=sqrt(r*r-(r-a)*(r-a));
                        if (B==D)
                            swap(B,C);
                        E=Cut(D,B,b),F=Cut(D,B,-b);
                        L2=Verc(E,L1),L3=Verc(F,L1);
                        G=Pedal(A,L2),H=Pedal(A,L3);
                        I=Cut(E,G,r),J=Cut(F,H,r);
                        Q[++Q0]=I,Q[++Q0]=J;
                    }
                }
                sort(Q+1,Q+Q0+1);
                if (Q0==0)
                    puts("[]"); else
                    {
                        printf("[(%.6lf,%.6lf)",Q[1].x,Q[1].y);
                        for (int i=2;i<=Q0;++i)
                            printf(",(%.6lf,%.6lf)",Q[i].x,Q[i].y);
                        putchar(']'),putchar('\n');
                    }
                break;
            case 5:
                A.read(),B.read(),C.read(),D.read(),scanf("%lf",&r);
                Q0=0;
                L1=ToLine(A,B),L2=ToLine(C,D);
                E=Cross(L1,L2);
                L3=Verc(E,L1),L4=Verc(E,L2);
                F=Get_Rand(L3);
                H=Cut(E,F,r),I=Cut(E,F,-r);
                L5=Para(H,L1),L6=Para(I,L1);
                F=Get_Rand(L4);
                H=Cut(E,F,r),I=Cut(E,F,-r);
                L7=Para(H,L2),L8=Para(I,L2);
                Q[++Q0]=Cross(L5,L7),Q[++Q0]=Cross(L5,L8);
                Q[++Q0]=Cross(L6,L7),Q[++Q0]=Cross(L6,L8);
                sort(Q+1,Q+Q0+1);
                if (Q0==0)
                    puts("[]"); else
                    {
                        printf("[(%.6lf,%.6lf)",Q[1].x,Q[1].y);
                        for (int i=2;i<=Q0;++i)
                            printf(",(%.6lf,%.6lf)",Q[i].x,Q[i].y);
                        putchar(']'),putchar('\n');
                    }
                break;
            case 6:
                C1.read(),C2.read(),scanf("%lf",&r);
                if (C1.r<C2.r)
                    swap(C1,C2);
                Q0=0;
                O1=C1.O,O2=C2.O,r1=C1.r,r2=C2.r;
                a=Dis(O1,O2);
                r1+=r,r2+=r;
                if (Equ(a,r1+r2))
                    Q[++Q0]=Cut(O1,O2,r1); else
                if (!Bg(a,r1+r2))
                {
                    b=r1*((a*a+r1*r1-r2*r2)/(2.0*a*r1));
                    c=sqrt(r1*r1-b*b);
                    A=Cut(O1,O2,b);
                    L3=ToLine(O1,O2);
                    L4=Verc(A,L3);
                    B=Get_Rand(L4);
                    Q[++Q0]=Cut(A,B,c);
                    Q[++Q0]=Cut(A,B,-c);
                }
                sort(Q+1,Q+Q0+1);
                if (Q0==0)
                    puts("[]"); else
                    {
                        printf("[(%.6lf,%.6lf)",Q[1].x,Q[1].y);
                        for (int i=2;i<=Q0;++i)
                            printf(",(%.6lf,%.6lf)",Q[i].x,Q[i].y);
                        putchar(']'),putchar('\n');
                    }
                break;
            default:
                puts("Error");
                break;
        }
    }
    return 0;
}

标签:UVA12304,%.,return,Point,Geometry,db,2D,operator,Line
来源: https://www.cnblogs.com/GK0328/p/14237910.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有