山東省第四屆 A Rescue The Princess

題目描述

    Several days ago, a beast caught a beautiful princess and the princess was put in prison. To rescue the princess, a prince who wanted to marry the princess set out immediately. Yet, the beast set a maze. Only if the prince find out the maze’s exit can he save the princess.

    Now, here comes the problem. The maze is a dimensional plane. The beast is smart, and he hidden the princess snugly. He marked two coordinates of an equilateral triangle in the maze. The two marked coordinates are A(x1,y1) and B(x2,y2). The third coordinate C(x3,y3) is the maze’s exit. If the prince can find out the exit, he can save the princess. After the prince comes into the maze, he finds out the A(x1,y1) and B(x2,y2), but he doesn’t know where the C(x3,y3) is. The prince need your help. Can you calculate the C(x3,y3) and tell him?

輸入

    The first line is an integer T(1 <= T <= 100) which is the number of test cases. T test cases follow. Each test case contains two coordinates A(x1,y1) and B(x2,y2), described by four floating-point numbers x1, y1, x2, y2 ( |x1|, |y1|, |x2|, |y2| <= 1000.0).
    Please notice that A(x1,y1) and B(x2,y2) and C(x3,y3) are in an anticlockwise direction from the equilateral triangle. And coordinates A(x1,y1) and B(x2,y2) are given by anticlockwise.

輸出

    For each test case, you should output the coordinate of C(x3,y3), the result should be rounded to 2 decimal places in a line.

示例輸入

4
-100.00 0.00 0.00 0.00
0.00 0.00 0.00 100.00
0.00 0.00 100.00 100.00
1.00 0.00 1.866 0.50

示例輸出

(-50.00,86.60)
(-86.60,50.00)
(-36.60,136.60)
(1.00,1.00)

#include <stdio.h>
#include <math.h>
const double pi = acos(-1.0);
int main()
{
    int t;
    double x1,x2,x3,y1,y2,y3,l,at;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
        at = atan2(y2-y1,x2-x1);
        l = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
        x3 = x1+l*cos(at+pi/3.0);
        y3 = y1+l*sin(at+pi/3.0);
        printf("(%.2lf,%.2lf)\n",x3,y3);
    }
    return 0;
}

漸漸體會到了數學的可愛and可怕之處了。。。

也知道爲什麼大部分大神都是深井冰狀態。。。


知識:

在C語言的math.h或C++中的cmath中有兩個求反正切的函數atan(double x)與atan2(double y,double x)  他們返回的值是弧度 要轉化爲角度再自己處理下。

前者接受的是一個正切值(直線的斜率)得到夾角,但是由於正切的規律性本可以有兩個角度的但它卻只返回一個,因爲atan的值域是從-90~90 也就是它只處理一四象限,所以一般不用它。

第二個atan2(double y,double x) 其中y代表已知點的Y座標 同理x ,返回值是此點與遠點連線與x軸正方向的夾角,這樣它就可以處理四個象限的任意情況了,它的值域相應的也就是-180~180了

例如:

例1:斜率是1的直線的夾角

cout<<atan(1.0)*180/PI;//45°

cout<<atan2(1.0,1.0)*180/PI;//45° 第一象限

cout<<atan2(-1.0,-1.0)*180/PI;//-135°第三象限

後兩個斜率都是1 但是atan只能求出一個45°

例2:斜率是-1的直線的角度

cout<<atan(-1.0)*180/PI;//-45°

cout<<atan2(-1.0,1.0)*180/PI;//-45° y爲負 在第四象限

cout<<atan2(1.0,-1.0)*180/PI;//135° x爲負 在第二象限

 

常用的不是求過原點的直線的夾角 往往是求一個線段的夾角 這對於atan2就更是如魚得水了

例如求A(1.0,1.0) B(3.0,3.0)這個線段AB與x軸正方向的夾角

用atan2表示爲 atan2(y2-y1,x2-x1) 即 atan2(3.0-1.0,3.0-1.0)

它的原理就相當於把A點平移到原點B點相應變成B'(x2-x1,y2-y1)點 這樣就又回到先前了

例三:

A(0.0,5.0) B(5.0,10.0)

線段AB的夾角爲

cout<<atan2(5.0,5.0)*180/PI;//45°

^_^


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章