给定三角形ABC和一点P(x, y),判断P是否在三角形内

解题思路:
  根据点P与三角形其中两点所形成的三角形面积之和与三角形ABC面积进行比较,如果相等则点P在三角形内,不相等则不在三角形ABC内。
解题步骤:
  一、根据给定的三点坐标计算三角形的面积;
  二、将点P所形成的的三角形面积之和与三角形ABC进行比较,相等则说明点P在三角形ABC内,反之则不在三角形ABC内。
步骤分析:
  根据给定的三点坐标计算三角形的面积
在这里插入图片描述
  如上图所示,给定abc三点在坐标系中围成一个三角形
  三角形abc的面积可以用公式s = 1/2 * (ac * bd) = 1/2 * (ac * ab * sinΘ)
  ac和ab长度相当于向量ac和ab的模,为了方便表达,向量ac(c1 - a1, c2 - a2)记为ac(ac1, ac2),向量ab(b1 - a1, b2 - a2)记为ab(ab1, ab2)。
  那么上面的公式就可以转换为
在这里插入图片描述
  注:4式转5式中的向量的乘积相当于两个向量之间x与y坐标相乘的推导如下
  计算向量ab和向量ac的乘积,向量ab(x1, y1),向量ac(x2, y2)。现在假设两个x和y的单位向量i(1,0)&#x

### 判断是否位于三角形内部的算法 在 Unreal Engine 中,判断一个点 \(P\) 是否位于由三个顶点 \(A\)、\(B\) \(C\) 构成的三角形内部,通常可以采用 **重心坐标法** 或者 **向量叉积法** 来实现。 #### 方法一:重心坐标法 通过计算点 \(P\) 的重心坐标判断是否处于三角形内部。如果重心坐标的分量均满足条件,则说明该点在三角形内。 设三角形的三个顶点为 \((Ax, Ay)\),\((Bx, By)\),\((Cx, Cy)\),待检测点为 \((Px, Py)\)。可以通过以下公式计算重心坐标: \[ u = ((By - Cy)(Px - Cx) + (Cx - Bx)(Py - Cy)) / ((By - Cy)(Ax - Cx) + (Cx - Bx)(Ay - Cy)) \] \[ v = ((Cy - Ay)(Px - Cx) + (Ax - Cx)(Py - Cy)) / ((By - Cy)(Ax - Cx) + (Cx - Bx)(Ay - Cy)) \] \[ w = 1 - u - v \] 当且仅当 \(u \geq 0\),\(v \geq 0\),并且 \(w \geq 0\) 时,点 \(P\) 才位于三角形内部[^1]。 以下是基于此方法的一个 Unreal Engine 蓝图函数或 C++ 实现示例: ```cpp bool IsPointInTriangle(const FVector& A, const FVector& B, const FVector& C, const FVector& P) { float denominator = (B.Y - C.Y) * (A.X - C.X) + (C.X - B.X) * (A.Y - C.Y); float u = ((B.Y - C.Y) * (P.X - C.X) + (C.X - B.X) * (P.Y - C.Y)) / denominator; float v = ((C.Y - A.Y) * (P.X - C.X) + (A.X - C.X) * (P.Y - C.Y)) / denominator; float w = 1.0f - u - v; return (u >= 0.0f && v >= 0.0f && w >= 0.0f); } ``` #### 方法二:向量叉积法 另一种常用的方法是利用向量叉积的方向性来判断点的位置关系。对于给定三角形边 \(AB\)、\(BC\) \(CA\),分别计算它们与目标点构成的矢量之间的方向一致性。 具体来说,定义如下三个叉积表达式: \[ V_{AB} = (B - A) \times (P - A) \] \[ V_{BC} = (C - B) \times (P - B) \] \[ V_{CA} = (A - C) \times (P - C) \] 如果这三个叉积的结果同号(即均为正数或者负数),则表明点 \(P\) 处于三角形内部;否则不在其中[^2]。 对应的 Unreal Engine C++ 实现可能如下所示: ```cpp float CrossProduct2D(FVector Vec1, FVector Vec2) { return Vec1.X * Vec2.Y - Vec1.Y * Vec2.X; } bool IsPointInsideUsingCrossProducts(const FVector& A, const FVector& B, const FVector& C, const FVector& P) { FVector AB = B - A; FVector AP = P - A; float crossAB_AP = CrossProduct2D(AB, AP); FVector BC = C - B; FVector BP = P - B; float crossBC_BP = CrossProduct2D(BC, BP); FVector CA = A - C; FVector CP = P - C; float crossCA_CP = CrossProduct2D(CA, CP); bool isSameSign_AB_BC = FMath::Sign(crossAB_AP) == FMath::Sign(crossBC_BP); bool isSameSign_BC_CA = FMath::Sign(crossBC_BP) == FMath::Sign(crossCA_CP); bool isSameSign_CA_AB = FMath::Sign(crossCA_CP) == FMath::Sign(crossAB_AP); return isSameSign_AB_BC && isSameSign_BC_CA && isSameSign_CA_AB; } ``` 以上两种方式均可用于解决 UE 中关于点是否落在指定平面三角形内的判定问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值