首页 > 试题广场 >

正三角形的顶点位置

[编程题]正三角形的顶点位置
  • 热度指数:1334 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

给出直角三角坐标平面上三角形其中两个顶点的坐标,求第三个顶点的坐标,要求保留小数点后两位小数


输入描述:
有多组测试数据,输入的第一行是整数T(1≤T≤200)表示随后测试数据的组数。

每组测试数据占一行,由4个带两位小数由一个空格隔开的实数构成,表示已知的两个顶点的横纵坐标。


输出描述:
对应每组测试数据,输出对应的第三个顶点(两组解),如果两组解的横坐标不相等,则先输出横坐标较小的顶点,否则输出纵坐标较小的顶点,每组输出占一行,输出保留两位小数
示例1

输入

3
12.00 3.00 12.00 9.00
12.00 3.00 24.00 3.00
1.00 2.00 3.00 4.00

输出

6.80 6.00 17.20 6.00
18.00 -7.39 18.00 13.39
0.27 4.73 3.73 1.27
假设已知的两个点为p1和p2,第三个要求的点为p3。显然,向量p1->p2逆时针和顺时针旋转60°就可以得到向量p1->p3的坐标,而p1的坐标已知,进一步我们可以求得p3的两个可行解。
对于旋转角度Θ,有旋转矩阵为[[cosΘ,-sinΘ],[sinΘ,cosΘ]],用行向量右乘旋转矩阵就可以得到旋转后的向量坐标。
import java.lang.String;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

class Point {
    private double x, y;
    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
    
    public double getX() { return x; }
    
    public double getY() { return y; }
}

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine().trim());
        while(T-- > 0) {
            String[] params = br.readLine().trim().split(" ");
            Point point1 = new Point(Double.parseDouble(params[0]), Double.parseDouble(params[1]));
            Point point2 = new Point(Double.parseDouble(params[2]), Double.parseDouble(params[3]));
            Point[] points = getPoints(point1, point2);
            System.out.printf("%.2f %.2f %.2f %.2f\n",
                              points[0].getX(), points[0].getY(), points[1].getX(), points[1].getY());
        }
    }
    
    private static Point[] getPoints(Point p1, Point p2) {
        Point[] points = new Point[2];
        // 向量p1->p2的坐标
        Point v = new Point(p2.getX() - p1.getX(), p2.getY() - p1.getY());
        // 将向量分别逆时针和顺时针旋转60°就可以得到向量p1->p3的坐标
        double[][] rotate1 = new double[2][2];
        rotate1[0][0] = Math.cos(Math.toRadians(60));
        rotate1[0][1] = -Math.sin(Math.toRadians(60));
        rotate1[1][0] = Math.sin(Math.toRadians(60));
        rotate1[1][1] = Math.cos(Math.toRadians(60));
        Point v1 = new Point(v.getX()*rotate1[0][0] + v.getY()*rotate1[1][0],
                             v.getX()*rotate1[0][1] + v.getY()*rotate1[1][1]);
        double[][] rotate2 = new double[2][2];
        rotate2[0][0] = Math.cos(Math.toRadians(-60));
        rotate2[0][1] = -Math.sin(Math.toRadians(-60));
        rotate2[1][0] = Math.sin(Math.toRadians(-60));
        rotate2[1][1] = Math.cos(Math.toRadians(-60));
        Point v2 = new Point(v.getX()*rotate2[0][0] + v.getY()*rotate2[1][0],
                             v.getX()*rotate2[0][1] + v.getY()*rotate2[1][1]);
        // 而p1坐标已知,进一步可以求得p3的坐标
        Point p3_1 = new Point(v1.getX() + p1.getX(), v1.getY() + p1.getY());
        Point p3_2 = new Point(v2.getX() + p1.getX(), v2.getY() + p1.getY());
        // 按照题中要求的顺序排列两个点
        if(p3_1.getX() != p3_2.getX()){
            if(p3_1.getX() < p3_2.getX()){
                points[0] = p3_1;
                points[1] = p3_2;
            }else{
                points[0] = p3_2;
                points[1] = p3_1;
            }
        }else{
            if(p3_1.getY() < p3_2.getY()){
                points[0] = p3_1;
                points[1] = p3_2;
            }else{
                points[0] = p3_2;
                points[1] = p3_1;
            }
        }
        return points;
    }
}


