码迷,mamicode.com
首页 > 其他好文 > 详细

线段与非无限平面相交检测

时间:2017-09-02 20:50:23      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:es2017   ==   ima   zed   com   pre   代码   分享   val   

参考自《游戏编程精粹1》,用该方法除了知道是否相交以外还可以得到相交点,从而用于其他判断。

 

技术分享

 

原文用到了平面方程Ax+By+Cz+D=0,通过三角形求出平面,然后用方程求出线段交点

这里直接使用平面,以下为Unity中的实现代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Practice : MonoBehaviour
{
    public Transform p0;
    public Transform p1;
    public Transform planeLocation;
    public float size = 5f;


    void OnDrawGizmos()
    {
        if (p0 == null) return;
        if (p1 == null) return;
        if (planeLocation == null) return;

        var cacheColor = Gizmos.color;

        var r = GetIntersectPoint(planeLocation.forward, planeLocation.position, p0.position, p1.position);

        if (r != null)
        {
            var quat = Quaternion.FromToRotation(planeLocation.forward, Vector3.forward);
            var temp = quat * r.Value;
            var sizeHalf = size * 0.5f;

            if (temp.x <= sizeHalf
                && temp.x >= -sizeHalf
                && temp.y <= sizeHalf
                && temp.y >= -sizeHalf)
            {
                Gizmos.color = Color.red;
            }

            Gizmos.DrawWireSphere(r.Value, 0.1f);
        }

        var cacheMatrix = Gizmos.matrix;
        Gizmos.matrix = Matrix4x4.TRS(planeLocation.position, planeLocation.rotation, Vector3.one);
        Gizmos.DrawWireCube(Vector3.zero, new Vector3(size, size, 0f));
        Gizmos.matrix = cacheMatrix;
        Gizmos.color = cacheColor;
    }

    /// <summary>
    /// 检测相交点的原始函数,没有相交点返回空,否则返回相交点。
    /// </summary>
    /// <param name="planeNormal">平面的法线朝向</param>
    /// <param name="planePosition">平面的位置</param>
    /// <param name="p0">线段点0</param>
    /// <param name="p1">线段点1</param>
    Vector3? GetIntersectPoint(Vector3 planeNormal, Vector3 planePosition, Vector3 p0, Vector3 p1)
    {
        var sign1 = Mathf.Sign(Vector3.Dot(planeNormal, (planePosition - p0).normalized));
        var sign2 = Mathf.Sign(Vector3.Dot(planeNormal, (planePosition - p1).normalized));
        if (sign1 == sign2) return null;//同侧异侧.

        var a = planeNormal.x;
        var b = planeNormal.y;
        var c = planeNormal.z;
        var d = -a * planePosition.x - b * planePosition.y - c * planePosition.z;

        var i0 = a * p0.x + b * p0.y + c * p0.z;
        var i1 = a * p1.x + b * p1.y + c * p1.z;
        var final_t = -(i1 + d) / (i0 - i1);

        var finalPoint = new Vector3()
        {
            x = p0.x * final_t + p1.x * (1 - final_t),
            y = p0.y * final_t + p1.y * (1 - final_t),
            z = p0.z * final_t + p1.z * (1 - final_t),
        };

        return finalPoint;
    }
}

 

线段与非无限平面相交检测

标签:es2017   ==   ima   zed   com   pre   代码   分享   val   

原文地址:http://www.cnblogs.com/hont/p/7467618.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!