DESCRIPTION:

判断空间点 P(x, y, z)是否在一个四面体的内部?

Let the tetrahedron have vertices

        V1 = (x1, y1, z1)
V2 = (x2, y2, z2)
V3 = (x3, y3, z3)
V4 = (x4, y4, z4)

and your test point be

        P = (x, y, z).

Then the point P is in the tetrahedron if following fivedeterminants all have the same sign.

             |x1 y1 z1 1|
D0 = |x2 y2 z2 1|
|x3 y3 z3 1|
|x4 y4 z4 1| |x y z 1|
D1 = |x2 y2 z2 1|
|x3 y3 z3 1|
|x4 y4 z4 1| |x1 y1 z1 1|
D2 = |x y z 1|
|x3 y3 z3 1|
|x4 y4 z4 1| |x1 y1 z1 1|
D3 = |x2 y2 z2 1|
|x y z 1|
|x4 y4 z4 1| |x1 y1 z1 1|
D4 = |x2 y2 z2 1|
|x3 y3 z3 1|
|x y z 1|

简单地对上面的算法进行分析:

其实上述算法的核心思想是 四面体的体积 = 4个小四面体的之和(判断点 与 四面体的四个面各自组成的 小四面体)

但是注意: 一个四面体的体积可有上述的行列式计算, 但是行列式的值可能是负的,只有保证点的顺序是左手法则是才能保证是正的。

// copyright @ L.J.SHOU Dec.18, 2013
// test whether a point is in a tet
#include "include/cmatrix"
#include "pt.h"
#include <cassert>
#include <vector>
#include <iostream>
using namespace std;
typedef techsoft::matrix<double> Matrix;//class for matrix
typedef cpt<double> CPt; //class for points
enum SpaceRelation{ IN, OUT, ONSURFACE}; /*
* tell whether a point is in a tetrahedran or not
* return IN, OUT, ONSURFACE
*/
SpaceRelation TestPointInTet(vector<CPt>& tet, CPt& point)
{
assert(tet.size() == 4);
Matrix mat[5];
for(int i=0; i<5; ++i)
mat[i].resize(4,4);
double det[5]; for(int i=0; i<4; ++i)
{
mat[0](i,0) = tet[i].x;
mat[0](i,1) = tet[i].y;
mat[0](i,2) = tet[i].z;
mat[0](i,3) = 1;
} if(mat[0].det() < 0)
{
swap(tet[0].x, tet[1].x);
swap(tet[0].y, tet[1].y);
swap(tet[0].z, tet[1].z); for(int i=0; i<4; ++i)
{
mat[0](i,0) = tet[i].x;
mat[0](i,1) = tet[i].y;
mat[0](i,2) = tet[i].z;
mat[0](i,3) = 1;
}
} mat[1](0,0) = point.x;
mat[1](0,1) = point.y;
mat[1](0,2) = point.z;
mat[1](0,3) = 1;
for(int i=0; i<4; ++i)
{
if(i == 0) continue;
mat[1](i,0) = tet[i].x;
mat[1](i,1) = tet[i].y;
mat[1](i,2) = tet[i].z;
mat[1](i,3) = 1;
} mat[2](1,0) = point.x;
mat[2](1,1) = point.y;
mat[2](1,2) = point.z;
mat[2](1,3) = 1;
for(int i=0; i<4; ++i)
{
if(i == 1) continue;
mat[2](i,0) = tet[i].x;
mat[2](i,1) = tet[i].y;
mat[2](i,2) = tet[i].z;
mat[2](i,3) = 1;
} mat[3](2,0) = point.x;
mat[3](2,1) = point.y;
mat[3](2,2) = point.z;
mat[3](2,3) = 1;
for(int i=0; i<4; ++i)
{
if(i == 2) continue;
mat[3](i,0) = tet[i].x;
mat[3](i,1) = tet[i].y;
mat[3](i,2) = tet[i].z;
mat[3](i,3) = 1;
} mat[4](3,0) = point.x;
mat[4](3,1) = point.y;
mat[4](3,2) = point.z;
mat[4](3,3) = 1;
for(int i=0; i<4; ++i)
{
if(i == 3) continue;
mat[4](i,0) = tet[i].x;
mat[4](i,1) = tet[i].y;
mat[4](i,2) = tet[i].z;
mat[4](i,3) = 1;
} double volume = 0;
for(int i=0; i<5; ++i)
{
det[i] = mat[i].det();
//cout << det[i] << endl;
} for(int i=1; i<=4; ++i)
volume += fabs(det[i]); if(fabs(det[0]-volume) < 1e-15)
{
for(int i=1; i<=4; ++i)
{
if(fabs(det[i]) < 1e-15)
return ONSURFACE;
}
return IN;
}
else
return OUT;
}

