题目大意:几何法计算三角形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;
}