예제 #1
0
        public static Vector3 GetHoverPoint(Vector3 lp1, Vector3 lp2, Vector3 modelP, float attachR)
        {
            var _area    = Geometric.GetArea(lp1, lp2, modelP);                  //三角形面积
            var _lLength = Vector3.Distance(lp1, lp2);                           //lp1,lp2长度
            var dis      = _lLength < 1e-3 ? attachR + 1 : 2 * _area / _lLength; //modelP到lp1,lp2的距离

            if (dis > attachR)                                                   //太远
            {
                return(default(Vector3));
            }

            Vector3 lDir = lp1 - lp2;                                //直线方向
            Vector3 mDir = QuaternionUtility.Euler(0, 90, 0) * lDir; //xz平面上垂直直线方向
            Vector3 __S  = modelP - mDir * 999;
            Vector3 __E  = modelP + mDir * 999;                      //临时的两个线点

            if (!Geometric.Meet(__S, __E, lp1, lp2))                 //不相交
            {
                return(default(Vector3));
            }

            //到这里还能执行的话是相交且接近, 就要计算点
            Vector3 res = Geometric.GetCorssPointOfSegment(__E, __S, lp1, lp2);

            return(res);
        }
예제 #2
0
        public static float GetHoverDis(Vector3 lp1, Vector3 lp2, Vector3 modelP)
        {
            var _lp1    = new Vector3(lp1.x, 0, lp1.z);
            var _lp2    = new Vector3(lp2.x, 0, lp2.z);
            var _modelP = new Vector3(modelP.x, 0, modelP.z);

            var _area    = Geometric.GetArea(_lp1, _lp2, _modelP); //三角形面积
            var _lLength = Vector3.Distance(_lp1, _lp2);           //lp1,lp2长度
            var dis      = 2 * _area / _lLength;                   //modelP到lp1,lp2的距离

            return(dis);
        }
예제 #3
0
        public static bool AlmostOnLine(Vector3 lineP1, Vector3 lineP2, float width, Vector3 toCheck)
        {
            Vector3 _lineDir = (lineP2 - lineP1).normalized;

            lineP1 += _lineDir * 99;
            lineP2 -= _lineDir * 99;

            Quaternion q         = QuaternionUtility.Euler(0, 90, 0);
            Vector3    _rightDir = (q * _lineDir).normalized;

            Vector3 lp1Right = lineP1 + _rightDir * 0.5f * width - _lineDir * 0.5f * width;
            Vector3 lp1Left  = lineP1 - _rightDir * 0.5f * width - _lineDir * 0.5f * width;

            Vector3 lp2Right = lineP2 + _rightDir * 0.5f * width + _lineDir * 0.5f * width;
            Vector3 lp2Left  = lineP2 - _rightDir * 0.5f * width + _lineDir * 0.5f * width;

            return(Geometric.IsPointInArea(new[] { lp1Right, lp2Right, lp2Left, lp1Left }, toCheck));
        }
예제 #4
0
        public static bool IsPointAlmostOnSegment(Vector3 lineP1, Vector3 lineP2, float width, Vector3 toCheck)
        {
            Vector3    _lineDir  = (lineP2 - lineP1).normalized;
            Quaternion q         = QuaternionUtility.Euler(0, 90, 0);
            Vector3    _rightDir = (q * _lineDir).normalized;

            Vector3 diff = _rightDir * width - _lineDir * width;

            Vector3 lp1Right = lineP1 + diff;
            Vector3 lp1Left  = lineP1 - diff;

            Vector3 lp2Right = lineP2 + diff;
            Vector3 lp2Left  = lineP2 - diff;

            var res = Geometric.IsPointInArea(new[] { lp1Right, lp2Right, lp2Left, lp1Left }, toCheck);

            return(res);
        }
예제 #5
0
        /// <summary>
        /// 使用向量叉乘来计算任意多边形面积
        /// </summary>
        /// <param name="points">顺序描述的点集</param>
        /// <returns>面积</returns>
        public static float GetArea(params Vector3[] points)
        {
            //去重
            List <Vector3> toCalcualte = new List <Vector3>(points);

            for (int i = 0; i < toCalcualte.Count; i++)
            {
                for (int j = 0; j < toCalcualte.Count; j++)
                {
                    if (j != i && toCalcualte[i] == toCalcualte[j])
                    {
                        toCalcualte.RemoveAt(j);
                        j--;
                    }
                }
            }

            int n = toCalcualte.Count;

            for (int i = 0; i < n; i++)
            {
                if (Geometric.Meet(toCalcualte[i], toCalcualte[(i + 1) % n], toCalcualte[(i + 2) % n], toCalcualte[(i + 3) % n]))
                {
                    var temp = toCalcualte[(i + 2) % n];
                    toCalcualte[(i + 2) % n] = toCalcualte[(i + 1) % n];
                    toCalcualte[(i + 1) % n] = temp;
                }
            }

            points = toCalcualte.ToArray();

            float   area = 0f;
            Vector3 ANXI = toCalcualte[0] + Vector3.one * 100;//要尽量远来补平舍入误差

            for (int i = 0; i < points.Length; i++)
            {
                area += cross(ANXI, points[i], points[(i + 1) % points.Length]);
            }
            area /= 2f;
            return(Mathf.Abs(area));
        }
예제 #6
0
        public static Vector3 GetHoverPointOfLine(Vector3 lp1, Vector3 lp2, Vector3 modelP, float attachR)
        {
            var _area    = Geometric.GetArea(lp1, lp2, modelP);                  //三角形面积
            var _lLength = Vector3.Distance(lp1, lp2);                           //lp1,lp2长度
            var dis      = _lLength < 1e-3 ? attachR + 1 : 2 * _area / _lLength; //modelP到lp1,lp2的距离

            if (dis > attachR)                                                   //太远
            {
                return(default(Vector3));
            }

            Vector3 lDir = lp1 - lp2;                                //直线方向
            Vector3 mDir = QuaternionUtility.Euler(0, 90, 0) * lDir; //xz平面上垂直直线方向
            Vector3 __S  = modelP - mDir * 99;
            Vector3 __E  = modelP + mDir * 99;                       //临时的两个线点

            //if (!Geometric.Meet(__S, __E, lp1, lp2))//不相交
            //{
            //    return default(Vector3);
            //}

            //到这里还能执行的话是相交且接近, 就要计算点
            Vector3 res = Geometric.GetCrossPointOfLine(__E, __S, lp1, lp2);

            if ((Mathf.Abs(res.x - modelP.x) < 0.01f))
            {
                res.x = modelP.x;
            }

            if ((Mathf.Abs(res.z - modelP.z) < 0.01f))
            {
                res.z = modelP.z;
            }

            return(res);
        }
예제 #7
0
 public static bool IsTwoLinePointPartCover(Vector3 a, Vector3 b, Vector3 c, Vector3 d, float offset = 0.03f)
 {
     return(Geometric.IsPointAlmostOnSegment(a, b, offset, c) || Geometric.IsPointAlmostOnSegment(a, b, offset, d) ||
            Geometric.IsPointAlmostOnSegment(c, d, offset, a) || Geometric.IsPointAlmostOnSegment(c, d, offset, b));
 }
예제 #8
0
        public static bool Meet_crossWay(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4)
        {
            Vector3 crossP = GetCrossPointOfLine(p1, p2, p3, p4);

            return(Geometric.IsPointOnSegment(p1, p2, crossP) && Geometric.IsPointOnSegment(p3, p4, crossP));
        }