发表于 2021-02-24 17:52:37 回复(0)
#include<iostream>
#include<iomanip>
#include<vector>
#include<cmath>
using namespace std;

int main()
{
    int n;    
    while(cin>>n)
    {
        vector<vector<double>> vec;
        for(int i=0;i<n;i++)
        {
            vector<double> v(4,0);
            cin>>v[0]>>v[1]>>v[2]>>v[3];
            vec.push_back(v);
        }
        for(int i=0;i<n;i++)
        {
            double mid_x=(vec[i][0]+vec[i][2])/2.0;
            double mid_y=(vec[i][1]+vec[i][3])/2.0;
            double l=sqrt((vec[i][0]-vec[i][2])*(vec[i][0]-vec[i][2])+(vec[i][1]-vec[i][3])*(vec[i][1]-vec[i][3]));
            double x1 = mid_x - sqrt(3.0) / 2.0*l*sin(atan((vec[i][1] - vec[i][3]) / (vec[i][2] - vec[i][0])));
			double y1 = mid_y - sqrt(3.0) / 2.0*l*cos(atan((vec[i][1] - vec[i][3]) / (vec[i][2] - vec[i][0])));
			double x2 = mid_x + sqrt(3.0) / 2.0*l*sin(atan((vec[i][1] - vec[i][3]) / (vec[i][2] - vec[i][0])));
			double y2 = mid_y + sqrt(3.0) / 2.0*l*cos(atan((vec[i][1] - vec[i][3]) / (vec[i][2] - vec[i][0])));
            if(x1<x2 ||(x1==x2&&y1<y2))
                cout<<fixed<<setprecision(2)<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<endl;
            else               
                cout<<fixed<<setprecision(2)<<x2<<" "<<y2<<" "<<x1<<" "<<y1<<endl;                  
        }
    }
}

发表于 2020-08-12 15:00:51 回复(0)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author wylu
 */
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int t = Integer.parseInt(br.readLine());

        while (t-- != 0) {
            String[] strs = br.readLine().split(" ");
            double x1 = Double.parseDouble(strs[0]), y1 = Double.parseDouble(strs[1]);
            double x2 = Double.parseDouble(strs[2]), y2 = Double.parseDouble(strs[3]);

            double dx = x2 - x1, dy = y2 - y1;
            double edgeLen = Math.sqrt(dx * dx + dy * dy);
            double height = Math.sqrt(3) / 2.0 * edgeLen;

            double resX1, resY1, resX2, resY2;
            if (dx == 0) {
                resX1 = x1 - height;
                resX2 = x1 + height;
                resY1 = (y1 + y2) / 2.0;
                resY2 = resY1;
            } else if (dy == 0) {
                resX1 = (x1 + x2) / 2.0;
                resX2 = resX1;
                resY1 = y1 - height;
                resY2 = y1 + height;
            } else {
                double midX = (x1 + x2) / 2.0, midY = (y1 + y2) / 2.0;
                double sine = Math.abs(dy / edgeLen), k = dy / dx;
                double ox = height * sine, oy = ox / k;
                resX1 = midX - ox;
                resY1 = midY + oy;
                resX2 = midX + ox;
                resY2 = midY - oy;
            }
            System.out.printf("%.2f %.2f %.2f %.2f\n", resX1, resY1, resX2, resY2);
        }
    }
}

