Ejemplo n.º 1
0
        public static bool TestRayPolygon(LVector2 o, LVector2 dir, LVector2 *points, int vertexCount,
                                          ref LVector2 point)
        {
            LFloat t = LFloat.FLT_MAX;

            for (var i = 0; i < vertexCount; i++)
            {
                var b1    = points[i];
                var b2    = points[(i + 1) % vertexCount];
                var inter = TestRaySegment(o, dir, b1, b2);
                if (inter >= 0)
                {
                    if (inter < t)
                    {
                        t = inter;
                    }
                }
            }

            if (t < LFloat.FLT_MAX)
            {
                point = o + dir * t;
            }

            return(false);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// 射线和多边形
 /// </summary>
 /// <param name="o"></param>
 /// <param name="dir"></param>
 /// <param name="points"></param>
 /// <param name="vertexCount"></param>
 /// <returns></returns>
 public static bool TestRayPolygon(LVector2 o, LVector2 dir, LVector2 *points, int vertexCount)
 {
     for (int i = 0; i < vertexCount; i++)
     {
         LVector2 b1    = points[i];
         LVector2 b2    = points[(i + 1) % vertexCount];
         int      inter = TestRaySegment(o, dir, b1, b2);
         if (inter >= 0)
         {
             return(true);
         }
     }
     return(false);
 }
Ejemplo n.º 3
0
        //http://www.kevlindev.com/geometry/2D/intersections/index.htm
        //http://www.kevlindev.com/geometry/2D/intersections/index.htm
        //https://bitlush.com/blog/circle-vs-polygon-collision-detection-in-c-sharp
        public static bool TestCirclePolygon(LVector2 c, LFloat r, LVector2 *_points, int vertexCount)
        {
            var radiusSquared   = r * r;
            var circleCenter    = c;
            var nearestDistance = LFloat.MaxValue;
            int nearestVertex   = -1;

            for (var i = 0; i < vertexCount; i++)
            {
                LVector2 axis     = circleCenter - _points[i];
                var      distance = axis.sqrMagnitude - radiusSquared;
                if (distance <= 0)
                {
                    return(true);
                }

                if (distance < nearestDistance)
                {
                    nearestVertex   = i;
                    nearestDistance = distance;
                }
            }

            LVector2 GetPoint(int index)
            {
                if (index < 0)
                {
                    index += vertexCount;
                }
                else if (index >= vertexCount)
                {
                    index -= vertexCount;
                }

                return(_points[index]);
            }

            var vertex = GetPoint(nearestVertex - 1);

            for (var i = 0; i < 2; i++)
            {
                var nextVertex        = GetPoint(nearestVertex + i);
                var edge              = nextVertex - vertex;
                var edgeLengthSquared = edge.sqrMagnitude;
                if (edgeLengthSquared != 0)
                {
                    LVector2 axis = circleCenter - vertex;
                    var      dot  = LVector2.Dot(edge, axis);
                    if (dot >= 0 && dot <= edgeLengthSquared)
                    {
                        LVector2 projection = vertex + (dot / edgeLengthSquared) * edge;
                        axis = projection - circleCenter;
                        if (axis.sqrMagnitude <= radiusSquared)
                        {
                            return(true);
                        }
                        else
                        {
                            if (edge.x > 0)
                            {
                                if (axis.y > 0)
                                {
                                    return(false);
                                }
                            }
                            else if (edge.x < 0)
                            {
                                if (axis.y < 0)
                                {
                                    return(false);
                                }
                            }
                            else if (edge.y > 0)
                            {
                                if (axis.x < 0)
                                {
                                    return(false);
                                }
                            }
                            else
                            {
                                if (axis.x > 0)
                                {
                                    return(false);
                                }
                            }
                        }
                    }
                }

                vertex = nextVertex;
            }

            return(true);
        }
Ejemplo n.º 4
0
 //TODO
 public static bool TestPolygonPolygon(LVector2 *_points, int vertexCount, LVector2 *_points2, int vertexCount2)
 {
     return(false);
 }
Ejemplo n.º 5
0
        /// <summary>
        /// 测试圆和多边形是否相交
        /// </summary>
        /// <param name="c"></param>
        /// <param name="r"></param>
        /// <param name="_points"></param>
        /// <param name="vertextCount">多边形顶点数量</param>
        /// <returns></returns>
        public static bool TestCirclePolygon(LVector2 c, LFloat r, LVector2 *_points, int vertextCount)
        {
            //圆形的半径平方
            var radiusSquared = r * r;
            //圆的中心点
            var circleCenter = c;
            // 记录最近的距离
            var nearestDistance = LFloat.MaxValue;
            // 记录最近的顶点
            int nearestVertex = -1;

            for (int i = 0; i < vertextCount; i++)
            {
                LVector2 axix = circleCenter - _points[i];
                // 多边形的任何顶点在圆的范围内  说明相交
                var distance = axix.sqrMagnitude - radiusSquared;
                if (distance <= 0)
                {
                    return(true);
                }
                if (distance < nearestDistance)
                {
                    nearestVertex   = i;
                    nearestDistance = distance;
                }
            }

            // 获取点
            LVector2 GetPoint(int index)
            {
                if (index < 0)
                {
                    index += vertextCount;
                }
                else if (index >= vertextCount)
                {
                    index -= vertextCount;
                }
                return(_points[index]);
            }

            var vertex = GetPoint(nearestVertex - 1);

            for (int i = 0; i < 2; i++)
            {
                LVector2 nextVertex        = GetPoint(nearestVertex + 1);
                LVector2 edge              = nextVertex - vertex;
                LFloat   edgeLengthSquared = edge.sqrMagnitude;
                if (edgeLengthSquared != 0)
                {
                    LVector2 axis = circleCenter - vertex;
                    LFloat   dot  = LVector2.Dot(edge, axis);
                    if (dot >= 0 && dot <= edgeLengthSquared)
                    {
                        //   (dot / edgeLengthSquare ) *  edge   是求 向量的投影
                        //  两向量 a'  b'  夹角β
                        //  a·b = |a'||b'|cosβ
                        //
                        LVector2 projection = vertex + (dot / edgeLengthSquared) * edge;
                        axis = projection - circleCenter;
                        if (axis.sqrMagnitude <= radiusSquared)
                        {
                            return(true);
                        }
                        else
                        {
                            if (edge.x > 0)
                            {
                                if (axis.y > 0)
                                {
                                    return(false);
                                }
                                else if (edge.x < 0)
                                {
                                    if (axis.y < 0)
                                    {
                                        return(false);
                                    }
                                    else if (edge.y > 0)
                                    {
                                        if (axis.x < 0)
                                        {
                                            return(false);
                                        }
                                        else
                                        if (axis.x > 0)
                                        {
                                            return(false);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                vertex = nextVertex;
            }
            return(true);
        }