三角形内的点:重心坐标
Point within a triangle: barycentric co-ordinates
我正在解决一个经典问题,即确定一个点是否在三角形内,我正在使用质心坐标方法。由于某种原因(我认为这是逻辑,而不是精度),它没有通过所有的测试。会出什么问题呢?
代码如下:
#include <iostream>
using namespace std;
struct point
{
int x;
int y;
};
bool Place(point &A, point &B, point &C, point &P)
{
double det = (B.y - C.y)*(A.x - C.x) + (C.x - B.x)*(A.y - C.y);
double factor_alpha = (B.y - C.y)*(P.x - C.x) + (C.x - B.x)*(P.y - C.y);
double factor_beta = (C.y - A.y)*(P.x - C.x) + (A.x - C.x)*(P.y - C.y);
double alpha = factor_alpha / det;
double beta = factor_beta / det;
double gamma = 1.0 - alpha - beta;
bool In = false;
if (((A.x == P.x) & (A.y == P.y)) | ((B.x == P.x) & (B.y == P.y)) | ((C.x == P.x) & (C.y == P.y)))
In = true; // the sneaky guys are trying to see if the vertice of the triangle belongs to it
// the problem statement says it does.
if ((alpha == 0) | (beta == 0) | (gamma == 0))
In = true; // the point is on the edge of the triangle
if (( (0 < alpha) & (alpha < 1)) & ((0 < beta) & (beta < 1)) & ((0 < gamma) & (gamma < 1)))
In = true; // in this case P is actually within the triangle area
return In;
}
int main()
{
point A, B, C, P;
cin >> A.x >> A.y >> B.x >> B.y >> C.x >> C.y >> P.x >> P.y;
Place(A, B, C, P) ? cout << "Inn" : cout << "Outn";
return 0;
}
如果alpha
, beta
或gamma
中至少有一个为0,则该点位于边缘上。
这是必要的,但不是充分的;其他也必须在[0, 1]
区间。
既然你对"边缘"情况不感兴趣,你可以写
if (0 <= alpha && alpha <= 1 && 0 <= beta && beta <= 1 && 0 <= gamma && gamma <= 1)
In = true;
(我删除了一些括号并用逻辑&&
替换了按位&
)
可读性建议:
引入两个函数使代码看起来更像一个数学定义:
bool operator ==(const point& a, const point& b)
{
return a.x == b.x && a.y == b.y;
}
bool within(double x)
{
return 0 <= x && x <= 1;
}
bool Place(const point &A, const point &B, const point &C, const point &P)
{
double det = (B.y - C.y)*(A.x - C.x) + (C.x - B.x)*(A.y - C.y);
double factor_alpha = (B.y - C.y)*(P.x - C.x) + (C.x - B.x)*(P.y - C.y);
double factor_beta = (C.y - A.y)*(P.x - C.x) + (A.x - C.x)*(P.y - C.y);
double alpha = factor_alpha / det;
double beta = factor_beta / det;
double gamma = 1.0 - alpha - beta;
return P == A || P == B || P == C || (within(alpha) && within(beta) && within(gamma));
}
尝试这个函数(假设您有一个Point
类模板,其中T
是存储类型,并且您已经重载了operator*
来计算点积):
template <typename T>
bool is_point_in_triangle(const Point<3,T>& p,
const Point<3,T>& a,
const Point<3,T>& b,
const Point<3,T>& c) {
typedef Point<3,T> point_type;
point_type v0 = b-a, v1 = c-a, v2 = p-a;
T d00 = v0*v0;
T d01 = v0*v1;
T d11 = v1*v1;
T d20 = v2*v0;
T d21 = v2*v1;
T denom = d00*d11 - d01*d01;
// compute parametric coordinates
Real v = (d11 * d20 - d01 * d21) / denom;
Real w = (d00 * d21 - d01 * d20) / denom;
return v >= 0. && w >= 0. && v + w <= 1.;
}
作为旁注,您使用int
来存储坐标,因此您的测试可能会因为截断而失败?好运!
相关文章:
- QGraphicsPolygonItem在拖动时未更新QPolygonF坐标
- 绘制旋转的三角形
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 如何用for循环在c++中生成单词三角形
- 如何使用递归打印修改后的星号三角形图案
- C++ 创建带有 for 循环的三角形
- 绘制顺时针三角形,重新排序点
- 在顶点着色器中使用 OpenGl 的未声明标识符,我在顶点着色器中绘制三角形时遇到问题
- Eigen c++ 三角形来自
- 为我的 c++ 类介绍制作一个三角形分类器.我有几个问题
- 使用对象文件读取三角形数据网格
- 重心坐标并不总是有效(3d)
- 如何在三角形曲面细分评估着色器中插值 UV 映射坐标?
- 为什么在三角形带中使用z坐标开gl
- 三角形内的点:重心坐标
- DirectX 9.0(世界坐标移动我的对象(三角形)动画
- 在openGL中改变三角形坐标
- 重心坐标夹紧 3D 三角形
- 我无法使用用户输入使用 GLUT 更改三角形的 z 坐标?