`
阿尔萨斯
  • 浏览: 4170396 次
社区版块
存档分类
最新评论

POJ 1673 EXOCENTER OF A TRIANGLE(证明+求三角形垂心)

 
阅读更多

POJ 1673 EXOCENTER OF A TRIANGLE(证明+求三角形垂心)

http://poj.org/problem?id=1673

题意: ZOJ 1821

有一个三角形ABC,扩展它的三边构成3个相邻的矩形,然后连接相邻矩形的两个顶点构成3个新的三角形,然后连接着3个新三角形的中线,交与1点O.要求你O的坐标?

分析:

其实本题就是求三角形ABC的垂心,下面是证明:

先将△EBJ绕B点逆时针旋转90度,这时EB与AB重合,BJ与BC共线。之所以BJ与BC共线是因为∠ABC和∠EBJ之前是互补的。这时,就会出现一个大的组合而成的三角形△JAC,同时BC=BJ,ME=MJ,所以ME是△JAC的中位线,因此BM平行于AC。而BM是旋转90度之后平行于AC的,于是之前BM就是垂直于AC的了,进而就可以得到O是△ABC的垂心。

现在问题是如何求垂心呢? 已知三角形3,只需要用它的两条边的法向量(直线)相交即可得到垂心.

AC代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps=1e-10;
int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    return x<0?-1:1;
}

struct Point
{
    double x,y;
    Point(){}
    Point(double x,double y):x(x),y(y){}
};
typedef Point Vector;
Vector operator-(Point A,Point 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);
}
double Cross(Vector A,Vector B)
{
    return A.x*B.y-A.y*B.x;
}
Vector Normal(Vector A)//返回A的法向量
{
    return Vector(-A.y,A.x);
}
Point GetLineIntersection(Point P,Vector v,Point Q,Vector w)
{
    Vector u=P-Q;
    double t=Cross(w,u)/Cross(v,w);
    return P+v*t;
}

int main()
{
    int n; scanf("%d",&n);
    while(n--)
    {
        Point A,B,C;
        scanf("%lf%lf%lf%lf%lf%lf",&A.x,&A.y,&B.x,&B.y,&C.x,&C.y);
        Point O=GetLineIntersection(A,Normal(B-C),B,Normal(A-C));
        printf("%.4lf %.4lf\n",O.x,O.y);
    }
    return 0;
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics