2016 Multi-University Training Contest 1-1011---HDU 5733 tetrahedron(计算几何)

本文主要是介绍2016 Multi-University Training Contest 1-1011---HDU 5733 tetrahedron(计算几何),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  1. 题目链接
    HDU 5733
  2. 题意:
    给出一个四面体的四个点,求内切球的半径和圆心。
  3. 题解:
    设四面体的四个顶点分别为 A1 , A2 , A3 , A4
    • 四面体内切球半径
      四面体的总体积:
      V=VPA2A3A4+VPA1A3A4+VPA1A2A4+VPA1A2A3

      =R3(SA2A3A4+SA1A3A4+SA1A2A4+SA1A2A3)

      =R3(S1+S2+S3+S4)

      内切球半径:
      R=3V(SA2A3A4+SA1A3A4+SA1A2A4+SA1A2A3)

      =3V(S1+S2+S3+S4)

      由任意四面体的体积公式可有:
      V=|(A1A4)[(A2A4)×(A3A4)]|6

      又由三个向量混合积的几何意义:
      R=|(A1A4)[(A2A4)×(A3A4)]|/2(S1+S2+S3+S4)

      又由两个向量叉积的几何意义:
      S1=(A2A4)(A3A4)/2

      S2=(A4A1)(A3A1)/2

      S3=(A4A1)(A2A1)/2

      S4=(A3A1)(A2A4)/2

      所以:
      R=|(A1A4)[(A2A4)×(A3A4)]|((A2A4)(A3A4)+(A4A1)(A3A1)+(A4A1)(A2A1)+(A3A1)(A2A4))
    • 四面体内心坐标
      对四面体内任意一点 P , 我们用P⃗ 表示 OP , 有
      P⃗ =i=14λiA⃗ i=λ1A⃗ 1+λ2A⃗ 2+λ3A⃗ 3+λ4A⃗ 4

      其中 0λ1,λ2,λ3,λ41 ,且 4i=1λi=λ1+λ2+λ3+λ4=1 ,则称 (λ1,λ2,λ3,λ4) 为 P 点关于四面体A1A2A3A4 的体积坐标 。
      体积坐标具有明显的几何意义, 其各坐标分量是以 P 为顶点, 以各底面为底的四面体体积与原四面体体积之比。即:
      λ1=VPA2A3A4VA1A2A3A4

      λ2=VPA1A3A4VA1A2A3A4

      λ3=VPA1A2A4VA1A2A3A4

      λ4=VPA1A2A3VA1A2A3A4

      记四面体 A1A2A3A4 的四个底面的面积分别为 S1,S2,S3,S4 , 若P是四面体 A1A2A3A4 的内心 I ,因为内心到四个面的距离相等,则有
      λi=SiS1+S2+S3+S4,i=1,2,3,4


      OI=i=14λiAi=i=14SiAii=14Si

      从而I的直角坐标(x, y, z)为:
      x=i=14Sixii=14Si

      y=i=14Siyii=14Si

      z=i=14Sizii=14Si

      与上面一样面积可以表示成向量叉积的形式:
      S1=(A2A4)(A3A4)/2

      S2=(A4A1)(A3A1)/2

      S3=(A4A1)(A2A1)/2

      S4=(A3A1)(A2A4)/2

      代入计算即可。
  4. 代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps=1e-8;
int dcmp(double a)
{if(fabs(a)<eps) return 0;return a>0?1:-1;
}
struct point3
{double x,y,z;point3(double _x=0,double _y=0,double _z=0):x(_x),y(_y),z(_z){};point3( const point3& a ){x = a.x;y = a.y;z = a.z;}
};
typedef point3 vector3;
vector3 operator +(vector3 a,vector3 b)
{return vector3(a.x+b.x,a.y+b.y,a.z+b.z);
}
vector3 operator -(vector3 a,vector3 b)
{return vector3(a.x-b.x,a.y-b.y,a.z-b.z);
}vector3 operator *(vector3 a,double k)
{return vector3(a.x*k,a.y*k,a.z*k);
}vector3 operator /(vector3 a,double k)
{return vector3(a.x/k,a.y/k,a.z/k);
}vector3 Cross3(vector3 u,vector3 v)
{point3 ret;ret.x = u.y * v.z - u.z * v.y;ret.y = u.z * v.x - u.x * v.z;ret.z = u.x * v.y - u.y * v.x;return ret;
}double Dot3( vector3 u, vector3 v )
{return u.x * v.x + u.y * v.y + u.z * v.z;
}
double len(vector3 a)
{return sqrt(Dot3(a,a));
}int main()
{//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);point3 a,b,c,d;while(cin>>a.x>>a.y>>a.z>>b.x>>b.y>>b.z>>c.x>>c.y>>c.z>>d.x>>d.y>>d.z){if(dcmp(Dot3(b-a,Cross3(c-a,d-a)))==0) printf("O O O O\n");else {vector3 v1=Cross3(b-a,c-a);vector3 v2=Cross3(b-a,d-a);vector3 v3=Cross3(c-a,d-a);vector3 v4=Cross3(c-b,d-b);double r=fabs(Dot3(a-d,Cross3(b-d,c-d)))/(len(v1)+len(v2)+len(v3)+len(v4));double x=(d.x*len(v1)+c.x*len(v2)+b.x*len(v3)+a.x*len(v4))/(len(v1)+len(v2)+len(v3)+len(v4));double y=(d.y*len(v1)+c.y*len(v2)+b.y*len(v3)+a.y*len(v4))/(len(v1)+len(v2)+len(v3)+len(v4));double z=(d.z*len(v1)+c.z*len(v2)+b.z*len(v3)+a.z*len(v4))/(len(v1)+len(v2)+len(v3)+len(v4));printf("%.4lf %.4lf %.4lf %.4lf\n",x,y,z,r);}}return 0;
}

这篇关于2016 Multi-University Training Contest 1-1011---HDU 5733 tetrahedron(计算几何)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1049707

相关文章

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

mysqld_multi在Linux服务器上运行多个MySQL实例

《mysqld_multi在Linux服务器上运行多个MySQL实例》在Linux系统上使用mysqld_multi来启动和管理多个MySQL实例是一种常见的做法,这种方式允许你在同一台机器上运行多个... 目录1. 安装mysql2. 配置文件示例配置文件3. 创建数据目录4. 启动和管理实例启动所有实例

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

如何用Java结合经纬度位置计算目标点的日出日落时间详解

《如何用Java结合经纬度位置计算目标点的日出日落时间详解》这篇文章主详细讲解了如何基于目标点的经纬度计算日出日落时间,提供了在线API和Java库两种计算方法,并通过实际案例展示了其应用,需要的朋友... 目录前言一、应用示例1、天安门升旗时间2、湖南省日出日落信息二、Java日出日落计算1、在线API2

usaco 1.3 Mixing Milk (结构体排序 qsort) and hdu 2020(sort)

到了这题学会了结构体排序 于是回去修改了 1.2 milking cows 的算法~ 结构体排序核心: 1.结构体定义 struct Milk{int price;int milks;}milk[5000]; 2.自定义的比较函数,若返回值为正,qsort 函数判定a>b ;为负,a<b;为0,a==b; int milkcmp(const void *va,c

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

hdu 2093 考试排名(sscanf)

模拟题。 直接从教程里拉解析。 因为表格里的数据格式不统一。有时候有"()",有时候又没有。而它也不会给我们提示。 这种情况下,就只能它它们统一看作字符串来处理了。现在就请出我们的主角sscanf()! sscanf 语法: #include int sscanf( const char *buffer, const char *format, ... ); 函数sscanf()和

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :