您的位置:首页 > 其它

三角形内切圆与外接圆的面积比

2014-01-15 12:01 148 查看
CSDN编程挑战里的题目

一个三角形必然存在它的内切圆与外接圆,求他们的面积比。
考虑到精度问题,我们输出面积比*1000的整数部分(直接下取整)。
输入数据是一个三角形的三个顶点,但这三个顶点在三维空间中,
所以输入是9个整数,分别表示三个顶点(x1,y1,z1) (x2,y2,z2) (x3,y3,z3),
保证三点不共线,每个整数在-1000,+1000范围内。
输出内接圆与外切圆的面积比*1000的整数部分。

这题好搞,图形学我是专业的.

#include <cmath>
#include <cstring>
#include <cstdio>
#include <cfloat>

// 内切圆半径
// 内切圆半径r=2S/(a+b+c),其中S是三角形面积,a、b、c是三角形三边。
// 另外S=根号下p(p-a)(p-b)(p-c),其中p=(a+b+c)/2
float TrinagleInCircle(float xA, float yA, float zA,
float xB, float yB, float zB,
float xC, float yC, float zC)
{
float ab = (xA - xB)*(xA - xB) + (yA - yB)*(yA - yB) + (zA - zB)*(zA - zB);
float bc = (xC - xB)*(xC - xB) + (yC - yB)*(yC - yB) + (zC - zB)*(zC - zB);
float ca = (xA - xC)*(xA - xC) + (yA - yC)*(yA - yC) + (zA - zC)*(zA - zC);

ab = sqrtf(ab);
bc = sqrtf(bc);
ca = sqrtf(ca);

float p = (ab+bc+ca)/2;

float s = p*(p-ab)*(p-bc)*(p-ca);
if (s < FLT_EPSILON)
{
return 0.0f;
}
s = sqrtf(s);

if (ab+bc+ca < FLT_EPSILON)
{
return 0.0f;
}

float r = 2*s/(ab+bc+ca);

return r;
}

// 外接圆半径
// 已知三角形三边长a,b,c ,及其外接圆的半径R
// s=a*b*c/(4*R)      (多半用于求外接圆半径 R=a*b*c/(4*s)
float TrinagleOutCircle(float xA, float yA, float zA,
float xB, float yB, float zB,
float xC, float yC, float zC)
{
float ab = (xA - xB)*(xA - xB) + (yA - yB)*(yA - yB) + (zA - zB)*(zA - zB);
float bc = (xC - xB)*(xC - xB) + (yC - yB)*(yC - yB) + (zC - zB)*(zC - zB);
float ca = (xA - xC)*(xA - xC) + (yA - yC)*(yA - yC) + (zA - zC)*(zA - zC);

ab = sqrtf(ab);
bc = sqrtf(bc);
ca = sqrtf(ca);

float p = (ab+bc+ca)/2;

float s = p*(p-ab)*(p-bc)*(p-ca);
if (s < FLT_EPSILON)
{
return 0.0f;
}
s = sqrtf(s);

float r = ab*bc*ca/(4*s);

return r;
}

int ratio (int   x1,int   y1,int   z1,int   x2,int   y2,int   z2,int   x3,int   y3,int   z3)
{
float r = TrinagleInCircle(float(x1), float(y1), float(z1), float(x2), float(y2), float(z2), float(x3), float(y3), float(z3));
float R = TrinagleOutCircle(float(x1), float(y1), float(z1), float(x2), float(y2), float(z2), float(x3), float(y3), float(z3));
if (R < FLT_EPSILON || r < FLT_EPSILON)
{
return 0;
}
return (int)(1000*R*R/r/r);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: