예제 #1
0
    /**
     * Generate all the critical points based on the position of the viewpoint and end points
     * @param viewpoint   the oject of the view point
     * @param endPoints   the list of the end points that need to connected with the view point
     */
    private void GenerateLinesCast(GameObject viewpoint, OBSTACLE.Obstacle endPoints)
    {
        for (int i = 0; i < endPoints.obstaclePoints.Length; i++)
        {
            Vector2 direction = endPoints.obstaclePoints[i] - viewpoint.transform.position;
            if (bPartiallyView)
            {
                if (HelpFunction.isInsideClockRangeOfTwoVector(startDirection, endDirection, direction))
                {
                    GenerateLineCast(viewpoint, endPoints, direction, i);
                }
            }
            else
            {
                GenerateLineCast(viewpoint, endPoints, direction, i);
            }
        }



        if (rangeEffect)
        {
            // compute the intersection point with the obstacle
            for (int i = 0; i < endPoints.obstaclePoints.Length; i++)
            {
                Vector2 intersection1;
                Vector2 intersection2;
                if (HelpFunction.FindLineCircleIntersections(viewpoint.transform.position, range, endPoints.obstaclePoints[i], endPoints.obstaclePoints[(i + 1) % endPoints.obstaclePoints.Length], out intersection1, out intersection2) != 0)
                {
                    GenerateRangeIntersectionPoint(intersection1, endPoints.index);
                    GenerateRangeIntersectionPoint(intersection2, endPoints.index);
                }
            }
        }
    }
예제 #2
0
 public static int isConcave(OBSTACLE.Obstacle obstacle)
 {
     return(isConcave(obstacle.obstaclePoints));
 }
예제 #3
0
    /// <summary>
    /// Triangularization
    /// 1.Find a splitable point
    /// 2.split to get new polygon
    /// 3.repeat until all the polygon are convex
    ///
    /// Find a splitable point
    /// 1.Is the vertex a splitable point:whether the vertex is outside the polygon that surrounded by the rest of the vertex
    /// 2.random connect to a non-adjacent vertex
    /// </summary>
    public static List <OBSTACLE.Obstacle> triangularization(OBSTACLE.Obstacle obstacle)
    {
        int len = obstacle.obstaclePoints.Length;

        if (len <= 3)
        {
            List <OBSTACLE.Obstacle> newObstacleList = new List <OBSTACLE.Obstacle>();
            newObstacleList.Add(obstacle);
            return(newObstacleList);
        }

        int        searchIndex = isConcave(obstacle);
        List <int> covexIndex  = new List <int>();

        if (searchIndex == -1)
        {
            List <OBSTACLE.Obstacle> newObstacleList = new List <OBSTACLE.Obstacle>();
            newObstacleList.Add(obstacle);
            return(newObstacleList);
        }

        //Find splitable point
        int canFragementIndex = -1;//the index of splitable point

        for (int i = 0; i < len; i++)
        {
            List <Vector3> polygon = new List <Vector3>(obstacle.obstaclePoints);
            polygon.RemoveAt(i);
            if (!IsPointInsidePolygon(obstacle.obstaclePoints[i], polygon) && IsFragementIndex(i, obstacle.obstaclePoints.ToList()))
            {
                canFragementIndex = i;
                break;
            }
        }

        if (canFragementIndex < 0)
        {
            throw new Exception("Invalid Argument");
        }

        //split to a triangle and a polygon
        List <Vector3> tTriangles = new List <Vector3>(3);
        int            next       = (canFragementIndex == len - 1) ? 0 : canFragementIndex + 1;
        int            prev       = (canFragementIndex == 0) ? len - 1 : canFragementIndex - 1;

        tTriangles.Add(obstacle.obstaclePoints[prev]);
        tTriangles.Add(obstacle.obstaclePoints[canFragementIndex]);
        tTriangles.Add(obstacle.obstaclePoints[next]);
        //delete the point

        List <Vector3> tempObstclePoints = obstacle.obstaclePoints.ToList();

        tempObstclePoints.RemoveAt(canFragementIndex);
        obstacle.obstaclePoints = tempObstclePoints.ToArray();

        // Recursion splitting
        List <OBSTACLE.Obstacle> leaveTriangles = triangularization(obstacle);

        OBSTACLE.Obstacle newObstacle = new OBSTACLE.Obstacle();
        newObstacle.obstaclePoints = tTriangles.ToArray();
        leaveTriangles.Add(newObstacle);
        return(leaveTriangles);
    }
예제 #4
0
    private void GenerateLineCast(GameObject viewpoint, OBSTACLE.Obstacle endPoints, Vector2 direction, int endPointIndex)
    {
        HitPoint hitPoint = new HitPoint();

        RaycastHit2D[] rayCastHits2D;
        rayCastHits2D = Physics2D.RaycastAll(viewpoint.transform.position, direction);

        if (rayCastHits2D.Length > 0)
        {
            if (!HelpFunction.Vector2Equal(endPoints.obstaclePoints[endPointIndex], rayCastHits2D[0].point))
            {
                if ((rayCastHits2D[0].point - new Vector2(viewpoint.transform.position.x, viewpoint.transform.position.y)).magnitude
                    > new Vector2(endPoints.obstaclePoints[endPointIndex].x - viewpoint.transform.position.x, endPoints.obstaclePoints[endPointIndex].y - viewpoint.transform.position.y).magnitude)
                {
                    // force to add the critical point
                    if ((endPoints.obstaclePoints[endPointIndex] - viewpoint.transform.position).magnitude < range)
                    {
                        addPointToCriticalList(new HitPoint(endPoints.obstaclePoints[endPointIndex], endPoints.index));
                    }
                }
            }

            foreach (RaycastHit2D rayCastHit2D in rayCastHits2D)
            {
                Vector2 temp = new Vector2(rayCastHit2D.point.x - viewpoint.transform.position.x
                                           , rayCastHit2D.point.y - viewpoint.transform.position.y);

                // if the hit result is the same position as obstacle position
                if (HelpFunction.Vector2Equal(rayCastHit2D.point, endPoints.obstaclePoints[endPointIndex]))
                {
                    // If the hit point is out of the range
                    if (temp.magnitude > range)
                    {
                        hitPoint.location      = new Vector2(viewpoint.transform.position.x, viewpoint.transform.position.y) + direction.normalized * range;
                        hitPoint.obstacleIndex = endPoints.index;
                        addPointToCriticalList(hitPoint);
                    }
                    else
                    {
                        // If the neighbour endpoints of the hitting result are both in the one side, keep the hitting result
                        Vector3 prev = endPoints.obstaclePoints[(endPointIndex + endPoints.obstaclePoints.Length - 1) % endPoints.obstaclePoints.Length];
                        Vector3 next = endPoints.obstaclePoints[(endPointIndex + 1) % endPoints.obstaclePoints.Length];

                        if (AreSameSide(new Vector2(rayCastHit2D.point.x - viewpoint.transform.position.x, rayCastHit2D.point.y - viewpoint.transform.position.y)
                                        , prev - viewpoint.transform.position, next - viewpoint.transform.position))
                        {
                            addPointToCriticalList(new HitPoint(rayCastHit2D.point, endPoints.index));
                            if (!bMesh)
                            {
                                GenerateVisibilityEffectWithLine(viewpoint, rayCastHit2D.point);
                            }
                            continue;
                        }
                        else
                        {
                            hitPoint.location      = rayCastHit2D.point;
                            hitPoint.obstacleIndex = endPoints.index;
                            addPointToCriticalList(hitPoint);
                            break;
                        }
                    }
                }
                else
                {
                    hitPoint.location = rayCastHit2D.point;
                    // find the index of obstacle in the hit point
                    foreach (OBSTACLE.Obstacle obstacle in ObstaclesLine)
                    {
                        if (HelpFunction.isInObstacle(hitPoint.location, obstacle.obstaclePoints))
                        {
                            hitPoint.obstacleIndex = obstacle.index;
                            break;
                        }
                    }
                    if (temp.magnitude > range)
                    {
                        hitPoint.location = new Vector2(viewpoint.transform.position.x, viewpoint.transform.position.y) + direction.normalized * range;
                    }
                    addPointToCriticalList(hitPoint);
                    break;
                }
            }
            if (!bMesh)
            {
                GenerateVisibilityEffectWithLine(viewpoint, hitPoint.location);
            }
        }
    }