Sicily.1059. Exocenter of a Trian(求垂心,向量旋转)

/* 1059. Exocenter of a Trian
   题目大意: 给出三角形ABC三点坐标,如图所示,作正方形ABDE,正方形BCHJ,
   正方形CAGF,L为DG中点,M为EJ中点,N为FH中点,直线LA,MB,NC交于同一点O,求点O的坐标。
   其实O就是其垂心
   
   思路:1、先通过向量旋转分别得到D、G、F、H,由于求两直线交点只需两条直线即可,
            所以EJ不用求。(向量旋转90) 
         2、求DG中点L和FH中点N,然后求直线LA和NC的交点
         3、这里求两直线交点有三种情况 1.LA无斜率  2.NC无斜率 3.都有斜率 
*/

#include<iostream>
#include<cmath>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
const double PI = 3.1415926535897932384626433832795;
const double eps = 1e-8;

int dcmp(double x){return x < -eps ? -1 : x > eps ;}
 
double fix(double x){
     if(dcmp(x)==0)return 0;
     return x;
}
 
struct Point {
     double x, y;
     Point() {}
     Point(double x0, double y0): x(x0), y(y0) {}
};
 
double operator*(Point p1, Point p2) // 计算叉乘 p1 × p2
{
     return (p1.x * p2.y - p2.x * p1.y);
}
Point operator-(Point p1, Point p2)
{
     return Point(p1.x - p2.x, p1.y - p2.y);
}
Point operator+(Point p1, Point p2)
{
     return Point(p1.x + p2.x, p1.y + p2.y);
}
Point Rotate(Point p, double angle)
{
    Point result;
    result.x = p.x * cos(angle) - p.y * sin(angle);
    result.y = p.x * sin(angle) + p.y * cos(angle);
    return result;
 }
double Area(Point A, Point B, Point C) //三角形面积
{
     return ((B-A)*(C-A) / 2.0);
}
//无斜率 
Point withoutSlop(double x, Point p1, Point p2 ){
       double k = (p1.y- p2.y)/(p1.x - p2.x);
       double b = p1.y  - k * p1.x;
       Point result;
       result.x = x;
       result.y = x * k + b;
       return result;
 }
 //都有斜率 
 Point withSlop(Point p1, Point p2, Point p3, Point p4){
       double k1 = (p1.y- p2.y)/(p1.x - p2.x);
       double b1 = p1.y  - k1 * p1.x;
       
       double k2 = (p3.y- p4.y)/(p3.x - p4.x);
       double b2 = p3.y  - k2 * p3.x;
       Point result;
       result.x = (b1-b2)/(k2-k1);
       result.y = k1 * result.x + b1;
       return result;
 }
 //求直线交点 
 Point intersection(Point p1,Point p2,Point p3,Point p4){
     Point result;
     //浮点数绝对值为fabs,整数为abs 
     if(fabs(p1.x - p2.x) < eps)
        result = withoutSlop(p1.x, p3,p4);
     else
        if(fabs(p3.x-p4.x) < eps)
          result = withoutSlop(p3.x, p1,p2);
        else
          result = withSlop(p1,p2,p3,p4);
     return result;
 }
 
 
 int main()
 {
     int T, cas;
     Point A, B, C;
     scanf("%d",&T);
     for(cas = 0; cas < T; cas++)
     {
         scanf("%lf%lf",&A.x, &A.y);
         scanf("%lf%lf",&B.x, &B.y);
         scanf("%lf%lf",&C.x, &C.y);
         if(Area(A,B,C) < 0)swap(B,C);
         Point D, G, F, H, L, N, ans;
         //如向量AB=(B-A),旋转90后,变成AD=(D-A); 所以D = Rotate(B-A,-PI/2) + A 
         D = Rotate(B - A,-PI/2) + A;
         G = Rotate(C - A, PI/2) + A;
         L = (D + G);
         L.x/=2; L.y/=2;
 
         F = Rotate(A - C,-PI/2) + C;
         H = Rotate(B - C, PI/2) + C;
         N = (F + H);
         N.x/=2; N.y/=2;
         ans = intersection(A, L, C, N);
         printf("%.4lf %.4lf\n",fix(ans.x), fix(ans.y));
     }
     system("pause");
     return 0;
 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值