发表于 2019-03-16 10:17:00 回复(0)
这道题我一开始读题目看到是直角坐标系以为是求直角三角形,说直角三角形怎么可能第三点只有两个,不是无穷多个吗?后来仔细看了一下题目,原来是求正三角形,也就是等边三角形
发表于 2020-04-13 17:43:56 回复(1)
我看不懂题目,居然有这么高的通过率,草率了,告辞
发表于 2022-05-12 18:19:06 回复(1)
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int t = sc.nextInt();
        while(t-- > 0){
            double x1 = sc.nextDouble(), y1 = sc.nextDouble(), 
                    x2 = sc.nextDouble(), y2 = sc.nextDouble();
            double dx = x2 - x1, dy = y2 - y1;
            double radians = Math.toRadians(60.0);
            double x3 = x1 + Math.cos(radians) * dx + Math.sin(radians) * dy
                 ,y3 = y1 - Math.sin(radians) * dx + Math.cos(radians) * dy;
            radians = Math.toRadians(-60.0);
            double x4 = x1 + Math.cos(radians) * dx + Math.sin(radians) * dy
                 ,y4 = y1 - Math.sin(radians) * dx + Math.cos(radians) * dy;
            if(x3 > x4 || (x3 == x4 && y3 > y4)){
                double tmp = x3;
                x3 = x4;
                x4 = tmp;
                tmp = y3;
                y3 = y4;
                y4 = tmp;
            }
            System.out.println(String.format("%.2f",x3) + " " + String.format("%.2f",y3) 
                               + " " + String.format("%.2f",x4) + " " + String.format("%.2f",y4));
        }
    }
}

发表于 2022-03-21 22:19:30 回复(0)
对于数值计算和用到公式的地方,python比java要方便很多,适合在时间紧迫的面试时候用
from math import sqrt
for i in range(int(input())):
    points = list(map(float, input().split()))
    value = [points[2] - points[0], points[3] - points[1]]
    side1 = [points[0] + value[0] / 2 - value[1] * sqrt(3) / 2, points[1] + value[1] / 2 + value[0] * sqrt(3) / 2] #c和d一左一右
    side2 = [points[0] + value[0] / 2 + value[1] * sqrt(3) / 2, points[1] + value[1] / 2 - value[0] * sqrt(3) / 2] #c和d一左一右
    if value[1] > 0:
        result = (side1[0], side1[1], side2[0], side2[1])
    elif value[1] < 0:
        result = (side2[0], side2[1], side1[0], side1[1])
    else:
        result = (side1[0], min(side1[1], side2[1]), side2[0], max(side1[1], side2[1]))
    print("%.2f %.2f %.2f %.2f" % result)

发表于 2021-03-31 16:39:40 回复(0)
#include<iostream>
#include<vector>
#include<math.h>
#include<algorithm>
#include<iomanip>
using namespace std;
int main()
{
    int n;
    while (cin >> n)
    {
        vector<vector<double>> p(n, vector<double>(4, 0));
        for (int i = 0; i < n; i++)
        {
            cin >> p[i][0]; cin >> p[i][1]; cin >> p[i][2]; cin >> p[i][3];
        }
        vector<pair<double, double>> temp;
        vector<vector<pair<double, double>>> res;
        double a1, b1; double a2, b2;
        double x, y;//中点
        double dx, dy;//从中点开始的坐标增量
        double l;//两点距离
        for (int i = 0; i < n; i++)
        {
            if (p[i][3] - p[i][1] == 0 || p[i][2] - p[i][0] == 0)//平行于x轴或者y轴
            {
                if (p[i][3] - p[i][1] == 0)
                {
                    pair<double, double> t;
                    t.first = (p[i][2] + p[i][0]) / 2;
                    t.second = p[i][3] + abs(p[i][2] - p[i][0]) * sqrt(3) / 2;
                    temp.push_back(t);
                    t.first = (p[i][2] + p[i][0]) / 2;
                    t.second = p[i][3] - abs(p[i][2] - p[i][0]) * sqrt(3) / 2;
                    temp.push_back(t);
                    sort(temp.begin(), temp.end());
                    res.push_back(temp);
                    temp.clear();
                }
                else
                {
                    pair<double, double> t;
                    t.first = p[i][2] + abs(p[i][1] - p[i][3]) * sqrt(3) / 2;
                    t.second = (p[i][1] + p[i][3]) / 2;
                    temp.push_back(t);
                    t.first = p[i][2] - abs(p[i][1] - p[i][3]) * sqrt(3) / 2;
                    t.second = (p[i][1] + p[i][3]) / 2;
                    temp.push_back(t);
                    sort(temp.begin(), temp.end());
                    res.push_back(temp);
                    temp.clear();
                }
            }
            else
            {
                a1 = (p[i][3] - p[i][1]) / (p[i][2] - p[i][0]);
                a2 = -1 / a1;
                x = (p[i][2] + p[i][0]) / 2; y = (p[i][3] + p[i][1]) / 2;
                //cout << x << " " << y << endl;
                b2 = y - a2 * x;
                l = sqrt(pow(p[i][3] - p[i][1], 2) + pow(p[i][2] - p[i][0], 2));
                dx = sqrt(pow(l * sqrt(3) / 2,2) / (1 + pow(a2, 2)));
                dy = abs(a2) * dx;
                //cout << dx << " " << dy << endl;
                pair<double, double> t;
                if (a2 > 0)
                {
                    t.first = x + dx;
                    t.second = y + dy;
                    temp.push_back(t);
                    t.first = x - dx;
                    t.second = y - dy;
                    temp.push_back(t);
                    sort(temp.begin(), temp.end());
                    res.push_back(temp);
                    temp.clear();
                }
                else
                {
                    t.first = x - dx;
                    t.second = y + dy;
                    temp.push_back(t);
                    t.first = x + dx;
                    t.second = y - dy;
                    temp.push_back(t);
                    sort(temp.begin(), temp.end());
                    res.push_back(temp);
                    temp.clear();
                }
            }
        }
        for (int i = 0; i < res.size(); i++)
        {
            cout << fixed;
            cout << setprecision(2) << res[i][0].first << " " << res[i][0].second << " " << res[i][1].first << " " << res[i][1].second << endl;
        }
    }
    return 0;
}

