方法
由两端点、
的中点
、边长
和斜率
计算第三个端点
的两个可能位置
、
(前者在左下,后者在右上):
- 由已有的两个端点坐标
和
,计算中点
坐标和边长
;
- 分三种情况
- k=无穷。
和
的连线垂直于
轴,即
与
接近(浮点数不能判等),
,
、
;
- k=0。
和
的连线垂直于
轴,即
与
接近,
,
、
;
- k为其他值(计算时无风险),首先根据
和
计算斜率
,再计算点
和
所在直线的斜率
,然后根据三角形几何关系可知
,
。
- 如果
,
、
;
- 否则,
,
、
;
- 如果
- k=无穷。
注意
- 浮点数不能判等,两者的差值小于一定范围即可认为相等。
- 要使用double,float会有误差。
- 其次要使用double对应的sqrt、pow,不能使用sqrtf、powf。
#include <iostream>
#include <cmath>
using namespace std;
typedef double FT;
bool isClose(FT v1, FT v2){
return abs(v1-v2) < 10e-5;
}
FT center(FT v1, FT v2){
return (v1+v2)/2;
}
FT dist(FT x1, FT y1, FT x2, FT y2){
return sqrt(pow(x1-x2, 2.0) + pow(y1-y2, 2.0));
}
int main()
{
int n;
FT factor = pow(3, 0.5) / 2; // 二分之根号三
while(cin >> n)
{
for(int i=0; i<n; i++)
{
FT x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
FT x31, y31, x32, y32;
FT cx = center(x1, x2), cy = center(y1, y2);
FT r = dist(x1, y1, x2, y2);
FT offset_x, offset_y;
if(isClose(x1, x2)){
// 这条边是竖直的,可能的端点在左右
offset_x = r * factor;
x31 = cx - offset_x; y31 = cy;
x32 = cx + offset_x; y32 = cy;
}
else if(isClose(y1, y2)){
// 这条边是水平的,可能的端点在上下
offset_y = r * factor;
x31 = cx; y31 = cy - offset_y;
x32 = cx; y32 = cy + offset_y;
}
else{
// 这条边是倾斜的,
FT k_12 = (y2 - y1) / (x2 - x1);
FT k_34 = (-1.0) / k_12;
offset_x = sqrt((3.0 * r * r) / (4.0 * (1 + k_34 * k_34)));
offset_y = abs(k_34) * offset_x;
if(k_34 < 0){
x31 = cx - offset_x; y31 = cy + offset_y;
x32 = cx + offset_x; y32 = cy - offset_y;
}
else{
x31 = cx - offset_x; y31 = cy - offset_y;
x32 = cx + offset_x; y32 = cy + offset_y;
}
}
printf("%.2f %.2f %.2f %.2f\n", x31, y31, x32, y32);
}
}
return 0;
}

京公网安备 11010502036488号