计算几何----判断空间点是否在一个四面体(tetrahedron)内部的更多相关文章

  1. HDU 1756 Cupid's Arrow 计算几何 判断一个点是否在多边形内

    LINK:Cupid's Arrow 前置函数 atan2 返回一个向量的幅角.范围为[Pi,-Pi) 值得注意的是 返回的是 相对于x轴正半轴的辐角. 而判断一个点是否在一个多边形内 通常有三种方法 ...

  2. POJ-2318 TOYS 计算几何 判断点在线段的位置

    题目链接:https://cn.vjudge.net/problem/POJ-2318 题意 在一个矩形内,给出n-1条线段,把矩形分成n快四边形 问某些点在那个四边形内 思路 二分+判断点与位置关系 ...

  3. poj 1127 -- Jack Straws(计算几何判断两线段相交 + 并查集)

    Jack Straws In the game of Jack Straws, a number of plastic or wooden "straws" are dumped ...

  4. 计算几何--判断两条线段相交--poj 2653

    Pick-up sticks Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 8862   Accepted: 3262 De ...

  5. 判断一个点是否在多边形内部,射线法思路,C#实现

    感谢原作者,原理请看原作者的文章 http://www.html-js.com/article/1517 C#实现 public string rayCasting(PointF p, PointF[ ...

  6. FZU 2148 moon game (计算几何判断凸包)

    Moon Game Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit St ...

  7. 判断一个点在多边形的内部C++

    /* 原理: 将测试点的Y坐标与多边形的每一个点进行比较, ** 会得到测试点所在的行与多边形边的所有交点. ** 如果测试点的两边点的个数都是奇数个, ** 则该测试点在多边形内,否则在多边形外. ...

  8. HDU - 4458 计算几何判断点是否在多边形内

    思路:将飞机看成不动的,然后枚举时间看点是否在多边形内部. #include<bits/stdc++.h> #define LL long long #define fi first #d ...

  9. [算法]Python判断一个点是否在多边形内部

    题目: 代码: # -*- coding:utf-8 -*- def rayCasting(p, poly): px = p['x'] py = p['y'] flag = False i = 0 l ...

随机推荐

  1. 【MYSQL】创建虚表来辅助数据库查询

    在进行数据库查询时,有时需要用到对既有的数据表进行多表查询得出的临时条件的数据表,就可以暂时创建成为虚表,并赋予简单明了的字段名以及临时表名. 例题a:查询出每门课程低于平均成绩的学生姓名.课程名称. ...

  2. Scrum团队成立,阅读《构建之法》第6~7章,并参考以下链接,发布读后感、提出问题、并简要说明你对Scrum的理解

    Scrum团队成立:  团队名称:神的孩子 团队目标:短期目标,完成O2O模式的第一个平台 团队口号:我们都不是神的孩子 团队照: 角色分配 产品负责人: 许佳仪.决定开发内容和优先级排序,最大化产品 ...

  3. hdu----(1257)最少拦截系统(dp/LIS)

    最少拦截系统 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  4. 229. Majority Element II -- 找出数组中出现次数超过 ⌊ n/3 ⌋ 次的数

    Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit ...

  5. 安装VC6提示找不到ACME时的解决办法

    将安装程序COPY到电脑上1.打开setupwiz.ini,把"acme=acmboot.exe"改为"=acmsetup.exe";2.STF=setup/v ...

  6. go——beego的数据库增删改查

    一直都不理解使用go语言的时候,为什么还要自己去装beego,以为使用go便可以解决所有的问题,结果在朋友的点拨下,才意识到: go与beego的关系就好比是nodejs与thinkjs的关系,因此也 ...

  7. PDF 补丁丁 0.4.1 版:新增嵌入中文字库、替换文档字库的功能

    PDF 补丁丁 0.4.1 版新增了嵌入中文字库.替换文档字库的功能. 嵌入汉字字库 历史上有一批黄底黑字的 PDF 文档.这批文档都具有相同的问题:没有嵌入字库.在一些设备上阅读时显示乱码.复制文本 ...

  8. ASP.NET MVC学习之控制器篇(二)

    原文链接:http://www.asp.net/learn/mvc/ 这篇教程探索了ASP.NET MVC控制器(controller).控制器动作(controller action)和动作结果(a ...

  9. jquery插件理解看这

    zepto 插件写法 一个更换背景颜色的小插件 html 1 <div id="box">content</div> javascript 12345678 ...

  10. 单人SVN提交bug

    The working copy "初识tableVIew" failed to commit files. fatal: Unable to create '/Users/zjj ...