题目概述
给定三个不共线点的坐标,求一圆,使三个点都在圆上
时限
1000ms/3000ms
输入
每行六个浮点数,描述三个点的坐标,输入到EOF为止
限制
没有限制
输出
每组数据输出在两行中,第一行为圆的标准方程,第二行为圆的一般方程,具体参见样例,每组输出后带一空行
样例输入
7.0 -5.0 -1.0 1.0 0.0 -6.0
1.0 7.0 8.0 6.0 7.0 -2.0
样例输出
(x - 3.000)^2 + (y + 2.000)^2 = 5.000^2
x^2 + y^2 - 6.000x + 4.000y - 12.000 = 0(x - 3.921)^2 + (y - 2.447)^2 = 5.409^2
x^2 + y^2 - 7.842x - 4.895y - 7.895 = 0
讨论
计算几何,解析几何,利用三个点求出两条中垂线,其交点为圆心,到任意一个点距离为半径,求交点方法依然是定比分点,取得中垂线上点的方法有些类似于方向向量,都是固定方法
实现上,就是这个破输出格式需要注意,由于符号到数字之间有空格,因而需要分开输出,利用?:算符确定符号,对输出的数字则要取模,注意一般式不要算错,这可是高中的刚学的
感觉是又复习了一下计算几何最基础的那几个函数
题解状态
164K,0MS,C++,1704B
题解代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 0
#define memset0(a) memset(a,0,sizeof(a))
#define EPS 1e-8
double dis(double x1, double y1, double x2, double y2)//两点间距离
{
return sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2));
}
double xp(double x1, double y1, double x2, double y2, double x3, double y3)//向量积
{
return (x1 - x2)*(y3 - y2) - (y1 - y2)*(x3 - x2);
}
void point_of_intersection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double &poix, double &poiy)//十个参数的交点公式 最后两个做返回值 这三个函数仍然是那么熟悉
{
double Sabc = xp(x3, y3, x1, y1, x2, y2), Sabd = xp(x4, y4, x1, y1, x2, y2);
poix = (Sabc*x4 - Sabd*x3) / (Sabc - Sabd);
poiy = (Sabc*y4 - Sabd*y3) / (Sabc - Sabd);
}
void fun(double x1, double y1, double x2, double y2, double x3, double y3)
{
double mp1x = (x1 + x2) / 2, mp1y = (y1 + y2) / 2;//midpoint 中点
double p1x = mp1x + mp1y - y1, p1y = mp1y - mp1x + x1;//这个公式直接写不好理解 但是作图的话很容易有“显然成立”的感觉
double mp2x = (x3 + x2) / 2, mp2y = (y3 + y2) / 2;
double p2x = mp2x + mp2y - y3, p2y = mp2y - mp2x + x3;
double Ox, Oy, r;//圆心及半径
point_of_intersection(mp1x, mp1y, p1x, p1y, mp2x, mp2y, p2x, p2y, Ox, Oy);
r = dis(Ox, Oy, x2, y2);
printf("(x %c %.3lf)^2 + (y %c %.3lf)^2 = %.3lf^2\n", Ox >= 0 ? '-' : '+', abs(Ox), Oy >= 0 ? '-' : '+', abs(Oy), r);//output//注意标准式中两个符号原本就是减号
printf("x^2 + y^2 %c %.3lfx %c %.3lfy %c %.3lf = 0\n\n", Ox >= 0 ? '-' : '+', 2 * abs(Ox), Oy >= 0 ? '-' : '+', 2 * abs(Oy), r*r - Ox*Ox - Oy*Oy > 0 ? '-' : '+', abs(r*r - Ox*Ox - Oy*Oy));//output
}
int main(void)
{
//freopen("vs_cin.txt", "r", stdin);
//freopen("vs_cout.txt", "w", stdout);
double x1, y1, x2, y2, x3, y3;//由于y1在头文件中有重名函数 因而没法作为全局变量
while (~scanf("%lf%lf%lf%lf%lf%lf", &x1, &y1, &x2, &y2, &x3, &y3))//input
fun(x1, y1, x2, y2, x3, y3);
}
EOF