发表于 2020-11-21 14:58:43 回复(0)
#include<iostream>
#include<iomanip>
#include<cmath>
int main()
{
    int T;
    double b;
    while(std::cin>>T)
    {
        for(int i=0;i<T;i++)
        {
            double b[4]={0.0};
            for(int j=0;j<4;j++)std::cin>>b[j];
            if(b[0]==b[2])std::cout<<std::fixed<<std::setprecision(2)<<b[0]-abs(b[3]-b[1])*sqrt(3)/2<<" "<<(b[1]+b[3])/2<<" "<<b[0]+abs(b[3]-b[1])*sqrt(3)/2<<" "<<(b[1]+b[3])/2<<std::endl;
            else if(b[1]==b[3])std::cout<<std::fixed<<std::setprecision(2)<<(b[0]+b[2])/2<<" "<<b[1]-abs(b[2]-b[0])*sqrt(3)/2<<" "<<(b[0]+b[2])/2<<" "<<b[1]+abs(b[2]-b[0])*sqrt(3)/2<<std::endl;
            else
            {
                double k1=(b[3]-b[1])/(b[2]-b[0]);
                double k2=-1/k1;
                double x0=(b[0]+b[2])/2;
                double y0=(b[1]+b[3])/2;
                double d=(y0-b[1])*(y0-b[1])+(x0-b[0])*(x0-b[0]);
                std::cout<<std::fixed<<std::setprecision(2)<<x0-sqrt(3*d/(k2*k2+1))<<" "<<y0-k2*sqrt(3*d/(k2*k2+1))<<" "<<x0+sqrt(3*d/(k2*k2+1))<<" "<<y0+k2*sqrt(3*d/(k2*k2+1))<<std::endl;
            }

        }
    }
    return 0;
}
考一个数学专业的
发表于 2020-09-14 20:01:34 回复(0)
复数
from math import sqrt

for i in range(int(input())):
    a = list(map(float, input().split()))
    b = [a[2] - a[0], a[3] - a[1]]
    c = [a[0] + b[0] / 2 - b[1] * sqrt(3) / 2, a[1] + b[1] / 2 + b[0] * sqrt(3) / 2]
    d = [a[0] + b[0] / 2 + b[1] * sqrt(3) / 2, a[1] + b[1] / 2 - b[0] * sqrt(3) / 2]
    if b[1] > 0: o = (c[0], c[1], d[0], d[1])
    elif b[1] < 0: o = (d[0], d[1], c[0], c[1])
    else: o = (c[0], min(c[1], d[1]), d[0], max(c[1], d[1]))
    print("%.2f %.2f %.2f %.2f" % o)

发表于 2020-07-15 22:11:13 回复(0)
看不懂题目,能构成直角三角形的第三个点不是有无数个吗

发表于 2019-09-05 15:21:37 回复(4)
import math
n=int(input())
arr=[] for i in range(n):
    arr.append([float(x) for x in input().split()])
