zoukankan      html  css  js  c++  java
  • UVa 11178计算几何 模板题

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    
    struct Point{
        double x,y;
        Point(double x=0, double y=0) : x(x),y(y){ }    //构造函数
    };
    typedef Point Vector;
    
    Vector operator + (Vector A , Vector B){return Vector(A.x+B.x,A.y+B.y);}
    Vector operator - (Vector A , Vector B){return Vector(A.x-B.x,A.y-B.y);}
    Vector operator * (Vector A , double p){return Vector(A.x*p,A.y*p);}
    Vector operator / (Vector A , double p){return Vector(A.x/p,A.y/p);}
    
    bool operator < (const Point& a,const Point& b){
        return a.x < b.x ||( a.x == b.x && a.y < b.y);
    }
    const double eps = 1e-10;
    int dcmp(double x){
        if(fabs(x) < eps) return 0;
        else              return x < 0 ? -1 : 1;
    }
    bool operator == (const Point& a, const Point& b){
        return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
    }
    
    ///向量(x,y)的极角用atan2(y,x);
    double Dot(Vector A, Vector B){ return A.x*B.x + A.y*B.y; }
    double Length(Vector A)    { return sqrt(Dot(A,A)); }
    double Angle(Vector A, Vector B)  { return acos(Dot(A,B) / Length(A) / Length(B)); }
    
    double Cross(Vector A, Vector B)  { return A.x*B.y - A.y * B.x; }
    double Area2(Point A,Point B,Point C) { return Cross(B-A,C-A); }
    
    ///向量的逆时针旋转,rad 为旋转的角;
    Vector Rotate(Vector A, double rad) { return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad)); }
    ///特殊的,下面函数计算向量的单位法向量,即左旋90,在长度归一化;
    Vector Normal(Vector A){
        double L = Length(A);
        return Vector(-A.y/L, A.x/L);
    }
    
    ///直线用参数式 P = P'+ t * v;P'为直线上一点,v为方向向量;
    ///t不受限制,为直线,t>0 为射线, 0=<t<=1为线段;
    ///推导暂时不会,下面计算直线P+tv和Q+tw的交点。调用前先确保两直线有唯一交点;即判定Cross(v,w) 非0;
    Point GetLineIntersecion(Point P, Vector v,Point Q,Vector w){
        Vector u = P - Q;
        double t = Cross(w,u)/Cross(v,w);
        return P + v*t;
    }
    
    ///求点到直线的距离,利用h*|AB| == AB(向量) * AP(向量);
    double DistanceToLine(Point P,Point A,Point B){
        Vector v1 = B - A, v2 = P - A;
        return fabs(Cross(v1,v2)) / Length(v1);
    }
    
    ///求点P到线段AB的距离,先看Q点在线段外还是内;利用点积就可以,
    double DistanceToSegment(Point P,Point A,Point B){
        if(A == B)  return Length(P-A);
        Vector v1 = B - A,v2 = P - A,v3 = P - B;
        if(dcmp(Dot(v1,v2)) < 0)       return Length(v2);
        else if(dcmp(Dot(v1,v3) > 0))  return Length(v2);
        else    return  fabs(Cross(v1,v2))/Length(v1);
    }
    ///如果要求Q的话:(当然满足Q在线段内),由公式Dot(v,P-(A+t'*v)) == 0 推出;
    Point GetLineProjection(Point P,Point A,Point B){
        Vector v = B - A;
        return A + v * (Dot(v,P-A)/Dot(v,v));
    }
    
    ///判定线段是否规范相交;
    bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2){
        double c1 = Cross(a2-a1,b1-a1), c2 = Cross(a2-a1,b2-a1),
               c3 = Cross(b2-b1,a1-b1), c4 = Cross(b2-b1,a2-b1);
        return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
    }
    ///如果允许在端点处相交:c1和c2都是0,表示两线段共线;如果只有其中一个为0,则一条线段的端点在另一条线段上;
    ///下面的代码判断一个点P是否在一条线段AB上;
    bool OnSegment(Point P,Point A,Point B){
        return dcmp(Cross(A-P,B-P)) == 0 && dcmp(Dot(P-A,P-B)) < 0;
    }
    
    ///多边形
    ///求面积
    double PolygonArea(Point* p,int n){
        double area = 0;
        for(int i=1;i<n-1;i++){
            area += Cross(p[i]-p[0],p[i+1]-p[0]);
        }
        return area/2;
    }
    
    Point GetOnePoint(Point A,Point B,Point C){
        Vector v1 = C-B;
        double a1 = Angle(A-B,v1);
        v1 = Rotate(v1,a1/3);
    
        Vector v2 = B-C;
        double a2 = Angle(A-C,v2);
        v2 = Rotate(v2,-a2/3);   ///负数表示顺时针旋转;
    
        return GetLineIntersecion(B,v1,C,v2);
    }
    Point read_point(){
        Point A;
        scanf("%lf %lf",&A.x,&A.y);
        return A;
    }
    
    int main()
    {
        //freopen("input.txt","r",stdin);
        //freopen("output.txt","w",stdout);
        int T;
        cin>>T;
        Point A,B,C,D,E,F;
        while(T--){
           A = read_point();
           B = read_point();
           C = read_point();
           D = GetOnePoint(A,B,C);
           E = GetOnePoint(B,C,A);
           F = GetOnePoint(C,A,B);
           printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf
    ",D.x,D.y,E.x,E.y,F.x,F.y);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Kinect 开发 —— 硬件设备解剖
    Kinect 开发 —— 引言
    (转)OpenCV 基本知识框架
    OpenCV —— 摄像机模型与标定
    OpenCV —— 跟踪与运动
    OpenCV —— 图像局部与分割(二)
    OpenCV —— 图像局部与部分分割(一)
    OpenCV —— 轮廓
    OpenCV —— 直方图与匹配
    OpenCV —— 图像变换
  • 原文地址:https://www.cnblogs.com/acmdeweilai/p/3243112.html
Copyright © 2011-2022 走看看