同向法判断某个点是否在三角形内

原理

假设有三角形ABC与任意点P, 则如果点P在三角形ABC内时, 满足点P在向量AB,BC,CA的相同侧,即在三个向量的左侧或者右侧。
对于向量AB,C点永远在AB的左侧或右侧,所以只要P点与C点同侧,P点就在向量AB的左侧或右侧。
对向量AB,AP和向量AB,AC做叉乘运行,可以得到两条垂直向量,若这两条向量同向,则可以证明P,C相对AB同侧
对三条边分别计算即可证明P在ABC内。

该原理对多边形也适用
在这里插入图片描述

代码

// ******************************************************************
//       /\ /|       @file       TriangleTest.cs
//       \ V/        @brief      三角形测试
//       | "")       @author     Shadowrabbit, yingtu0401@gmail.com
//       /  |                    
//      /  \\        @Modified   2021-05-12 11:13:59
//    *(__\_\        @Copyright  Copyright (c) 2021, Shadowrabbit
// ******************************************************************

using UnityEngine;

public class TriangleTest : MonoBehaviour
{
    public Transform transformA;
    public Transform transformB;
    public Transform transformC;
    public Transform transformP;

    private void OnDrawGizmos()
    {
        if (transformP == null)
        {
            return;
        }

        var positionA = transformA.position;
        var positionB = transformB.position;
        var positionC = transformC.position;
        Gizmos.color = IsPointInTriangle(positionA, positionB, positionC,
            transformP.position)
            ? Color.green
            : Color.red;
        Gizmos.DrawLine(positionA, positionB);
        Gizmos.DrawLine(positionB, positionC);
        Gizmos.DrawLine(positionC, positionA);
    }

    /// <summary>
    /// 判断同边 点AB构成一个线段 计算以AB顺时针旋转 AP,AC是否在AB同侧
    /// </summary>
    /// <param name="pointA">点A</param>
    /// <param name="pointB">点B</param>
    /// <param name="pointC"></param>
    /// <param name="pointP"></param>
    private bool IsSameSide(Vector3 pointA, Vector3 pointB, Vector3 pointC, Vector3 pointP)
    {
        //计算向量
        var ab = pointB - pointA;
        var ac = pointC - pointA;
        var ap = pointP - pointA;
        //计算ab与ac的叉乘 ab与ap的叉乘
        var crossAbAc = Vector3.Cross(ab, ac);
        var crossAbAp = Vector3.Cross(ab, ap);
        //点乘>0 则为相同方向
        return Vector3.Dot(crossAbAc, crossAbAp) > 0;
    }

    /// <summary>
    /// 判断P点是否在三角形ABC中
    /// </summary>
    /// <param name="pointA"></param>
    /// <param name="pointB"></param>
    /// <param name="pointC"></param>
    /// <param name="pointP"></param>
    /// <returns></returns>
    private bool IsPointInTriangle(Vector3 pointA, Vector3 pointB, Vector3 pointC, Vector3 pointP)
    {
        //点P对三边都是同侧则在三角形内
        return IsSameSide(pointA, pointB, pointC, pointP) && IsSameSide(pointB, pointC, pointA, pointP) &&
               IsSameSide(pointC, pointA, pointB, pointP);
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值