c,midx,midy,l,px1,px2,py1,py2=[],[],[],[],[],[],[],[] for i in range(n):
    c.append(math.sqrt((arr[i][0]-arr[i][2])**2+(arr[i][1]-arr[i][3])**2))
    midx.append(abs((arr[i][0]+arr[i][2])/2))
    midy.append(abs((arr[i][1]+arr[i][3])/2))
    l.append((math.sqrt(3)/2)*c[i])
    px1.append(midx[i]-abs(arr[i][1]-arr[i][3])/c[i]*l[i])
    px2.append(midx[i]+abs(arr[i][1]-arr[i][3])/c[i]*l[i])
    temp1=arr[i][3]-arr[i][1]
    temp2=arr[i][2] - arr[i][0] if temp1!=0 and temp2!=0:
        py1.append(
            midy[i] + abs(arr[i][0] - arr[i][2]) / c[i] * l[i] * ((arr[i][3] - arr[i][1])*(arr[i][2] - arr[i][0]))/abs(((arr[i][3] - arr[i][1])*(arr[i][2] - arr[i][0]))))
        py2.append(
            midy[i] - abs(arr[i][0] - arr[i][2]) / c[i] * l[i] * ((arr[i][3] - arr[i][1])*(arr[i][2] - arr[i][0]))/abs(((arr[i][3] - arr[i][1])*(arr[i][2] - arr[i][0])))) else:
        py1.append(midy[i] + abs(arr[i][0] - arr[i][2]) / c[i] * l[i])
        py2.append(midy[i] - abs(arr[i][0] - arr[i][2]) / c[i] * l[i]) for i in range(n): if px1[i]>px2[i]: print('%.2f %.2f %.2f %.2f'%(px2[i],py2[i],px1[i],py1[i])) elif px1[i]<px2[i]: print('%.2f %.2f %.2f %.2f'%(px1[i],py1[i],px2[i],py2[i])) else: if py1[i]>py2[i]: print('%.2f %.2f %.2f %.2f'%(px2[i],py2[i],px1[i],py1[i])) else: print('%.2f %.2f %.2f %.2f'%(px1[i],py1[i],px2[i],py2[i]))
发表于 2019-06-19 00:12:55 回复(0)
嗯...不能用float,要用double...
发表于 2019-06-12 12:36:47 回复(0)
纯数学题
#include<iostream>
#include<algorithm>
#include<iomanip>
using namespace std;
int main()
{
    int n;
    cin>>n;
    double g3=sqrt(3);
    for(int i=0;i<n;i++)
    {
        double x1,y1,x2,y2,x0,y0,d,x,y,xx,yy,k,hx,hy;
        cin>>x1>>y1>>x2>>y2;
        if(x2==x1)
        {
            d=abs(y2-y1);
            y=min(y1,y2)+d/2;
            yy=y;
            x=x1+d*g3/2;
            xx=x1-d*g3/2;
        }
        else if(y2==y1)
        {
            d=abs(x2-x1);
            x=min(x1,x2)+d/2;
            xx=x;
            y=y1+d*g3/2;
            yy=y1-d*g3/2;
        }
        else
        {
            d=sqrt(pow((y2-y1),2)+pow((x2-x1),2));
            k=(x1-x2)/(y2-y1);
            x0=(x1+x2)/2;y0=(y1+y2)/2;
            hx=g3*d/2/sqrt(1+pow(k,2));
            hy=abs(k*hx);
            if(k<0)
            {
                xx=x0-hx;
                yy=y0+hy;
                x=x0+hx;
                y=y0-hy;
            }
            else
            {
                xx=x0-hx;
                yy=y0-hy;
                x=x0+hx;
                y=y0+hy;
            }
        }
        cout<<setiosflags(ios::fixed)<<setprecision(2);
        cout<<xx<<" "<<yy<<" "<<x<<" "<<y<<endl;
    }
    return 0;
}

发表于 2019-04-28 10:55:57 回复(4)
圆和直线方程
发表于 2019-01-14 23:46:38 回复(0)

问题信息

上传者:小小
难度:
15条回答 3576浏览

热门推荐

通过挑战的用户

查看代码
正三角形的顶点位置