关闭

Sicily 1059. Exocenter of a Trian

标签: sicily
638人阅读 评论(0) 收藏 举报
分类:

题目大意:几何法计算三角形ABC的垂心

解题思路:根据题意解题即可,但是计算过程需要三个主要的函数。

1.向量旋转ratate():把向量分解成平行于x坐标轴和y坐标轴的向量,再分别旋转,最合把旋转结果合并。

2.求中点middle():返回两点中点即可。

3.求两直线交点intersection():只需计算两条直线即可求出交点,但是需要判断直线是否有斜率,分类讨论。


// 1059. Exocenter of a Trian
// 计算三角形的垂心 

#include <iostream>
#include <cmath>
#include <stdlib.h>
#include <stdio.h>
  
using namespace std;  

#define PI 3.141592654
#define EPS 1E-6
#define INF 1E+15

struct Point{
    double x,y;
    Point(){}
    Point( double x0, double y0 ){
        x = x0;
        y = y0;    
    }  
    
    Point& operator + ( const Point& p ){
        x = p.x + x;
        y = p.y + y;
        return *this;    
    } 
    // 两点相减得到的点代表方向向量 
    Point operator - ( const Point& p ){
        return Point( x - p.x, y - p.y );    
    } 
};

struct Line{
    double k,b;
    Line(){}
    Line( const Point& p1, const Point& p2 ){
        // 是否为垂直直线,有无斜率进行判断 
        if( fabs(p1.x - p2.x) < EPS ){
            k = INF;
            b = p1.x;
        }else{
            k = ( p1.y - p2.y )/( p1.x - p2.x );
            b = p1.y - k * p1.x; 
        }           
    }   
};

Point rotate( const Point& v, double angle );            // 向量旋转 
Point middle( const Point& p1, const Point& p2 );        // 取两点中点 
Point intersection( const Line& l1, const Line& l2 );    // 求两直线交点 

int main () {
    //freopen("D:\\input.txt","r",stdin); 
    int m;
    double x,y;
    Point A,B,C;
    
    cin >> m;
    while( m-- ){
        scanf("%lf%lf",&A.x,&A.y);
        scanf("%lf%lf",&B.x,&B.y);
        scanf("%lf%lf",&C.x,&C.y);
        
        Point D,G,L,E,J,M,O;
        D = rotate( B-A, PI/2 ) + A;
        G = rotate( C-A, -PI/2 ) + A;
        L = middle( D, G );
        
        E = rotate( A-B, -PI/2 ) + B;
        J = rotate( C-B, PI/2 ) + B;
        M = middle( E, J );
        
        O = intersection( Line(L,A), Line(M,B) );
        
        // 对x,y修正,未修正会WA 
        x = fabs(O.x) < EPS ? 0 : O.x; 
        y = fabs(O.y) < EPS ? 0 : O.y; 
        
        printf( "%.4lf %.4lf\n", x, y );          
    }
 
    return 0;  
} 

// 将向量v分解为x,y轴方向向量分别进行旋转后再进行合成 
Point rotate( const Point& v, double angle ){
    Point res;
    res.x = v.x * cos(angle) - v.y * sin(angle);
    res.y = v.x * sin(angle) + v.y * cos(angle);
    return res;    
}

Point middle( const Point& p1, const Point& p2 ){
    return Point( (p1.x + p2.x)/2.0, (p1.y + p2.y)/2.0 );    
} 

Point intersection( const Line& l1, const Line& l2 ){
    Point o;
    if( l1.k == INF ){              // 直线l1为垂直直线,无斜率 
        o.x = l1.b;
        o.y = l2.k * o.x + l2.b;
    }else if( l2.k == INF ){        // 直线l2为垂直直线,无斜率 
        o.x = l2.b;
        o.y = l1.k * o.x + l1.b;
    }else{                          // 直线l1,l2均不为垂直直线,有斜率 
        o.x = ( l1.b - l2.b )/( l2.k - l1.k );
        o.y = l1.k * o.x + l1.b;
    }    
    return o;
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:18212次
    • 积分:469
    • 等级:
    • 排名:千里之外
    • 原创:28篇
    • 转载:2篇
    • 译文:0篇
    • 评论:8条
    文章分类
    最新评论